【OpenCV】第五章: 几何变换

第五章: 几何变换

  • 1、什么是图像的几何变换?
    图像的几何变换就是将一组图像数据经过某种数学运算,映射成另外一组图像数据的操作。所以,几何变换的关键就是要确定这种空间映射关系。
    几何变换又称空间变换。对于图像数据来说,就是将一幅图像中的坐标位置映射到另一幅图像中的新坐标位置。或者说,几何变换不改变图像的像素值,只是在图像平面上进行像素的重新安排。

  • 2、为什么要对图像进行几何变换?
    对图像进行几何变换可以一定程度上的消除图像由于角度、透视关系、拍摄等原因造成的几何失真,进而造成计算机模型或者算法无法正确识别图像,所以我们要对图像进行几何变换。
    几何变换不是取悦人眼的,是取悦计算机的,是让计算机(模型、算法)能更好的认识图片的。所以,对图像进行几何变换处理是深度学习中数据增强的一种常用手段,是进行图像识别前的数据预处理工作内容。
    比如,在很多机器视觉落地项目中,在实际工作中,我们并不能保证被检测的物体在图像的相同位置和方向,所以我们首先要解决的就是被检测物体的位置和方向。所以我们首先要做的就是对图像进行几何变换。

  • 3、图像数据都有哪些几何变换?
    按照人类的视觉效果分,二维图像的基本几何变换主要有缩放、平移、旋转、镜像、透视等。
    按照变换的数学原理的不同分,二维图像的基本几何变换主要有仿射变换、透视变换、重映射变换。
    由于我们课件还是要尊重课本的基本安排,所以下面的几何变换按照课本的分类规则进行编写。

  • 一、缩放变换

    就是对图像的大小进行放大和缩小的变换。
    cv2.resize(img, dsize, fx=0, fy=0, interpolation=cv2.INTER_LINEAR)
    img: 要进行缩放处理的图像
    dsize: 进行绝对尺寸的放缩处理,直接指定你要缩放后的大小即可。
       注意: 这里的参数传入顺序是(列,行)的顺序。
    fx, fy : 进行相对尺寸的缩放处理,fx,fy是一个比例值,当你想放大图像时,fx,fy就是一个大于1的数,当缩小图像时,fx,fy就是一个小于1的数。
       注意: 当使用这两个参数时,dsize=None,就是把绝对尺寸调整方式关闭掉。
    interpolation: 插值方法。
    interpolation=cv2.INTER_LINEAR,表示双线性插值法,是默认方式。
    interpolation=cv2.INTER_NEAREST,最近邻插值
    interpolation=cv2.INTER_AREA,使用像素区域关系进行重采样,也叫区域插值法。就是根据当前像素点周边区域的像素实现当前像素点的采样。
    interpolation=cv2.INTER_CUBIC, 4x4像素邻域的双三次插值
    当缩小图像时,使用INTER_AREA插值方式效果最好。当放大图像时,使用INTER_LINEAR和INTER_CUBIC效果最好,但是双三次插值法运算速度较慢,双线性插值法速度较快。

    #例5.1 对图像进行绝对尺寸缩放处理 
    import cv2
    import matplotlib.pyplot as plt
    img = cv2.imread(r'C:\Users\25584\Desktop\test.bmp')
    img_small = cv2.resize(img, (int(0.9*img.shape[1]), int(0.5*img.shape[0])))   #注意dsize参数的顺序
    img_big = cv2.resize(img, (100, 600))
    img_mix = cv2.resize(img, (100, 400))
    img.shape, img_small.shape, img_big.shape, img_mix.shape
    
    plt.subplot(141), plt.imshow(img[:,:,::-1]), plt.xlim(0,100), plt.ylim(0,600)
    plt.subplot(142), plt.imshow(img_small[:,:,::-1]), plt.xlim(0,100), plt.ylim(0,600)
    plt.subplot(143), plt.imshow(img_big[:,:,::-1]), plt.xlim(0,100), plt.ylim(0,600)
    plt.subplot(144), plt.imshow(img_mix[:,:,::-1]), plt.xlim(0,100), plt.ylim(0,600)
    plt.show()

 

#例5.2 对图像进行相对尺寸缩放处理 
import cv2
import matplotlib.pyplot as plt
img = cv2.imread(r'C:\Users\25584\Desktop\test.bmp')
img_1 = cv2.resize(img, None, fx=2, fy=0.5)   #水平方向扩大为原来的2倍,垂直方向缩小到原来的0.5倍。这里dsize参数一定要设置为None。
img.shape, img_1.shape

