OpenCV学习笔记7-图像的基本变换(附代码实现)

图像的基本变换

1 图像的放大与缩小

  • cv2.resize(src, dsize[, dst[, fx[, fy[, interpolation]]]])

    • src: 要缩放的图片
    • dsize: 缩放之后的图片大小, 元组和列表表示均可.(高度,宽度)
    • dst: 可选参数, 缩放之后的输出图片
    • fx, fy: x轴和y轴的缩放比, 即宽度高度的缩放比.
    • interpolation: 插值算法, 主要有以下几种:
      • cv2.INTER_NEAREST, 邻近插值, 速度快, 效果差.
      • cv2.INTER_LINEAR, 双线性插值, 使用原图中的4个点进行插值. 默认.
      • cv2.INTER_CUBIC, 三次插值, 原图中的16个点.
      • cv2.INTER_AREA, 区域插值, 效果最好, 计算时间最长.

    将一个图片缩放成和另一个图片的大小相同示例:

    import cv2
    import numpy as np
    
    dog = cv2.imread('./dog.jpeg')
    cat = cv2.imread('./cat.jpeg')
    
    print('dog',dog.shape)
    print('cat',cat.shape)
    
    # 把猫缩放成和狗一样大
    new_cat = cv2.resize(cat, (499, 360))
    print('new_cat',new_cat.shape)
    
    cv2.imshow('new_cat', np.hstack((dog, new_cat)))
    cv2.imshow('cat', cat)
    
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2qRCC40v-1648822019955)(D:\Desktop\daxue\MSB\AIoT\机器视觉\day05_图像的算术与位运算\课件\img\693f5bcaffa52187b6a1fe5c540db2e.png)]

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CcVlKMs9-1648822019956)(D:\Desktop\daxue\MSB\AIoT\机器视觉\day05_图像的算术与位运算\课件\img\30f631a44e03a804b046c19a0e2cb97.png)]

    四种插值算法的对比:

    import cv2
    import numpy as np
    
    dog = cv2.imread('./dog.jpeg')
    
    new_dog1 = cv2.resize(dog, (640, 480), interpolation=cv2.INTER_NEAREST)
    new_dog2 = cv2.resize(dog, (640, 480), interpolation=cv2.INTER_LINEAR)# 默认效果
    new_dog3 = cv2.resize(dog, (640, 480), interpolation=cv2.INTER_CUBIC)
    new_dog4 = cv2.resize(dog, (640, 480), interpolation=cv2.INTER_AREA)
    
    cv2.imshow('dog', dog)
    cv2.imshow('new_dog1', new_dog1)
    cv2.imshow('new_dog2', new_dog2)
    cv2.imshow('new_dog3', new_dog3)
    cv2.imshow('new_dog4', new_dog4)
    
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

在这里插入图片描述

还可以按照x,y轴的比例进行缩放

import cv2
import numpy as np

dog = cv2.imread('./dog.jpeg')

new_dog = cv2.resize(dog, dsize=None, fx=1.5, fy=0.5, interpolation=cv2.INTER_AREA)

cv2.imshow('dog', dog)
cv2.imshow('new_dog', new_dog)

cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述
在这里插入图片描述

2 图像的翻转

  • cv2.flip(src, flipCode[, dst])

    扫描二维码关注公众号,回复: 14189721 查看本文章
    • src 输入图像

    • flipCode 翻转形式

      • flipCode = 0 表示上下翻转
      • flipCode > 0 表示左右翻转
      • flipCode < 0 上下 + 左右
    • dst 输出图像

# flip
import cv2
import numpy as np

cv2.namedWindow('dog1',cv2.WINDOW_NORMAL)
cv2.namedWindow('dog2',cv2.WINDOW_NORMAL)
cv2.namedWindow('dog3',cv2.WINDOW_NORMAL)

cv2.resizeWindow('dog1',(400,200))
cv2.resizeWindow('dog2',(400,200))
cv2.resizeWindow('dog3',(400,200))

dog = cv2.imread('./dog.jpeg')

