为什么 iplRotate() 没有给我正确的结果?
叹息我很遗憾地说,我在我正在处理的一些图像处理代码中使用了英特尔IPL(图像处理库)。 这是我努力让图像正确旋转的故事。
- 我有一个源图像。 它的尺寸(w, h)不一定是正方形。
- 它将旋转theta角度。
- 我计算了适合大小为 (w, h) 旋转角度 theta 的图像所需的输出尺寸。 该尺寸为(dw, dh)。 我已经分配了一个具有该大小的目标缓冲区。
- 我想围绕源图像的中心(w/2,h/2)将源图像旋转角度theta,并让该旋转图像位于我的目标缓冲区的中心。
iplRotate() 采用 2 个平移参数,xShift 和 yShift,它们指示图像在旋转后应沿 x 轴和 y 轴平移的距离。执行旋转。
问题是我无法让 iplRotate 将旋转图像置于目标图像的中心。 它总是偏离中心。
我对 xShift 和 yShift 应该是什么的最佳猜测如下:
- xShift = dw - w
- yShift = dh - h
但这不起作用,我不知道还可以做什么来计算 xShift和yShift。 有人对如何使用 iplRotate 来做我想做的事情有任何建议吗?
最后一点信息: 我再次尝试使用 iplGetRotateShift() 来计算 xShift 和 yShift,但无济于事。 我想这会起作用:
iplGetRotateShift(dw / 2.0, dh / 2.0, theta, &xShift, &yShift);
但事实并非如此。
编辑: 我使用 Intel IPP 6.0 而不是 IPL 重写了代码,并且看到了相同的错误结果。 我无法想象英特尔在两个不同的库中出现了轮换错误,所以我一定是做错了什么。
编辑: 我尝试了 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);
不幸的是,仍然没有运气。 那也不行。
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.
- I have a source image. It has a size (w, h) which is not necessarily square.
- It is going to be rotated by angle theta.
- I've calculated the output size required to fit an image of size (w, h) rotated by angle theta. This size is (dw, dh). I've allocated a destination buffer with that size.
- I want to rotate the source image by angle theta about the source image's center (w/2, h/2) and have that rotated image be centered in my destination buffer.
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:
- xShift = dw - w
- yShift = dh - h
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
使用 iplGetRotateShift 时,您需要指定源图像中的旋转中心。 如果源图像和目标图像的大小相同,则此方法效果很好。
在您的情况下,您需要额外的移位以使图像在目标图像中居中:
要结合两个移位,您需要使用 ippiAddRotateShift 而不是 ippiGetRotateShift。
注意:这些函数参考IPP库版本5.3(我拥有的版本)。 我不确定 AddRotateShift 在 IPL 中是否可用。 但是您在问题中提到您尝试使用 IPP 进行相同的操作,因此希望您可以使用 IPP 而不是 IPL。
您会得到类似的结果,
如果您在 ippiRotate 调用中使用这些移位,
图像应位于目标图像的中心。 我希望这有帮助。
编辑:
这是我用来测试的代码(从 w 到 dw 和 h 到 dh 的变化以及旋转角度都是随机的):
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:
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
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):
我以前从未使用过(或听说过)IPL,所以我只是猜测该 API 的作用。 但是,如果 iplRotate 绕 (0, 0) 旋转并且 iplGetRotateShift 也做类似的操作,为什么不尝试旋转原始“盒子”的其他 3 个角(忽略 (0, 0),因为它保持不变): (w, 0), ( 0,h)和(w,h)。
您的结果将是一个带有一些负值的新框。 你想要“向后移动”,这样你拥有的任何负值都将变为零,如果你明白我的意思的话。
I've never used (or heard of) IPL before, so I'm just merely guessing what the API does. But if iplRotate rotates about (0, 0) and if iplGetRotateShift does similarly, why not try rotating the other 3 corners of your original "box" (ignoring (0, 0) since that stays put): (w, 0), (0, h), and (w, h).
Your result will be a new box with some negative values. You want to "shift back" so whatever negative values you have will become zero, if you get what I mean.
根据我对文档的阅读,我认为您使用 iplGetRotateShift 是错误的。 特别是,我认为您需要指定源图像中的旋转中心,而不是目标图像,因此:
Based on my reading of the documentation I think you're using iplGetRotateShift wrong. In particular, I think you need to specify the center of rotation in the source image, not the destination image, thus:
如果它仍然不适合您,那么我们可以确认这些假设是有效的吗? 特别是第 3 点,您计算 dw 和 dh。
数学上
dw = w * |cos(theta)| + h * |sin(theta)|
dh = h * |cos(theta)| + w * |sin(theta)|
所以如果 theta = pi/6 的话,那么如果 w = 100 且 h = 150 那么大概 dw = 162?
您得到的错误位置是否随θ 变化而变化? 大概它适用于 theta=0 吗? 那么 theta=pi/2 和 theta=pi/4 又如何呢?
If it's still not working for you then can we confirm that the assumptions are valid? In particular point 3. where you calculate dw and dh.
Mathematically
dw = w * |cos(theta)| + h * |sin(theta)|
dh = h * |cos(theta)| + w * |sin(theta)|
so if theta = pi/6 say, then if w = 100 and h = 150 then presumably dw = 162?
Does the incorrect position you're getting vary with theta? Presumably it works with theta=0? What about theta=pi/2 and theta=pi/4?