alot物联网工程师|四.OpenCv图像的基本变换

4. 图像的基本变换 4.1 图像的放大与缩小

  • resize(src, dsize[, dst[, fx[, fy[, interpolation]]]])
    • src: 要缩放的图片
    • dsize: 缩放之后的图片大小, 元组和列表表示均可.
    • dst: 可选参数, 缩放之后的输出图片
    • fx, fy: x轴和y轴的缩放比, 即宽度和高度的缩放比.
    • interpolation: 插值算法, 主要有以下几种:
      • INTER_NEAREST, 邻近插值, 速度快, 效果差.
      • INTER_LINEAR, 双线性插值, 使用原图中的4个点进行插值. 默认.
      • INTER_CUBIC, 三次插值, 原图中的16个点.
      • INTER_AREA, 区域插值, 效果最好, 计算时间最长.
    import cv2 import numpy as np#导入图片 dog = cv2.imread('./dog.jpeg')# x,y放大一倍 new_dog = cv2.resize(dog,dsize=(800, 800), interpolation=cv2.INTER_NEAREST) cv2.imshow('dog', new_dog) cv2.waitKey(0) cv2.destroyAllWindows()

4.2 图像的翻转
  • flip(src, flipCode)
    • flipCode =0 表示上下翻转
    • flipCode >0 表示左右翻转
    • flipCode <0 上下 + 左右
# 翻转 import cv2 import numpy as np#导入图片 dog = cv2.imread('./dog.jpeg')new_dog = cv2.flip(dog, flipCode=-1) cv2.imshow('dog', new_dog) cv2.waitKey(0) cv2.destroyAllWindows()

4.3 图像的旋转
  • rotate(img, rotateCode)
    • ROTATE_90_CLOCKWISE 90度顺时针
    • ROTATE_180 180度
    • ROTATE_90_COUNTERCLOCKWISE 90度逆时针
# 旋转 import cv2 import numpy as np#导入图片 dog = cv2.imread('./dog.jpeg')new_dog = cv2.rotate(dog, rotateCode=cv2.cv2.ROTATE_90_COUNTERCLOCKWISE) cv2.imshow('dog', new_dog) cv2.waitKey(0) cv2.destroyAllWindows()

4.4 仿射变换之图像平移
  • 仿射变换是图像旋转, 缩放, 平移的总称.具体的做法是通过一个矩阵和和原图片坐标进行计算, 得到新的坐标, 完成变换. 所以关键就是这个矩阵.
  • warpAffine(src, M, dsize, flags, mode, value)
  • M:变换矩阵
  • dsize: 输出图片大小
  • flag: 与resize中的插值算法一致
  • mode: 边界外推法标志
  • value: 填充边界值
  • 平移矩阵
    • 矩阵中的每个像素由(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) $

# 仿射变换之平移 import cv2 import numpy as np#导入图片 dog = cv2.imread('./dog.jpeg')h, w, ch = dog.shape M = np.float32([[1, 0, 100], [0, 1, 0]]) # 注意opencv中是先宽度, 再高度 new = cv2.warpAffine(dog, M, (w, h))cv2.imshow('new', new) cv2.waitKey(0) cv2.destroyAllWindows()

4.5 仿射变换之获取变换矩阵
仿射变换的难点就是计算变换矩阵, OpenCV提供了计算变换矩阵的API
  • getRotationMatrix2D(center, angle, scale)
    • center 中心点 , 以图片的哪个点作为旋转时的中心点.
    • angle 角度: 旋转的角度, 按照逆时针旋转.
    • scale 缩放比例: 想把图片进行什么样的缩放.
# 仿射变换之平移 import cv2 import numpy as np#导入图片 dog = cv2.imread('./dog.jpeg')h, w, ch = dog.shape # M = np.float32([[1, 0, 100], [0, 1, 0]])# 注意旋转的角度为逆时针. # M = cv2.getRotationMatrix2D((100, 100), 15, 1.0) # 以图像中心点旋转 M = cv2.getRotationMatrix2D((w/2, h/2), 15, 1.0) # 注意opencv中是先宽度, 再高度 new = cv2.warpAffine(dog, M, (w, h))cv2.imshow('new', new) cv2.waitKey(0) cv2.destroyAllWindows()

  • getAffineTransform(src[], dst[]) 通过三点可以确定变换后的位置, 相当于解方程, 3个点对应三个方程, 能解出偏移的参数和旋转的角度.
    • src原目标的三个点
    • dst对应变换后的三个点
      alot物联网工程师|四.OpenCv图像的基本变换
      文章图片

    # 通过三个点来确定M # 仿射变换之平移 import cv2 import numpy as np#导入图片 dog = cv2.imread('./dog.jpeg')h, w, ch = dog.shape# 一般是横向和纵向的点, 所以一定会有2个点横坐标相同, 2个点纵坐标相同 src = https://www.it610.com/article/np.float32([[200, 100], [300, 100], [200, 300]]) dst = np.float32([[100, 150], [360, 200], [280, 120]]) M = cv2.getAffineTransform(src, dst) # 注意opencv中是先宽度, 再高度 new = cv2.warpAffine(dog, M, (w, h))cv2.imshow('new', new) cv2.waitKey(0) cv2.destroyAllWindows()

4.6 透视变换
透视变换就是将一种坐标系变换成另一种坐标系. 简单来说可以把一张"斜"的图变"正".
【alot物联网工程师|四.OpenCv图像的基本变换】alot物联网工程师|四.OpenCv图像的基本变换
文章图片

  • warpPerspective(img, M, dsize,…)
  • 对于透视变换来说, M是一个3 * 3 的矩阵.
  • getPerspectiveTransform(src, dst) 获取透视变换的变换矩阵, 需要4个点, 即图片的4个角.
    # 透视变换 import cv2 import numpy as np#导入图片 img = cv2.imread('./123.png') print(img.shape)src = https://www.it610.com/article/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 = cv2.warpPerspective(img, M, (2300, 3000)) cv2.namedWindow('img', cv2.WINDOW_NORMAL) cv2.resizeWindow('img', 640, 480)cv2.namedWindow('new', cv2.WINDOW_NORMAL) cv2.resizeWindow('new', 640, 480)cv2.imshow('img', img) cv2.imshow('new', new)cv2.waitKey(0) cv2.destroyAllWindows()

    推荐阅读