【Python3-OpenCV】实现图像处理—几何变换篇

·  阅读 176
【Python3-OpenCV】实现图像处理—几何变换篇

这是我参与更文挑战的第4天,活动详情查看: 更文挑战

OpenCV是一个C++库,目前流行的计算机视觉编程库,用于实时处理计算机视觉方面的问题,它涵盖了很多计算机视觉领域的模块。在Python中常使用OpenCV库实现图像处理。

image.png

本文将介绍如何在Python3中使用OpenCV实现对图像的几何变换:

参考: Opencv4 官方文档 : docs.opencv.org/4.2.0/

图像的几何变换主要包括:平移、缩放与扩大、旋转、仿射、透视等。

图像变换是建立在矩阵运算基础上的,通过矩阵运算可以很快的找到对应的图像变换关系。

图像缩放与扩大

缩放就是改变图像的大小,常使用cv2.resize()函数进行操作。

图像的大小可以手动指定,也可以使用缩放比例。

cv2.resize()支持多种插值算法,默认使用的是cv2.INTER_LINEAR(不管放大和缩小)

缩小最适合使用:cv2.INTER_AREA

放大最适合使用:cv2.INTER_CUBIC (慢)cv2.INTER_LINEAR

代码如下

import numpy as np
import cv2

## 按比例缩放
img = cv2.imread('E:\\demo\\lena.jpg')
res = cv2.resize(img,None,fx=0.5, fy=0.5, interpolation = cv2.INTER_CUBIC)
#或者按具体宽高进行缩放
#height, width = img.shape[:2]
#res = cv2.resize(img,(2*width, 2*height), interpolation = cv2.INTER_CUBIC)

cv2.imshow('Original image',img)
cv2.imshow('Reduce image',res)

cv2.waitKey(0)
cv2.destroyAllWindows()
复制代码

代码输出为

image.png

同理图像扩大代码如下:

图像扩大

图像扩大代码如下:

import numpy as np
import cv2

## 按比例缩放
img = cv2.imread('E:\\demo\\lena.jpg')
res = cv2.resize(img,None,fx=1.5, fy=1.5, interpolation = cv2.INTER_CUBIC)
#或者按具体宽高进行缩放
#height, width = img.shape[:2]
#res = cv2.resize(img,(2*width, 2*height), interpolation = cv2.INTER_CUBIC)

cv2.imshow('Original image',img)
cv2.imshow('Enlarge image',res)

cv2.waitKey(0)
cv2.destroyAllWindows()
复制代码

输出为:

image.png

图像平移

平移是物体位置的移动。同理图像平移也是基于这个原理,图像上的每个像素对应坐标轴上的点(x,y),图像的平移也就代表坐标轴上点的平移。

Opencv中是通过创建转换矩阵M,进行图像的平移,如下所示:

image.png

并将其放入np.float32类型的Numpy数组中,然后传递给cv.warpAffine函数。

代码如下

参见下面平移为(80, 50)的代码示例:

import numpy as np
import cv2
img = cv2.imread('E:\\demo\\lena.jpg')

rows = img.shape[0]
cols = img.shape[1]

M = np.float32([[1,0,100],[0,1,50]])
dst = cv2.warpAffine(img,M,(cols,rows))

cv2.imshow('Original image',img)
cv2.imshow('img',dst)

cv2.waitKey(0)
cv2.destroyAllWindows()
复制代码

代码输出为

image.png

图像旋转

Opencv中提供了cv2.getRotationMatrix2D函数获得变换矩阵。

第一参数指定旋转圆点;第二个参数指定旋转角度;第三个参数指定缩放比例。

代码如下

import numpy as np
import cv2
img = cv2.imread('E:\\demo\\lena.jpg')

rows = img.shape[0]
cols = img.shape[1]

# 将图像相对于中心旋转90度,而不进行任何缩放。旋转中心,角度,缩放比率
M = cv2.getRotationMatrix2D((cols / 2, rows / 2), 90, 1)
dst = cv2.warpAffine(img, M, (cols, rows))


cv2.imshow('Original image',img)
cv2.imshow('img',dst)

cv2.waitKey(0)
cv2.destroyAllWindows()
复制代码

代码输出为

image.png

图像仿射变换

仿射变换,又称仿射映射,是指在几何中,一个向量空间进行一次线性变换并接上一个平移,变换为另一个向量空间。

图像旋转加上拉升就是图像仿射变换,仿射变化也是需要一个M矩阵就可以实现,但是由于仿射变换比较复杂,一般直接找很难找到这个矩阵。

Opencv提供了根据变换前后三个点的对应关系来自动求解M

这个函数是M=cv2.getAffineTransform(pos1,pos2),

其中两个位置就是变换前后的对应位置关系。

输出的就是仿射矩阵M。然后再使用函数cv2.warpAffine()。生成最后的图片。

image.png

代码如下

import cv2
import numpy as np

img = cv2.imread('E:\\demo\\lena.jpg')

rows = img.shape[0]
cols = img.shape[1]

pts1 = np.float32([[50,50],[200,50],[50,200]])
pts2 = np.float32([[10,100],[200,50],[100,250]])
M = cv2.getAffineTransform(pts1,pts2)
#第三个参数:变换后的图像大小
dst = cv2.warpAffine(img,M,(rows,cols))

cv2.imshow('Original image',img)
cv2.imshow('img',dst)

cv2.waitKey(0)
cv2.destroyAllWindows()
复制代码

代码输出为

image.png

图像透视变换

透视变换是将图片投影到一个新的视平面,也称作投影映射。它是二维(x,y)到三维(X,Y,Z),再到另一个二维(x’,y’)空间的映射。

相对于仿射变换,透视变换提供了更大的灵活性,将一个四边形区域映射到另一个四边形区域(不一定是平行四边形)。它是通过线性变换矩阵乘法实现的。

该变换使用的是一个3x3的矩阵,矩阵的前两行与仿射矩阵相同

(m11,m12,m13,

m21,m22,m23),

也实现了线性变换和平移,第三行用于实现透视变换;

要找到此变换矩阵M,开发者需要在输入图像上有4个点,在输出图像上需要相应的点。在这四个点中,其中三个不应共线。然后可以通过函数cv.getPerspectiveTransform找到变换矩阵。

然后将cv.warpPerspective应用于此3x3转换矩阵。即可生成最终的图像。

代码如下

import cv2
import numpy as np

img = cv2.imread('E:\\demo\\lena.jpg')

rows = img.shape[0]
cols = img.shape[1]
ch   = img.shape[2]

pts1 = np.float32([[56,65],[368,52],[28,387],[389,390]])
pts2 = np.float32([[0,0],[300,0],[0,300],[300,300]])

M = cv2.getPerspectiveTransform(pts1,pts2)

#第三个参数:变换后的图像大小
dst = cv2.warpPerspective(img,M,(300,300))

cv2.imshow('Original image',img)
cv2.imshow('img',dst)
复制代码

代码输出为

image.png

本月将陆续推出相关系列文章,

篇篇精彩,尽请关注。

分类:
后端
标签:
收藏成功!
已添加到「」, 点击更改