▼页尾

python 简单图像处理(6) 错切

图像的错切实际上是平面景物在投影平面上的非垂直投影。错切使图像中的图形产生扭变

 

我们来看看错切的两种情况: 

  1. 水平方向错切
  2. 垂直方向错切

水平方向错切

 我们来直观看看错切的效果吧

 

其数学表达式为:

 

矩阵变换为:

其中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)

 


看看变换过程吧

好啦。“蜂窝煤”没有啦

恩,想一想,错切还是有点用的嘛

 

posted @ 2010-12-27 10:52  xiatwhu  阅读(6098)  评论(0编辑  收藏  举报
▲页首
西