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

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

水平方向错切

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

python切割卫星地图18级_python切割卫星地图18级

 

其数学表达式为:

 

python切割卫星地图18级_人工智能_02

矩阵变换为:

python切割卫星地图18级_python切割卫星地图18级_03

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


效果如下:

 

python切割卫星地图18级_人工智能_04

 

好了。垂直方向的就不多讲了。和水平方向的基本相同。

 

我们来考虑下之前讲过的“蜂窝煤”吧

python切割卫星地图18级_python切割卫星地图18级_05

左图是我们希望得到的图,而在计算机中图像只能一个像素一个像素的现实

所以,可能出现左边的两个像素点映射取整后都映射到右图中的同一点,那另一点就形成空穴,就是我们之前提到的“蜂窝煤”

解决这个问题的方法应该有很多种,我想到两种比较直观的。

第一种是在有空穴的地方插值,但这种方法要进行冗余标记并增加计算

第二种方法是从右边的图往左边映射,迫使右边的每个像素点都可以取到值,但这样也会出现一个问题,右边的两个点可能在映射取整后,同样映射到一个点,那原图中的某些像素信息就会丢失。同样的,我们从左边映射到右边时,对于映射到同一点的像素,后面的映射点会覆盖前面的映射点,也会丢失信息。看来第二种方法简单,并解决了“蜂窝煤”现象

 

那有没有什么方法能不丢失信息呢?

我们来看看

python切割卫星地图18级_python_06

好啦。你可能要头疼了。

其实我们可以把旋转操作看成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)

 

看看变换过程吧

python切割卫星地图18级_人工智能_07

python切割卫星地图18级_取整_08

python切割卫星地图18级_取整_09