欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

机器视觉专栏(三)图像的几何变换

程序员文章站 2022-03-31 11:41:15
...

总览

图像的几何变换主要是以下几种:缩放,旋转,仿射变换和透视
变换,接下来我们一一介绍。

图像的缩放:尺度变换

在opencv中提供了缩放的函数cv2.resize,这个函数可以按照倍数进行缩放,或者是直接将图像的大小变成指定的。说到缩放,我们首先想到的是如何处理变换之后图片中缺少的像素如何填充,在介绍缩放函数之前我们先来了解什么是插值。
插值算法,顾名思义就是如何填充/去掉图像中的像素,使得图像在变换大小过后中原有的特征得以保留。opencv支持的插值算法有三种:
cv2.INTER_AREA : 最近邻插值,把一个点的像素值直接设置为这个点最近的点的像素,但是这个方法会让图像出现很多色块
cv2.INTER_LINEAR : 双线性插值,这里使用了一维下的线性插值算法在二维上的推广,一维上的插值算法就是在两点之间填上一条直线,二维中只要4个方程对上下左右四个像素解方程就行
cv2.INTER_CUBIC:立方插值是在双线性插值算法的基础上进行改进,除了考虑函数值以外还添加了变化率的估量,只不过速度很慢就是了。
下面是代码的演示

import cv2
import numpy as np



img = cv2.imread(r"C:\Users\LIMN2O4\Pictures\lena.jpg")
# 按照倍数缩放


res1 = cv2.resize(img,(0,0),fx = 1.3,fy = 1.3,interpolation=cv2.INTER_CUBIC)

# 按照大小进行变化
res2 = cv2.resize(img,(500,500),interpolation=cv2.INTER_AREA)


cv2.imshow("out1",res1)
cv2.imshow("out2",res2)

cv2.waitKey(0)

图像的旋转

图像的旋转是通过图像的“投影”实现的,相当于将一张图像的某个点投影到另外一个点。我们将一个一个点投影到另外的点事实上变换算法的过程。我们将原矩阵乘以一个变换矩阵,得到的新矩阵就是投影完成之后的矩阵就是我们想要的图像。
具体的矩阵是通过cv2.getRotationMatrix2D 实现的,这个函数需要的参数是旋转的角度,之后将这个矩阵当作cv2.warpAffine 的参数就行:

import cv2
import numpy as np



img = cv2.imread(r"C:\Users\LIMN2O4\Pictures\lena.jpg")

# 旋转90°

row,col,ch = img.shape
M = cv2.getRotationMatrix2D(((col/2),(row/2)),90,1)
# 参数分别是中心点,角度,缩放尺度
res1 = cv2.warpAffine(img,M,(row,col))

cv2.imshow("out1",res1)

cv2.waitKey(0)

仿射变换和透视变换:

仿射变换很容易理解,就是在源图像中平行的直线,在变换之后的图像中仍然是平行的,这个方法需要三个点在变换前,变换后的坐标。
透视变换是保持原有图形的一种变换方法,在源图像中的直线,在变换后的时候仍是直线,这个方法需要4个点的坐标,我们需要创建一个np.float32 矩阵来保存这两种方法所需的矩阵和坐标点。

import cv2
import numpy as np



img = cv2.imread(r"C:\Users\LIMN2O4\Pictures\lena.jpg")

# 通过三个点的相对位置来确定整个图像

row,col,ch = img.shape

pts1 = np.float32([[0,0],[0,col],[row,0]])
pts2 = np.float32([[0,0],[100,col],[row,50]])
M1 = cv2.getAffineTransform(pts1,pts2)
res1 = cv2.warpAffine(img,M1,(row,col))

pts3 = np.float32([[0,0],[0,col],[row,0],[row,col]])
pts4 = np.float32([[10,10],[10,col-10],[row-10,10],[row-10,col-10]])
M2 = cv2.getPerspectiveTransform(pts3,pts4)

res2 = cv2.warpPerspective(img,M2,(row,col))

cv2.imshow("out1",res1)
cv2.imshow("out2",res2)
cv2.waitKey(0)