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

叹息我很抱歉地说,我正在使用英特尔IPL(image processing库)在我正在处理的一些image processing代码。 这是让我的图像旋转正确的斗争的故事。

  1. 我有一个源图像。 它的大小(w,h)不一定是方形的。
  2. 它将被angular度θ旋转。
  3. 我已经计算出所需的输出大小,以适应angular度θ旋转的大小(w,h)的图像。 这个大小是(dw,dh) 。 我已经分配了这个大小的目标缓冲区。
  4. 我想旋转源图像的angular度theta关于源图像的中心(W / 2,H / 2),并有旋转的图像居中在我的目标缓冲区。

iplRotate ()需要2个移动参数, xShiftyShift ,它们表示在执行旋转之后图像应该沿着x和y轴移动的距离。

问题是我无法得到iplRotate中心旋转的图像在目标图像。 它总是偏离中心。

我最好的猜测是什么xShift和yShift 应该是以下几点:

  • xShift = dww
  • yShift = dhh

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

最后一点信息:我试图用iplGetRotateShift()来计算xShift和yShift,再次,无济于事。 我会想象这将工作:

iplGetRotateShift(dw / 2.0, dh / 2.0, theta, &xShift, &yShift); 

但事实并非如此。


编辑:我重写了代码使用英特尔IPP 6.0而不是IPL,我看到相同的错误结果。 我无法想象英特尔在2个不同的图书馆中出现了旋转错误,所以我一定是做错了。


编辑:我尝试了以下(IPP)代码,丹妮·范德梅尔build议:

 xShift = (dw - w) / 2.0; yShift = (dh - h) / 2.0; ippiAddRotateShift(w / 2.0, h / 2.0, angle, &xShift, &yShift); 

不幸的是,仍然没有运气。 那也行不通。

当使用iplGetRotateShift时,您需要指定源图像中的旋转中心。 如果源和目标图像的大小相同,这将工作得很好。

在你的情况下,你需要一个额外的转变,以在目标图像中的图像中心:

 xShift = (dw - w) / 2.0; yShift = (dh - h) / 2.0; 

要结合这两个转变,你需要使用ippiAddRotateShift而不是ippiGetRotateShift。

:这些功能是指IPP库版本5.3(我拥有的版本)。 我不确定AddRotateShift在IPL中是否可用。 但是你在提到的问题中提到你使用了IPP,所以希望你可以使用IPP而不是IPL。

你得到这样的东西

 xShift = (dw - w) / 2.0; yShift = (dh - h) / 2.0; ippiAddRotateShift(w / 2.0, h / 2.0, angle, &xShift, &yShift); 

如果您在调用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); 

我以前从来没有使用(或听说过)IPL,所以我只是猜测API的功能。 但是,如果iplRotate围绕(0,0)旋转,并且如果iplGetRotateShift做类似的操作,为什么不尝试旋转原始“盒子”的其他三个角落(忽略(0,0),因为它保持放置):(w,0),( 0,h)和(w,h)。

你的结果将是一个有一些负值的新盒子。 如果你明白我的意思,你想要“后退”,所以你的负面价值会变成零。

基于我的文档阅读,我认为你使用iplGetRotateShift错误。 特别是,我认为你需要指定源图像中的旋转中心,而不是目标图像,因此:

 iplGetRotateShift( w / 2.0, h / 2.0, angle, &xShift, &yShift ); 

如果它仍然不适合你,那么我们可以证实这些假设是有效的吗? 尤其是第3点你在哪里计算dw和dh。

数学

dw = w * | cos(θ)| + h * | sin(θ)|
dh = h * | cos(θ)| + w * | sin(θ)|

所以如果theta =π/ 6说,那么如果w = 100和h = 150那么大概dw = 162?

你得到的不正确的位置是否随theta而变化? 推测它适用于θ= 0? 那么theta = pi / 2和theta = pi / 4呢?