plt.subplot(121), plt.imshow(img[:,:,::-1]), plt.xlim(0,120), plt.ylim(0,520)
plt.subplot(122), plt.imshow(img_1[:,:,::-1]), plt.xlim(0,120), plt.ylim(0,520)
plt.show()

#例5.3 观察不同插值方法对图像缩放的影响 
import cv2
import matplotlib.pyplot as plt
img = cv2.imread(r'C:\Users\25584\Desktop\lenacolor.png')
img_suoxiao = cv2.resize(img, (256, 256), interpolation=cv2.INTER_AREA)    #区域插值法
img_fangda = cv2.resize(img, (1024, 1024), interpolation=cv2.INTER_LINEAR)  #双线性插值法
img_suofang = cv2.resize(img, (256, 1024), interpolation=cv2.INTER_CUBIC)  #双三次插值法

plt.subplot(221), plt.imshow(img[:,:,::-1]), plt.xlim(0,512), plt.ylim(512,0)
plt.subplot(222), plt.imshow(img_suoxiao[:,:,::-1]), plt.xlim(0,512), plt.ylim(512,0)
plt.subplot(223), plt.imshow(img_fangda[:,:,::-1]), plt.xlim(0,1024), plt.ylim(1024,0)
plt.subplot(224), plt.imshow(img_suofang[:,:,::-1]), plt.xlim(0,1024), plt.ylim(1024,0)
plt.show()

二、翻转变换

opencv中图像翻转变换的API : cv2.flip(img, flipcode)
函数功能:实现图像的水平翻转、垂直翻转、水平+垂直翻转
img:要操作的图像对象 flipcode: flipcode=0 表示绕x轴翻转;flipcode=任意正整数,比如1,2,3,表示绕y轴翻转;flipcode=任意负整数,比如-1,-2,-3,表示绕x轴和y轴同时翻转;
函数返回:返回一个和img大小相同、类型相同的对象。

#例5.4 观察不同的翻转变换 
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread(r'C:\Users\25584\Desktop\lenacolor.png')
img_horizon = cv2.flip(img, 0)
img_vertical = cv2.flip(img, 1)
img_h_v = cv2.flip(img, -1)

fig, axes = plt.subplots(1,4, figsize=(12,4), dpi=100)
axes[0].imshow(img[:,:,::-1]), axes[0].set_title('yuan tu ')
axes[1].imshow(img_horizon[:,:,::-1]), axes[1].set_title('Flip around the X axis')
axes[2].imshow(img_vertical[:,:,::-1]), axes[2].set_title('Flip around the Y axis')
axes[3].imshow(img_h_v[:,:,::-1]), axes[3].set_title('Flip around the X and Y axis')
plt.show()

三、仿射变换

  • 1、什么是放射变换
    仿射变换通俗的讲就是:“线性变换”+“平移”。
    线性变换通俗讲,比如1个点可以随便移动,1条直线可以随便旋转和位移,1个平面可以翻转,1个曲线可以随便拐弯等等,而点、直线、平面、曲面之所以会移动,有三种原因,一是在相同的坐标空间下,点线面自身移动而产生,二是这些点线面本身没有移动,坐标空间发生了变换,比如,坐标轴放缩了、旋转了、平移了,导致点线面的坐标值发生变换,也就相当于移动了,三是,二者都变换而产生移动,但移动的相对量不一致。这些移动不管是主动还是被动,不管是绝对还是相对,都是移动,这些移动就是放射变换。
    那这些放射变换不变的是什么呢?不变的就是点还是点,线还是线,面还是面,点变不成线,线变不成面,并且同一条直线上的点的位置顺序和长度的比例关系不变,这就是放射变换下的不变性。放射变换变化的是:向量的夹角会发现变化,垂直关系也会发生变化。
  • 2、图像经过放射变换会发生哪些变化?
    推理到图像上就是,图像数据经过放射变换后,变换后的图像仍能够保持平直性(直线经过放射变换后还是直线)和平行性(平行线经过放射变换后还是平行线)。
    可以实现图像的平移、缩放、旋转、翻转和错切等效果:
  • 所以,我们前面讲的图像放缩和翻转,其实也是可以通过仿射变换得到的。上面的图像缩放采取的技术是填充像素点(放大)和减少像素点(缩小),用的是插值法,当然我们也可以通过仿射运算的方法得到放大缩小的效果。这就类似于一个数学题有好几种解法的意思。前面讲的翻转效果更是仿射变换中的一个特例而已。但是我们为什么还要单独把这两种变换拿出来讲?是因为opencv有专门的API,而且课本也是出于让同学们掌握这两个函数而单独拎出来讲了一下,我们尊重课本的讲解主线,所以也单独拿出来讲解。
  • 3、实现放射变换的数学公式?
  • 等号右边的矩阵就是仿射变换矩阵,其中,左上角的子矩阵是坐标系的放缩、旋转数据,右边第一列是坐标轴的平移值。最后一行是一个不影响方程组解的冗余方程。
  • 4、仿射变换的不同变换矩阵实现的效果:

