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)

 


看看变换过程吧

好啦。“蜂窝煤”没有啦

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

 

转载于:https://www.cnblogs.com/xianglan/archive/2010/12/27/1917595.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值