现在的位置: 首页 > 综合 > 正文

双线性插值(Bilinear interpolation)的图像旋转在mobile上面的C++实现

2013年09月10日 ⁄ 综合 ⁄ 共 3156字 ⁄ 字号 评论关闭

在图像拉伸了以后, 很自然地我们想把图像的旋转也做进来。我们找来了图像旋转的公式:

 

X' =  X cosθ -  Y sinθ;

Y' =  X sinθ  + Y cosθ;

 

这个图像公式大家在高中数学课都是会算滴。 然后我们要扩展一下因为我们不是在原点做旋转,我们要围绕原来的图片中心做旋转, 那么我们假定原来的图像中心是 oldCenterX, oldCenterY.旋转完成以后, 我们要对图像位置坐调整,调整到新的坐标中心, 那么我们需要有个新的newCenterX, newCenterY;新的坐标就是新的图片的中心。那么我们的公式就可以转化成了:

 

X' =  (X-oldCenterX) cosθ -  (Y-oldCenterY) sinθ  + newCenterX;

Y' =  (X-oldCenterX) sinθ  + (Y-oldCenterY) cosθ + newCenterY;

 

当然啦, 关键我们的问题不是旋转后的位置,而是旋转以后位置对于到原来的位置关系,也就是说我们更需要的是一个X,Y关于X'和Y'的表达式。很简单的,我们把问题变成了2元一次方程!

X = Y'sinθ + X'cosθ + oldCenterY - newCenterX cosθ - newCenterY sinθ;

Y = Y'cosθ - X'sinθ + oldCenterY - newCenterY cosθ + newCenterX sinθ;

 

这样要写个合适的代码就变得简单了。 但是另一个显著的问题就是没有三角函数怎么办呢? 就像我们插值的时候用大数一样, 我们用左移13位的大数来描述一下先,就像下面这样的:

有了这个三角函数的辅助:我们的最后的代码就是这个样子:

这里说明一下的是接口的定义,这里的和目标灰度图相关的参数都是引用类型的。表示都是输出的参数,因为图像旋转以后的大小会发生变化,函数外不是很方便事先分配好内存,所以这里采用了就地分配的模式。内存分配在函数内部完成。虽然没有用ticks去最后测速,但是想来没有浮点数的计算,这里的效率还是比较高的,当然这里一些细节的记录上还有可以再优化一下的,比如说这个常数5!!!Majic Number呵呵, 其实就是原来的那些数字都希望是左移8的, 所以三角函数中出来的数字需要左移5位!!除此以外就完全是公式的套用了 呵呵。

最后来点各个角度的效果图看看:

20度

20

40度

40

60度

60

80度

80

100度

100

120度

120

 

 

 

抱歉!评论已关闭.