我们来看看错切的两种情况:
- 水平方向错切
- 垂直方向错切
水平方向错切
我们来直观看看错切的效果吧

其数学表达式为:

矩阵变换为:

其中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)
看看变换过程吧



