# 上下翻转
new_dog1 = cv2.flip(dog, 0)
# 左右翻转
new_dog2 = cv2.flip(dog, 1)
# 上下左右翻转
new_dog3 = cv2.flip(dog, -1)

cv2.imshow('dog1', np.hstack((dog, new_dog1)))
cv2.imshow('dog2', np.hstack((dog, new_dog2)))
cv2.imshow('dog3', np.hstack((dog, new_dog3)))

cv2.waitKey(0)
cv2.destroyAllWindows()

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IIx6rP4l-1648822019956)(D:\Desktop\daxue\MSB\AIoT\机器视觉\day05_图像的算术与位运算\课件\img\888d1e02701e6e214f19c7736c0136a.png)]

3 图像的旋转

  • cv2.rotate(src, rotateCode[, dst])
    • src 输入图像

    • rotateCode: 旋转角度

      • ROTATE_90_CLOCKWISE 90度顺时针
      • ROTATE_180 180度
      • ROTATE_90_COUNTERCLOCKWISE 90度逆时针
    • dst 输出图像

# flip
import cv2
import numpy as np

dog = cv2.imread('./dog.jpeg')

# - ROTATE_90_CLOCKWISE 90度顺时针
new_dog1 = cv2.rotate(dog, rotateCode=cv2.ROTATE_90_CLOCKWISE )
# - ROTATE_180 180度
new_dog2 = cv2.rotate(dog, rotateCode=cv2.ROTATE_180)
# - ROTATE_90_COUNTERCLOCKWISE 90度逆时针
new_dog3 = cv2.rotate(dog, rotateCode=cv2.ROTATE_90_COUNTERCLOCKWISE)

cv2.imshow('dog', dog)
cv2.imshow('new_dog1', new_dog1)
cv2.imshow('new_dog2', new_dog2)
cv2.imshow('new_dog3', new_dog3)


cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述

4 仿射变换之图像平移

  • 仿射变换是图像旋转, 缩放, 平移的总称.具体的做法是通过一个矩阵和和原图片坐标进行计算, 得到新的坐标, 完成变换. 所以关键就是这个矩阵.

  • cv2.warpAffine(src, M, dsize[, dst[, flags[, borderMode[, borderValue]]]])

    • src:输入图像

    • M:仿射变换矩阵,一般反映平移或旋转的关系,可通过M = cv2.getRotationMatrix2D(center, angle, scale)获得

      • center 旋转中心,以图片的哪个点作为旋转时的中心点.
      • angle 逆时针旋转角度
      • scale 等比例放缩比例,想把图片进行什么样的缩放.
    • dst:输出图像。先宽度,后高度,即(宽度,高度)

    • dsize: 输出图片大小

    • flags: 与resize中的插值算法一致

    • borderMode: 边界外推法标志

    • borderValue: 填充边界值

  • 平移矩阵

    • 矩阵中的每个像素由(x,y)组成,(x, y)表示这个像素的坐标. 假设沿x轴平移 t x t_x tx​​​​​​​​, 沿y轴平移 t y t_y ty​​​​​​​, 那么最后得到的坐标为 ( x ^ , y ^ ) = ( x + t x , y + t y ) (\hat x, \hat y) = (x + t_x, y + t_y) (x^,y^)=(x+tx,y+ty)​​​​, 用矩阵表示就是:

    $ \left(\begin{matrix}\hat x \\hat y \1\end{matrix}\right) = \left(\begin{matrix}1 & 0 & t_x\0 & 1 & t_y\0 & 0 & 1\end{matrix}\right)\left(\begin{matrix}x \y \1\end{matrix}\right) $

    # 在进行旋转操作的时候, 不方便手动计算变换矩阵, 
    # opencv提供了获取变换矩阵的API.
    import cv2
    import numpy as np
    
    dog = cv2.imread('./dog.jpeg')
    
    # 高度,宽度,通道数
    h, w, ch = dog.shape
    
    # 获取变换矩阵
    # 规定按照逆时针转动图片
    M = cv2.getRotationMatrix2D((w/2, h/2), 45, 1)
    
    # 注意opencv中是先宽度, 再高度
    new_dog = cv2.warpAffine(dog, M, (w, h))
    
    cv2.imshow('dog_ndog', np.hstack((dog,new_dog)))
    
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-t83oNviP-1648822019956)(D:\Desktop\daxue\MSB\AIoT\机器视觉\day05_图像的算术与位运算\课件\img\6ceff7f8166e8e930f61e784096a490.png)]

