为什么iplRotate()没有给我正确的结果?

Rob*_*Rob 4 c++ windows image-processing intel-ipp

感叹我很遗憾地说我正在使用英特尔IPL(图像处理库)处理我正在处理的一些图像处理代码.这是我努力让我的图像正确旋转的故事.

  1. 我有一个源图像.它的大小(w,h)不一定是正方形.
  2. 它将以角度θ旋转.
  3. 我已经计算出适合旋转角度θ的尺寸(w,h)的图像所需的输出尺寸.这个大小是(dw,dh).我已经分配了一个具有该大小的目标缓冲区.
  4. 我想通过角度旋转所述源图像THETA有关源图象的中心(W/2,H/2)和具有旋转后的图像在我的目标缓冲区居中.

iplRotate()采用2个移位参数xShiftyShift,它们表示在执行旋转后图像应沿x和y轴移动的距离.

问题是我无法让iplRotate将旋转的图像置于目标图像的中心.它总是偏离中心.

我最好的XSHIFT和YSHIFT什么猜测应该是这样的:

  • xShift = dw - w
  • yShift = dh - h

但这不起作用,我不知道还有什么办法来计算xShiftyShift.有没有人有任何关于如何使用iplRotate做我想要的建议?

最后一点信息: 我试图使用iplGetRotateShift()再次计算xShift和yShift无济于事.我想这会起作用:

iplGetRotateShift(dw / 2.0, dh / 2.0, theta, &xShift, &yShift);
Run Code Online (Sandbox Code Playgroud)

但事实并非如此.


编辑: 我使用英特尔IPP 6.0而不是IPL重写代码,我看到相同的错误结果.我无法想象,英特尔有旋转错误在2个不同的库,所以我必须做一些错误的.


编辑: 我尝试了Dani van der Meer建议的以下(IPP)代码:

xShift = (dw - w) / 2.0;
yShift = (dh - h) / 2.0;
ippiAddRotateShift(w / 2.0, h / 2.0, angle, &xShift, &yShift);
Run Code Online (Sandbox Code Playgroud)

不幸的是,仍然没有运气.这也行不通.

Dan*_*eer 5

使用iplGetRotateShift时,您需要在源图像中指定旋转中心.如果源图像和目标图像的大小相同,这将很有效.

在您的情况下,您需要额外的班次以使图像在目标图像中居中:

xShift = (dw - w) / 2.0;
yShift = (dh - h) / 2.0;
Run Code Online (Sandbox Code Playgroud)

要结合两个班次,您需要使用ippiAddRotateShift而不是ippiGetRotateShift.

注意:这些函数是指IPP库版本5.3(我的版本).我不确定AddLotateShift在IPL中是否可用.但是您在问题中提到您使用IPP尝试了相同的操作,所以希望您可以使用IPP而不是IPL.

你得到这样的东西

xShift = (dw - w) / 2.0;
yShift = (dh - h) / 2.0;
ippiAddRotateShift(w / 2.0, h / 2.0, angle, &xShift, &yShift);
Run Code Online (Sandbox Code Playgroud)

如果在调用ippiRotate时使用这些移位,则图像应位于目标图像的中心.

我希望这有帮助.

编辑: 这是我用来测试的代码(从w到dw和h到dh的变化,旋转角度只是随机的):

//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);
Run Code Online (Sandbox Code Playgroud)