sigh I'm sorry to say that I'm using Intel IPL (Image Processing Library) in some image processing code I'm working on. This is the tale of my struggle with getting my images to rotate correctly.
iplRotate() takes 2 shift parameters, xShift and yShift, which indicate the distance the image should be shifted along the x and y axis after the rotate is performed.
The problem is I cannot get iplRotate to center the rotated image in the destination image. It's always off center.
My best guess for what xShift and yShift should be is the following:
But this doesn't work, and I'm not sure what else to do to calculate xShift and yShift. Does anyone have any suggestions for how to use iplRotate to do what I want?
One last bit of info: I've attempted to use iplGetRotateShift() to calculate xShift and yShift, again, to no avail. I would imagine that this would work:
iplGetRotateShift(dw / 2.0, dh / 2.0, theta, &xShift, &yShift);
But it does not.
Edit: I rewrote the code using Intel IPP 6.0 instead of IPL and I'm seeing identical wrong results. I can't imagine that Intel got rotation wrong in 2 different libraries, so I must be doing something wrong.
Edit: I tried the following (IPP) code that Dani van der Meer suggested:
xShift = (dw - w) / 2.0;
yShift = (dh - h) / 2.0;
ippiAddRotateShift(w / 2.0, h / 2.0, angle, &xShift, &yShift);
Unfortunately, still no luck. That does not work either.
When using iplGetRotateShift you need to specify the center of rotation in the source image. This will work well if the size of the source and destination image is the same.
In your case you want an extra shift to center the image in your destination image:
xShift = (dw - w) / 2.0;
yShift = (dh - h) / 2.0;
To combine the two shift you need to use ippiAddRotateShift instead of ippiGetRotateShift.
Note: These functions refer to the IPP library version 5.3 (the version I have). I am not sure that AddRotateShift is available in IPL. But you mentioned in the question that you tried the same using IPP, so hopefully you can use IPP instead of IPL.
You get something like this
xShift = (dw - w) / 2.0;
yShift = (dh - h) / 2.0;
ippiAddRotateShift(w / 2.0, h / 2.0, angle, &xShift, &yShift);
If you use these shifts in the call to ippiRotate the image should be centered in the destination image.
I hope this helps.
EDIT: Here is the code I used to test (the change from w to dw and h to dh and the rotation angle are just random):
//Ipp8u* dst_p; Initialized somewhere else in the code
//Ipp8u* src_p; Initialized somewhere else in the code
int w = 1032;
int h = 778;
int dw = w - 40; // -40 is just a random change
int dh = h + 200; // 200 is just a random change
int src_step = w * 3;
int dst_step = dw * 3;
IppiSize src_size = { w, h };
IppiRect src_roi = { 0, 0, w, h };
IppiRect dst_rect = { 0, 0, dw, dh };
double xShift = ((double)dw - (double)w) / 2.0;
double yShift = ((double)dh - (double)h) / 2.0;
ippiAddRotateShift((double)w / 2, (double)h / 2, 37.0, &xShift, &yShift);
ippiRotate_8u_C3R(src_p, src_size, src_step, src_roi,
dst_p, dst_step, dst_rect, 37.0, xShift, yShift, IPPI_INTER_NN);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With