• 【opencv图像处理】--3.图像运算、基本变换、仿射变换


    系列所有代码,复制粘贴即可运行。
    希望有能力的朋友还是拿C++运行一下。

    本节讨论图像的加减乘除、逻辑运算、基本变换翻转和旋转、仿射变换等

    1. 图像运算

    1.1 图像的加减乘除

    求和

    • ndarray切片更改图片尺寸
      切,会丢掉一部分
      相当于截图
      只能大的去切片成小的,不能小的切片成大的
    # 狗大,所以从狗里边切割,左闭右开
    new_dog = dog[300:876, 300:1324]
    new_img = cv2.add(cat, new_dog)
    cv2.imshow('new_dog', np.hstack((cat, new_img)))
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • resize更改图片尺寸
      用resize,可以实现图片自由缩放任意尺寸
    import cv2
    import numpy as np
    
    cat = cv2.imread('cat.jpeg')
    dog = cv2.imread('dog.jpeg')
    
    #opencv中resize传递新的宽度和高度,先宽度再高度,先列后行,和shape输出相反
    #new_cat = cv2.resize(cat, (dog.shape[:-1][::-1]))
    new_cat = cv2.resize(dog, (cat.shape[:-1][::-1]))
    
    #和单个数字做运算,超过255会被截断,相当于%256
    #print(new_img.shape)
    #print(dog.shape)
    #print(new_cat[0:5, 0:5])
    #print(new_cat[0:5, 0:5] + 100)
    #cv2.imshow('cat_dog', np.vstack((new_cat, dog)))
    #cv2.imshow('cat_dog', new_cat)
    #cv2.imshow('dog', dog)
    #cat += 200
    
    
    #加法的效果是超过255统一变成255
    new_img = cv2.add(new_cat, cat)
    
    #减法
    #new_img = cv2.subtract(new_cat, cat)
    
    #乘法
    #new_img = cv2.multiply(new_cat, cat)
    
    #除法
    #new_img = cv2.divide(cat, new_cat)
    
    #cv2.imshow('new_img', new_img)
    #print(new_img[0:5, 0:5])
    cv2.imshow('cat_dog', np.vstack((new_cat, cat, new_img)))
    #cv2.imshow('add_dog', cat)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 注意,add求和,超出默认为255
    • 但是+求和,超出的话是%256

    1.2 图像融合

    不是简单的叠加而是拿图片做线性运算。

    • new_img = imgw1 + imgw2 +bias
    res = cv2.addWeighted(new_cat, 0.7, dog, 0.3, 0)
    
    • 1

    1.3逻辑运算

    位运算 与或非 异或

    • opencv中的非,0反过来是255, 255-此值
    # 非
    img = cv2.bitwise_not(cat)
    #print(cat[:2, :2])
    #print(img[:2, :2])
    
    
    # 与   
    #img = cv2.bitwise_and(new_cat, dog)
    
    # 或   
    #img = cv2.bitwise_or(new_cat, dog)
    
    # 异或 
    #img = cv2.bitwise_xor(new_cat, dog)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    2. 图像基本变换

    2.1 缩放

    resize

    • src: 源图
    • dsize:缩放之后的图片大小,元组和列表均可
    • fx,fy:宽度高度缩放比
    • interpolation:插值算法:
    1. 临近插值, 双线性插值(默认),三次插值,区域插值等
    import cv2
    import numpy as np
    
    cat = cv2.imread('cat.jpeg')
    print(cat.shape)
    
    # new_cat1 = cv2.resize(cat, dsize=(800, 800), interpolation=cv2.INTER_NEAREST)
    # new_cat2 = cv2.resize(cat, dsize=(800, 800), interpolation=cv2.INTER_LINEAR)
    # new_cat3 = cv2.resize(cat, dsize=(800, 800), interpolation=cv2.INTER_CUBIC) #暂时不错
    # new_cat4 = cv2.resize(cat, dsize=(800, 800), interpolation=cv2.INTER_AREA)
    # cv2.imshow('cat1', new_cat1)   
    # cv2.imshow('cat2', new_cat2)   
    # cv2.imshow('cat3', new_cat3)   
    # cv2.imshow('cat4', new_cat4)  
    
    #还可以按照x,y轴比例进行缩放
    new_cat = cv2.resize(cat, dsize=None, fx=2, fy=2, interpolation=cv2.INTER_CUBIC)
    print(new_cat.shape)
    
    
    cv2.imshow('cat', new_cat)
    cv2.imshow('olcat', cat)
    
    
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    2.2 图像翻转和旋转

    图像的翻转和旋转

    • 翻转flip:
      flipCode=0 上下翻转
      flipCode>0 左右
      flipCode<0 中心对称 ```

    • 旋转rotate:
      ROTATE_90_CLOCKWISE 90° 顺时针
      ROTATE_180 180°180°
      ROTATE_90_COUNTERCLOCKWISE 90° 逆时针

    # flipCode=0  上下翻转
    # flipCode>0  左右
    # flipCode<0  中心对称
    n_cat = cv2.flip(cat, flipCode=0)
    n1_cat = cv2.flip(cat, -1)
    n2_cat = cv2.flip(cat, 1)
    
    img1 = np.vstack((cat, n_cat))
    img2 = np.vstack((n1_cat, n2_cat))
    #cv2.imshow('olcat',np.hstack(img1, img2))
    
    #左上角为原图
    cv2.imshow('all_cat',np.hstack((img1, img2)))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    旋转:

    new_cat = cv2.rotate(cat, rotateCode=cv2.cv2.ROTATE_90_CLOCKWISE)
    
    • 1

    3. 仿射变换

    affine transformation 图像与一个矩阵做运算

    • warpAffine(src, M, dsize, flags, mode, value)
    1. M : 变换矩阵
    2. dsize:输出图片大小
    3. flas:与resize中插值算法一致
    4. mode : 边界外推法标志
    5. value: 填充边界值

    3.1 平移

    矩阵像素,(x,y),沿x轴平移Tx, 沿y轴平移Ty。用矩阵表示就是

    x    1  0  Tx     x
    y  = 0  1  Ty  *  y
    1    0  0  1      1
    
    • 1
    • 2
    • 3
    h, w, ch = cat.shape
    #这里取Tx=100, Ty=0
    M = np.float32([[1, 0, 100], [0, 1, 0]])
    #先宽后高
    #仿射变换,平移
    new_cat = cv2.warpAffine(cat, M, (w,h))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    3.2 为旋转而获取变换矩阵

    3.2.1 使用获取变换矩阵的API

    • cv2.getRotationMatrix2D(center, angle, scale)
    1. 旋转中心点
    2. 旋转角度/逆时针
    3. 缩放比例:把图片进行何种缩放
    import cv2
    import numpy as np
    
    cat = cv2.imread('cat.jpeg')
    
    h, w, ch = cat.shape
    
    M = cv2.getRotationMatrix2D((w/2, h/2), 30, 0.5)
    #先宽后高
    #仿射变换,平移
    print(M)
    new_cat = cv2.warpAffine(cat, M, (w,h))
    
    
    cv2.imshow('cat',new_cat)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    3.2.2 利用仿射变换矩阵

    找到前后对应的三个点,自己解方程求得透视变换矩阵

    • cv2.getAffineTransform(src[], dst[])
    1. 原目标的三个点的位置
    2. 变换后在图像中的三个点的位置
    import cv2
    import numpy as np
    
    cat = cv2.imread('cat.jpeg')
    
    h, w, ch = cat.shape
    
    src = np.float32([[200,100], [300,100], [200,300]])
    dst = np.float32([[100,150], [360,200], [280,120]])
    
    
    M = cv2.getAffineTransform(src, dst)
    #先宽后高
    #仿射变换,平移
    print(M)
    new_cat = cv2.warpAffine(cat, M, (w,h))
    
    
    cv2.imshow('cat',new_cat)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    4. 透视变换

    需要4个点,可以变换得到鸟瞰图等

    import cv2
    import numpy as np
    import matplotlib.pyplot as plt
    
    img = cv2.imread('homework.jpg')
    
    print(img.shape)
    h, w, ch = img.shape
    
    src = np.float32([[290,74], [630, 141], [606,620], [43,500]])
    dst = np.float32([[0,0], [w, 0], [w,h], [0,h]])
    
    M = cv2.getPerspectiveTransform(src, dst)
    
    new_img = cv2.warpPerspective(img, M, (w,h))
    
    
    cv2.imshow('cat',np.hstack((img, new_img)))
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
  • 相关阅读:
    TIA博途中如何在网络视图中显示完整的设备名称?
    Kafka核心原理
    Neural Ordinary Differential Equations(NIPS2018)
    社区团购小程序开发
    力扣题解( 最长递增子序列的个数)
    UVM driver和sequencer握手机制 get_next_item() 和 get() and put()
    Cannot find module ‘./assets/empty-module.js‘
    信息检索 | 信息检索概述
    Qt 读写数据流文件(转 CppGuiProgrammingWithQt4)
    安卓逆向 - Frida反调试绕过
  • 原文地址:https://blog.csdn.net/Eric_Sober/article/details/126052812