opencv 图像几何变换基础讲解——含仿射和透射变换基础

文章目录

  • 实现原理
  • 实现函数
    • warpAffine——参数
    • getRotationMatrix2D——参数
    • cv.getAffineTransform——参数
    • warpPerspective——参数
    • cv.getPerspectiveTransform——参数
    • resize——参数
  • 代码实例
    • 缩放
    • 平移
    • 翻转(或者说叫做2D平移旋转)
    • 仿射变换
    • 投射变换(可以用来解决拍摄的图形不平整进行平整变化的转换)

                         QQ:3020889729                                                                                 小蔡

实现原理

毫无疑问,一个个图像——本质就是一个个多维数组,它包含像素点的排布,以及像素点的信息。
既然多维数组,我们将图像中前两维度——对应行列,当作一个矩阵进行处理。
第一维——也就是对应着行;第二维——也就是对应着列。
举例:将一个多维数组当作矩阵
[[1, 2, 3]
[4, 5, 6]
[7, 8, 9]]
这里应该能明白:第一维的每一个元素是一个list,且等大,每一个list作为一个行,list里边的元素——就一一对应着属于列。

实现函数

opencv提供的矩阵(图像)转换函数有两个:
cv.warpAffine()——对应23的矩阵转换——可以实现平移和翻转(反转还需要一个cv.getRotationMatrix2D来获取旋转后的移动坐标),以及仿射变换——getAffineTransform
cv.warpPerspective()——对应3
3的矩阵转换——可以应用透射变换
以及一个图像大小按比例修改的函数:cv.resize()

warpAffine——参数

  • 参数一:输入图像
  • 参数二:平移矩阵——list类型
  • 参数三:输出图像大小(采用元组(宽值,高值))
  • 参数四:bordermode——边界值处理——控制输出图像与原图像异常值是否处理,如何处理的参数
  • 参数五:bordervalue边界值——一般默认为0不处理
  • 说明——参数四五,在简单应用中不涉及,这里就不细讲了,后边会慢慢整理进阶的。
    在这里插入图片描述
    平移时——你应该知道移动的x,y值,并满足以上矩阵:(也就是把x,y值放在这个位置——创建这样的矩阵采用numpy实现)——采用numpy.float32创建

getRotationMatrix2D——参数

opencv使用该函数实现了任一点旋转的方法——并且返回一个warpAffine的平移参数矩阵(2*3)

  • 参数一:旋转中心位置坐标(采用二元元组传入)
  • 参数二:旋转角度——正值为逆时针旋转角度
  • 参数三:缩放比例——一般不变传入1即可

cv.getAffineTransform——参数

opencv使用该函数实现了通过取图像三点以及变化后的对应位置,来实现变换的方法——并且返回一个warpAffine的平移参数矩阵(2*3)——实现仿射变换

  • 参数一:变化前的三个点的矩阵——list类型采用numpy.float32创建
  • 参数二:变化后的三个点的矩阵——list类型

warpPerspective——参数

cv.warpPerspective实现透射变换——所以需要对空间有一个坐标——也就是对应着23到33矩阵变化的需要——当然实现透射变换还需要一个函数的帮助,来获取这样的移动参数矩阵

  • 参数一:输入图像
  • 参数二:移动(变换)参数
  • 参数三:输出图像大小
  • 参数四:插值方式
  • 参数五六与warpAffine一样,都是对变换的边界进行处理的参数设置

cv.getPerspectiveTransform——参数

该函数为透色变换提供移动参数——一个3*3的移动参数矩阵。
而这样的参数,来源于原图像中的4个点坐标,以及设置的改变后对应的坐标

  • 参数一:原图像四个坐标——list类型采用numpy.float32创建
  • 参数二:变换后的坐标——list类型

resize——参数

  • 参数一:输入图像
  • 参数二:输出大小——设置输出大小(二元元组)
  • 参数三:x伸展比例——参数二有具体大小,不为None时,x,y伸展不用填写,是无效的
  • 参数四:y伸展比例——也就是说,选择一种伸缩方式即可
  • 参数五:插值
  • 常见插值为:
  • cv.INTER_AREA——用于缩小
  • cv.INTER_LINEAR——用于缩放(放大/缩小都可以)
  • cv.INTER_CUBIC——用于低分辨率

代码实例

缩放

这里不要设置窗体可调——不然会显示不出来伸缩变换的。

import cv2 as cv
import numpy as np