5 仿射变换之获取变换矩阵

仿射变换的难点就是计算变换矩阵, 仿射变换需要一个M矩阵,但是由于仿射变换比较复杂,一般直接很难找到这个矩阵,为此OpenCV提供了计算变换矩阵的API

  • M = cv2.getAffineTransform(src, dst) 通过三点可以确定变换后的位置, 相当于解方程, 3个点对应三个方程, 能解出偏移的参数和旋转的角度.

    • src 原始图像的三个点

    • dst 对应变换后的三个点

  • M 根据三个对应点求出对应的仿射变换矩阵

  • 然后再使用函数cv2.warpAffine( )利用得到的M对原始图像进行变换即可。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iBktmbPZ-1648822019957)(D:\Desktop\daxue\MSB\AIoT\机器视觉\day05_图像的算术与位运算\课件\img\aier.png)]

# 通过三个点来确定变换矩阵
import cv2
import numpy as np

dog = cv2.imread('./dog.jpeg')

h, w, ch = dog.shape

src = np.float32([[100, 100], [200, 100], [200, 300]])
dst = np.float32([[100, 150], [360, 200], [280, 120]])
# 需要原始图片的三个点坐标, 和变换之后的三个对应的坐标
M = cv2.getAffineTransform(src, dst)
new_dog = cv2.warpAffine(dog, M, (w, h))

cv2.imshow('dog', dog)
cv2.imshow('new_dog', new_dog)

cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述

6 透视变换

透视变换就是将一种坐标系变换成另一种坐标系. 简单来说可以把一张"斜"的图变"正".

  • cv2.warpPerspective(src, M, dsize[, dst[, flags[, borderMode[, borderValue]]]])

    • src:输入图像

    • M:仿射变换矩阵,一般反映平移或旋转的关系,可通过 M = cv2.getPerspectiveTransform(src, dst[, solveMethod]) 获取透视变换的变换矩阵, 需要4个点, 即图片的4个角.

      • src 原始图像的四个点
      • dst 对应变换后的四个点
      • solveMethod 传递方式
      • 对于透视变换来说, M是一个3 * 3 的矩阵.
    • dsize: 输出图片大小

    • dst:输出图像。先宽度,后高度,即(宽度,高度)

    • flags: 与resize中的插值算法一致

    • borderMode: 边界外推法标志

    • borderValue: 填充边界值

    import cv2
    import numpy as np
    
    img = cv2.imread('./123.png')
    
    # print(img.shape)
    # 获取变换矩阵
    # src是原图的4个坐标
    src = np.float32([[100, 1100], [2100, 1100], [0, 4000], [2500, 3900]])
    dst = np.float32([[0, 0], [2300, 0], [0, 3000], [2300, 3000]])
    M = cv2.getPerspectiveTransform(src, dst)
    
    # 透视变换
    new_img = cv2.warpPerspective(img, M, (2300, 3000))
    cv2.namedWindow('img', cv2.WINDOW_NORMAL)
    cv2.resizeWindow('img', 640, 480)
    
    cv2.imshow('img', img)
    
    cv2.namedWindow('new_img', cv2.WINDOW_NORMAL)
    cv2.resizeWindow('new_img', 640, 480)
    cv2.imshow('new_img', new_img)
    
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

在这里插入图片描述
附OpenCV目录:OpenCV总目录学习笔记

智科专业小白,写博文不容易,如果喜欢的话可以点个赞哦!请添加图片描述

猜你喜欢

转载自blog.csdn.net/weixin_56197703/article/details/123909245