所以,一张图形进行仿射变换的重点在于找到这个变换矩阵!!!

  • 5、例子:把一张图像顺时针旋转45度,向左平移200个像素点,向下平移30个像素点,这个操作的转换矩阵是什么?
    假设x,y坐标系下,一个点(x,y)与x轴的夹角是α, 此时,将这个点顺时针旋转θ度,这个点新的(x',y')是:
    x' = rcos(α+θ)= xcosθ + ysinθ
    y' = rsin(α+θ)= -xsinθ + ycosθ
    所以:
    x'   cosθ   sinθ  200  x
    y' =  -sinθ   cosθ  30  y
    1    0    0    1  1
  • 6、获取旋转矩阵的API:
    一张图像进行仿射变换的时候,最重要的步骤就是找到变换矩阵,从上面的分析可以看到平移、放缩、剪切、镜像的变换矩阵都非常简单,可以快速手写出来,但是对于旋转操作的变换矩阵,由于有三角函数而无法迅速得出具体的矩阵表达,所以我们就单独把旋转操作中的变换矩阵的生成打包成一个函数,方便我们调用。
    cv2.getRotationMatrix2D(center, angle, scale)
    center:旋转的中心点
    angle:旋转角度,正数表示逆时针旋转,负数表示顺时针旋转
    scale:缩放大小
    我们通过这个函数就可以自动生成我们要用的转换矩阵。
  • 7、获取更加通用的变换矩阵的API(就是任意仿射变换的变换矩阵):
    cv2.getAffineTransform(P1,P2)
    p1: 输入图像的三个坐标点
    p2:输出图像的三个坐标点
  • 8、放射变换 API: cv2.warpAffine(img, M, dsize)
    img:要变换的对象
    M:变换矩阵
    dsize:输出图像的绝对大小。注意:这个参数的传入是(宽度,高度), 宽度width=列数, 高度height=行数
    # 例5.5 自定义一个变换矩阵,实现图像的平移  
    import cv2
    import numpy as np
    import matplotlib.pyplot as plt
    img = cv2.imread(r'C:\Users\25584\Desktop\lenacolor.png')
    M = np.float32([[1,0,100], [0,1,200]])    #定义变换矩阵,由于只是移动图像,图像大小没有改变,所以左上矩阵是单位矩阵,右边一列是x轴y轴的原点移动了100、200个像素点。
    img_affine1 = cv2.warpAffine(img, M, (img.shape[1], img.shape[0]))  #输出图像的大小和原图像大小一样
    img_affine2 = cv2.warpAffine(img, M, (800, 800))                    #输出图像变成800x800了。
    img_affine3 = cv2.warpAffine(img, M, (400, 400))                    #输出图像变成400x400了。
    
    fig, axes = plt.subplots(1,4, figsize=(12,5), dpi=100)
    axes[0].imshow(img[:,:,::-1]), axes[0].set_title('yuan tu ')
    axes[1].imshow(img_affine1[:,:,::-1]), axes[1].set_title('img_affine1')
    axes[2].imshow(img_affine2[:,:,::-1]), axes[2].set_title('img_affine2')
    axes[3].imshow(img_affine3[:,:,::-1]), axes[3].set_title('img_affine3')
    plt.show()

    # 例5.6 实现图像旋转:以图像的中心为圆点,让图像逆时针旋转45度,并缩小为原来的0.6倍。  
    import cv2
    import numpy as np
    import matplotlib.pyplot as plt
    img = cv2.imread(r'C:\Users\25584\Desktop\lenacolor.png')
    M1 = cv2.getRotationMatrix2D((img.shape[1]/2, img.shape[0]/2), 45, 0.6)   #以图片中心点旋转并缩小
    M2 = cv2.getRotationMatrix2D((img.shape[1]/2, img.shape[0]/2), 90, 1)     #以图片中心点旋转不缩小
    M3 = cv2.getRotationMatrix2D((512, 0), 30, 1)                             #以别的中心点旋转
                                 
    img_affine1 = cv2.warpAffine(img, M1, (img.shape[1], img.shape[0]))  #输出图像的大小和原图像大小一样
    img_affine2 = cv2.warpAffine(img, M2, (img.shape[1], img.shape[0])) 
    img_affine3 = cv2.warpAffine(img, M3, (1000, 1000))                    #输出图像变成800x800了。
    
    fig, axes = plt.subplots(1,4, figsize=(12,5), dpi=100)
    axes[0].imshow(img[:,:,::-1]), axes[0].set_title('yuan tu ')
    axes[1].imshow(img_affine1[:,:,::-1]), axes[1].set_title('img_affine1')
    axes[2].imshow(img_affine2[:,:,::-1]), axes[2].set_title('img_affine2')
    axes[3].imshow(img_affine3[:,:,::-1]), axes[3].set_title('img_affine3')
    plt.show()

     说明: 对于一张图像而言的坐标系,和我们平时的平面坐标系是有所不同的。我们平时水平方向向右是x轴的正方向,垂直向上是y轴的正方向。
    但是对于图像而言,它里面的各个像素的位置坐标是:水平方向向右是x轴的正方向,垂直向下是y轴的正方向。因为一张图像的第一个像素[0,0]是这个图像的左上角的第一个像素点。

    # 例5.7 实现图像的任意仿射变换 
    import cv2
    import numpy as np
    import matplotlib.pyplot as plt
    img = cv2.imread(r'C:\Users\25584\Desktop\lenacolor.png')
    P1 = np.float32([[0,0], [img.shape[1]-1,0], [0, img.shape[0]-1]])  #生成原始图像上的三个点(左上角,右上角,左下角)
    P2 = np.float32([[0,img.shape[1]*0.33], [img.shape[1]*0.85,img.shape[0]*0.25], [img.shape[1]*0.15, img.shape[0]*0.7]])  #生成目标图像上的三个点
    P3 = np.float32([[100,100], [400,50], [250,450]])
    M1 = cv2.getAffineTransform(P1, P2)       #生成转换矩阵
    M2 = cv2.getAffineTransform(P1, P3)       
    img_affine1 = cv2.warpAffine(img, M1, (img.shape[1], img.shape[0]))   #进行仿射变换,原图大小输出
    img_affine2 = cv2.warpAffine(img, M2, (600, 600))   
    
    fig, axes = plt.subplots(1,3, figsize=(8,3), dpi=100)
    axes[0].imshow(img[:,:,::-1]), axes[0].set_title('yuan tu ')
    axes[1].imshow(img_affine1[:,:,::-1]), axes[1].set_title('img_affine1')
    axes[2].imshow(img_affine2[:,:,::-1]), axes[2].set_title('img_affine2')
    plt.show()

    四、透视变换

    透视变换是把一个图像投影到一个新的视平面的过程,该过程包括:把一个二维坐标系转换为三维坐标系,然后把三维坐标系投影到新的二维坐标系。该过程是一个非线性变换过程,因此,一个平行四边形经过透视变换后只得到四边形,但不平行。
    透视变换矩阵为:

    其中,(x,y)是原图坐标,(x’,y’)是变换后的坐标;m11,m12,m21,m22,m31,m32为旋转量,m13,m23,m33为平移量。因为透视变换是非线性的,所以不能齐次性表示;透视变换矩阵为3*3。

    仿射变换常用于旋转和平移等图像处理操作,原理较简单。而透视变换的实际应用较大,如视角纠正,全景拼接等。

    同理,在透视变换中,关键的一步是找到一个透视变换矩阵,opencv也为我们打包了一个API,我们直接调用即可:
    cv2.getPerspectiveTransform(p1,p2)
    p1:输入图像的四个顶点的坐标
    p2:输出图像的四个顶点的坐标

    在opencv中,实现透视变换的函数为:cv2.warpPerspective(src,dst,H,(cols,rows))
    src:输入图像
    dst:输出图像
    H:3*3的仿射变换矩阵
    (cols,rows):输出图像的行数和列数

    # 例5.8 实现图像的透视变换 
    import cv2
    import numpy as np
    import matplotlib.pyplot as plt
    img = cv2.imread(r'C:\Users\25584\Desktop\demo.bmp')
    P1 = np.float32([[150,50], [400, 50], [60, 450], [310,450]])  #生成原始图像上的4个点
    P2 = np.float32([[50,50], [img.shape[0]-50,50], [50, img.shape[1]-50], [img.shape[0]-50, img.shape[1]-50]])  #生成目标图像上的三个点
    M = cv2.getPerspectiveTransform(P1, P2)       #生成转换矩阵
    img_perspective1 = cv2.warpPerspective(img, M, (img.shape[1], img.shape[0]))   
    img_perspective2 = cv2.warpPerspective(img, M, (1000, 1000))    #大画布输出
    
    fig, axes = plt.subplots(1,3, figsize=(8,3), dpi=100)
    axes[0].imshow(img[:,:,::-1]), axes[0].set_title('yuan tu ')
    axes[1].imshow(img_perspective1[:,:,::-1]), axes[1].set_title('img_perspective1')
    axes[2].imshow(img_perspective2[:,:,::-1]), axes[2].set_title('img_perspective2')
    plt.show()

    五、重映射

    1、为什么要进行重映射操作?
    前面我们学仿射变换、透视变换都是通过变换矩阵来时实现映射的。但是,有时候我们需要更加个性化的几何变换,比如我们希望通过自定义的方式来指定如何映射,此时我们就需要进行重映射操作。
    2、什么是重映射?
    把一张图像内的像素点放置到另外一幅图像内指定的位置,这个操作就是重映射。
    3、opencv中的重映射接口?
    cv2.remap(img, map1, map2, interpolation)
    img:原始图像
    map1:要映射的原始图像中的像素的列
    map2:要映射的原始图像中的像素的行
    interpolation:插值方式,不支持INTER_AREA方法

    # 例5.9 理解cv2.remap()函数  
    import cv2
    import numpy as np
    img = np.random.randint(0,256, (4,5), np.uint8)
    mapx = np.ones((3,3), np.float32)
    mapy = np.ones((3,3), np.float32)*2
    result = cv2.remap(img, mapx, mapy, cv2.INTER_LINEAR)
    result
    array([[47, 47, 47],
           [47, 47, 47],
           [47, 47, 47]], dtype=uint8)
    # 例5.10 用cv2.remap()函数实现图像的复制  
    import cv2
    import numpy as np
    img = np.random.randint(0,256, (4,5), np.uint8)
    mapx = np.zeros(img.shape, np.float32)     #先生成一个和目标图像大小一样的矩阵,然后更改这个矩阵里面的值。矩阵里面的值就是原图中要索引的像素点的列
    mapy = np.zeros(img.shape, np.float32)     #矩阵里面的值就是原图中要索引的像素点的行
    for i in range(4):
        for j in range(5):
            mapx[i,j]=j    #或者写成 mapx.itemset((i,j), j)
            mapy[i,j]=i
    copy_img = cv2.remap(img, mapx, mapy, cv2.INTER_LINEAR)
    # 例5.11 用cv2.remap()函数实现lenacolor.png的复制  
    import cv2
    import numpy as np
    import matplotlib.pyplot as plt
    lenacolor = cv2.imread(r'C:\Users\25584\Desktop\lenacolor.png')
    rows, cols = img.shape[:2]
    mapx = np.zeros(img.shape[:2], np.float32)
    mapy = np.zeros(img.shape[:2], np.float32)
    for i in range(rows):
        for j in range(cols):
            mapx.itemset((i,j), j)
            mapy.itemset((i,j), i)
    copy_lenacolor = cv2.remap(lenacolor, mapx, mapy, cv2.INTER_LINEAR)
    
    plt.subplot(121), plt.imshow(lenacolor[:,:,::-1])
    plt.subplot(122), plt.imshow(copy_lenacolor[:,:,::-1])
    plt.show()
    # 例5.12 用cv2.remap()函数图像绕x轴翻转 
    import cv2
    import numpy as np
    import matplotlib.pyplot as plt
    lenacolor = cv2.imread(r'C:\Users\25584\Desktop\lenacolor.png')
    rows, cols = img.shape[:2]
    mapx = np.zeros(img.shape[:2], np.float32)
    mapy = np.zeros(img.shape[:2], np.float32)
    for i in range(rows):
        for j in range(cols):
            mapx.itemset((i,j), j)
            mapy.itemset((i,j), rows-1-i)
    copy_lenacolor = cv2.remap(lenacolor, mapx, mapy, cv2.INTER_LINEAR)
    
    plt.subplot(121), plt.imshow(lenacolor[:,:,::-1])
    plt.subplot(122), plt.imshow(copy_lenacolor[:,:,::-1])
    plt.show()
    # 例5.13 用cv2.remap()函数图像绕y轴翻转 
    import cv2
    import numpy as np
    import matplotlib.pyplot as plt
    lenacolor = cv2.imread(r'C:\Users\25584\Desktop\lenacolor.png')
    rows, cols = img.shape[:2]
    mapx = np.zeros(img.shape[:2], np.float32)
    mapy = np.zeros(img.shape[:2], np.float32)
    for i in range(rows):
        for j in range(cols):
            mapx.itemset((i,j), cols-1-j)
            mapy.itemset((i,j), i)
    copy_lenacolor = cv2.remap(lenacolor, mapx, mapy, cv2.INTER_LINEAR)
    
    plt.subplot(121), plt.imshow(lenacolor[:,:,::-1])
    plt.subplot(122), plt.imshow(copy_lenacolor[:,:,::-1])
    plt.show()
    # 例5.14 用cv2.remap()函数图像绕x轴y轴同时翻转 
    import cv2
    import numpy as np
    import matplotlib.pyplot as plt
    lenacolor = cv2.imread(r'C:\Users\25584\Desktop\lenacolor.png')
    rows, cols = img.shape[:2]
    mapx = np.zeros(img.shape[:2], np.float32)
    mapy = np.zeros(img.shape[:2], np.float32)
    for i in range(rows):
        for j in range(cols):
            mapx.itemset((i,j), cols-1-j)
            mapy.itemset((i,j), rows-1-i)
    copy_lenacolor = cv2.remap(lenacolor, mapx, mapy, cv2.INTER_LINEAR)
    
    plt.subplot(121), plt.imshow(lenacolor[:,:,::-1])
    plt.subplot(122), plt.imshow(copy_lenacolor[:,:,::-1])
    plt.show()
    # 例5.15 用cv2.remap()函数图x轴、y轴互换  
    import cv2
    import numpy as np
    import matplotlib.pyplot as plt
    lenacolor = cv2.imread(r'C:\Users\25584\Desktop\lenacolor.png')
    rows, cols = img.shape[:2]
    mapx = np.zeros(img.shape[:2], np.float32)
    mapy = np.zeros(img.shape[:2], np.float32)
    for i in range(rows):
        for j in range(cols):
            mapx.itemset((i,j), i)
            mapy.itemset((i,j), j)
    copy_lenacolor = cv2.remap(lenacolor, mapx, mapy, cv2.INTER_LINEAR)
    
    plt.subplot(121), plt.imshow(lenacolor[:,:,::-1])
    plt.subplot(122), plt.imshow(copy_lenacolor[:,:,::-1])
    plt.show()
    # 例5.16 用cv2.remap()函数缩小图像    
    import cv2
    import numpy as np
    import matplotlib.pyplot as plt
    lenacolor = cv2.imread(r'C:\Users\25584\Desktop\lenacolor.png')
    rows, cols = img.shape[:2]
    mapx = np.zeros(img.shape[:2], np.float32)
    mapy = np.zeros(img.shape[:2], np.float32)
    for i in range(rows):
        for j in range(cols):
            if 0.25*cols< i <0.75*cols and 0.25*rows< j <0.75*rows:
                mapx.itemset((i,j), 2*(j-cols*0.25)+0.5)
                mapy.itemset((i,j), 2*(i-rows*0.25)+0.5)
            else:
                mapx.itemset((i,j), 0)
                mapy.itemset((i,j), 0)
                
    copy_lenacolor = cv2.remap(lenacolor, mapx, mapy, cv2.INTER_LINEAR)
    
    plt.subplot(121), plt.imshow(lenacolor[:,:,::-1])
    plt.subplot(122), plt.imshow(copy_lenacolor[:,:,::-1])
    plt.show()

  • 9
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值