OpenCV简单图像处理(6) 错切
时间:2010-12-27 来源:想兰
我们来看看错切的两种情况:
- 水平方向错切
- 垂直方向错切
水平方向错切
我们来直观看看错切的效果吧
其数学表达式为:
矩阵变换为:
其中b为tan(a),a为错切角度
好啦,我们还是写程序来看看效果吧
import cv
import math
def Warp(image,angle):
a = math.tan(angle*math.pi/180.0)
W = image.width
H = int(image.height+W*a)
size = (W,H)
iWarp = cv.CreateImage(size,image.depth,image.nChannels)
for i in range(image.height):
for j in range(image.width):
x = int(i+j*a)
iWarp[x,j] = image[i,j]
return iWarp
image = cv.LoadImage('lena.jpg',1)
iWarp1 = Warp(image,15)
cv.ShowImage('image',image)
cv.ShowImage('1',iWarp1)
cv.WaitKey(0)
效果如下:
好了。垂直方向的就不多讲了。和水平方向的基本相同。
我们来考虑下之前讲过的“蜂窝煤”吧
左图是我们希望得到的图,而在计算机中图像只能一个像素一个像素的现实
所以,可能出现左边的两个像素点映射取整后都映射到右图中的同一点,那另一点就形成空穴,就是我们之前提到的“蜂窝煤”
解决这个问题的方法应该有很多种,我想到两种比较直观的。
第一种是在有空穴的地方插值,但这种方法要进行冗余标记并增加计算
第二种方法是从右边的图往左边映射,迫使右边的每个像素点都可以取到值,但这样也会出现一个问题,右边的两个点可能在映射取整后,同样映射到一个点,那原图中的某些像素信息就会丢失。同样的,我们从左边映射到右边时,对于映射到同一点的像素,后面的映射点会覆盖前面的映射点,也会丢失信息。看来第二种方法简单,并解决了“蜂窝煤”现象
那有没有什么方法能不丢失信息呢?
我们来看看
好啦。你可能要头疼了。
其实我们可以把旋转操作看成3个错切操作
错切操作是不会舍弃任何点的
第一个矩阵是水平错切-tan(a/2)
第二个矩阵是垂直错切sina
第三个矩阵是水平错切-tan(a/2)
我发现我前面的程序出了些问题
是的,我前面的第二个参数用的是角度。但垂直变换时是sin a 不是 tan a
好吧,我们再重写一个函数
import cv
import math
def XWarp(image,angle):
a = math.tan(angle*math.pi/180.0)
W = image.width
H = int(image.height+W*a)
size = (W,H)
iWarp = cv.CreateImage(size,image.depth,image.nChannels)
for i in range(image.height):
for j in range(image.width):
x = int(i+j*a)
iWarp[x,j] = image[i,j]
return iWarp
def YWarp(image,angle):
a = math.tan(angle*math.pi/180.0)
H = image.height
W = int(image.width+H*a)
size = (W,H)
iYWarp = cv.CreateImage(size,image.depth,image.nChannels)
for i in range(image.height):
for j in range(image.width):
y = int((H-i)*a+j)
iYWarp[i,y] = image[i,j]
return iYWarp
def TYWarp(image,angle):
a = math.sin(angle*math.pi/180.0)
H = image.height
W = int(image.width+H*a)
size = (W,H)
iTYWarp = cv.CreateImage(size,image.depth,image.nChannels)
for i in range(image.height):
for j in range(image.width):
y = int((H-i)*a+j)
iTYWarp[i,y] = image[i,j]
return iTYWarp
image = cv.LoadImage('lena.jpg',1)
iWarp1 = XWarp(image,15)
iWarp2 = TYWarp(iWarp1,30)
iWarp3 = XWarp(iWarp2,15)
cv.ShowImage('image',image)
cv.ShowImage('1',iWarp1)
cv.ShowImage('2',iWarp2)
cv.ShowImage('3',iWarp3)
cv.WaitKey(0)
看看变换过程吧
好啦。“蜂窝煤”没有啦
恩,想一想,错切还是有点用的嘛