if __name__ == "__main__":
    img = cv.imread('../imag_in_save/open_class.png')
    # cv.namedWindow('imag', cv.WINDOW_NORMAL)

    img_size_h, img_size_w = img.shape[:2]  # 获取形状大小——即第一位为行数,第二位为列数
    res = cv.resize(img, (img_size_w*1, img_size_h*3), interpolation=cv.INTER_CUBIC)
    # 高度变为3倍
    # 除了这样的操作外,还可以如此
    # res = cv.resize(img, None, fx=1, fy=3, interpolation=cv.INTER_CUBIC)
    cv.imshow('imag', res)
    cv.waitKey(0)
    cv.destroyAllWindows()

效果:伸缩变换前
opencv 图像几何变换基础讲解——含仿射和透射变换基础_第1张图片
伸缩变换后
opencv 图像几何变换基础讲解——含仿射和透射变换基础_第2张图片

平移

import cv2 as cv
import numpy as np


if __name__ == "__main__":
    img = cv.imread('../imag_in_save/open_class.png')

    img_size_h, img_size_w = img.shape[:2]  # 获取形状大小——即第一位为行数,第二位为列数
    move_value = np.float32([[1, 0, 66], [0, 1, 66]])  # 前面的公式可知:这里是移动x = 66, y = 66
    res = cv.warpAffine(img, move_value, (img_size_w, img_size_h))

    cv.imshow('imag', res)
    cv.waitKey(0)
    cv.destroyAllWindows()

效果:
opencv 图像几何变换基础讲解——含仿射和透射变换基础_第3张图片

翻转(或者说叫做2D平移旋转)

import cv2 as cv
import numpy as np


if __name__ == "__main__":
    img = cv.imread('../imag_in_save/open_class.png')
    # cv.namedWindow('imag', cv.WINDOW_NORMAL)

    img_size_h, img_size_w = img.shape[:2]  # 获取形状大小——即第一位为行数,第二位为列数
    move_value = cv.getRotationMatrix2D((img_size_w/2.0, img_size_h/2.0), 90, 1)  # 获取旋转后的移动坐标矩阵
    res = cv.warpAffine(img, move_value, (img_size_w, img_size_h))  # 实现平移旋转

    cv.imshow('imag', res)
    cv.waitKey(0)
    cv.destroyAllWindows()

效果:
opencv 图像几何变换基础讲解——含仿射和透射变换基础_第4张图片

仿射变换

import cv2 as cv
import numpy as np

if __name__ == "__main__":
    img = cv.imread('../imag_in_save/open_class.png')

    img_size_h, img_size_w = img.shape[:2]  # 获取形状大小——即第一位为行数,第二位为列数

    pst1 = np.float32([[20, 30], [50, 100], [100, 100]])  # 原图像的点坐标
    pst2 = np.float32([[40, 30], [50, 100], [80, 120]])  # 原点一一对应的变换点坐标
    move_value = cv.getAffineTransform(pst1, pst2)  # 获取仿射变换的平移坐标
    res = cv.warpAffine(img, move_value, (img_size_w, img_size_h))  # 实现平移——得到仿射变换的图形
    cv.imshow('res_imag', res)  # 显示变化后的图形
    cv.imshow('imag', img)  # 显示原图形
    cv.waitKey(0)
    cv.destroyAllWindows()

效果:
opencv 图像几何变换基础讲解——含仿射和透射变换基础_第5张图片

投射变换(可以用来解决拍摄的图形不平整进行平整变化的转换)

import cv2 as cv
import numpy as np

if __name__ == "__main__":
    img = cv.imread('../imag_in_save/open_class.png')

    img_size_h, img_size_w = img.shape[:2]  # 获取形状大小——即第一位为行数,第二位为列数
	pst1 = np.float32([[56, 65], [368, 52], [28, 387], [389, 390]])  # 需要四个点坐标_要求三个点不共线,# 将四点间内容作为显示内容
    pst2 = np.float32([[0, 0], [300, 0], [0, 300], [300, 300]])  # 四点的坐标变化
    move_value = cv.getPerspectiveTransform(pst1, pst2)  # 获取投射变换的平移坐标
    res = cv.warpPerspective(img, move_value, (300, 300))  # 获取投射变换的图形——大小尽量与变化后的四点坐标等大宽度
    cv.imshow('res_imag', res)
    cv.imshow('imag', img)
    cv.waitKey(0)
    cv.destroyAllWindows()

效果:操作前后——如果图形是2d平整的,可能就会编程内凹或者其它的一些畸变。
以下图形实现通过透视变换,得到更平整的图像
视角变浅
opencv 图像几何变换基础讲解——含仿射和透射变换基础_第6张图片
opencv 图像几何变换基础讲解——含仿射和透射变换基础_第7张图片
**我的效果:**确实有透视的视角变深等变化
opencv 图像几何变换基础讲解——含仿射和透射变换基础_第8张图片

你可能感兴趣的:(#,Opencv学习笔记,python,opencv,计算机视觉,numpy)