Opencv第五章——几何变换

1. 缩放

我们可以通过OpenCV提供的resize()方法实现随意更改图像的大小比例,语法格式如下:

dst = cv2.resize(src, dsize, fx, fy, interpolation)

参数说明:

src: 原始图像

dsize: 输出图像的大小,格式为(宽, 高), 单位为像素

fx: 可选参数, 水平方向上缩放比例

fy:可选参数, 竖直方向上的缩放比例

interpolation:可选参数,缩放的插值方式(指定算法对图像的放大或缩小进行像素的删减和补充)

返回值说明:

dst: 缩放之后的图像

1.1 使用dsize参数实现

dsize参数是一个元组,例如(100, 200),若使用dsize参数,就可以不写fx, fy参数

实现代码如下:

import cv2
img = cv2.imread(r"B:\Python_opencv_book\05\01\demo.png")  
dst1 = cv2.resize(img, (100, 100))  # 按照宽100像素、高100像素的大小进行缩放
dst2 = cv2.resize(img, (400, 400))  # 按照宽400像素、高400像素的大小进行缩放
cv2.imshow("img", img)  # 原图
cv2.imshow("dst1", dst1)  # 缩放图像
cv2.imshow("dst2", dst2)  
cv2.waitKey() 
cv2.destroyAllWindows()  

图像变换结果:

1.2 使用fx参数和fy参数实现

fx参数和fy参数可以使用浮点值,小于1表示缩小,大于1表示放大

计算公式如下:

新图像宽度:round(fx X 原图像宽度)

新图像高度:round(fy X 原图像高度)

实现代码如下:

import cv2
img = cv2.imread(r"C:\Users\cgs\Desktop\pictures\5(3).jpg")  
dst3 = cv2.resize(img, None, fx=1 / 3, fy=1 / 2)  # 将宽缩小到原来的1/3、高缩小到原来的1/2
dst4 = cv2.resize(img, None, fx=2, fy=2)  # 将宽高扩大2倍
cv2.imshow("img", img)  
cv2.imshow("dst3", dst3)  
cv2.imshow("dst4", dst4)  
cv2.waitKey()  
cv2.destroyAllWindows()  

图像变换结果:

2. 翻转

Opencv使用cv2.flip()方法实现翻转效果,语法结构如下:

dst = cv2.flip(src, flipCode)

参数说明:

src:原始图像

flipCode:翻转类型

   0:沿着X轴翻转、

   正数:沿着Y轴翻转

   负数: 同时沿着X轴, Y轴翻转

返回值说明:

dst:翻转之后的图像

翻转操作实现代码:

import cv2
img = cv2.imread(r"C:\Users\cgs\Desktop\pictures\5(2).jpg")  
dst1 = cv2.flip(img, 0)  # 沿X轴翻转
dst2 = cv2.flip(img, 1)  # 沿Y轴翻转
dst3 = cv2.flip(img, -1)  # 同时沿X轴、Y轴翻转
cv2.imshow("img", img)  # 原图
cv2.imshow("dst_X", dst1)  # 翻转之后的图像
cv2.imshow("dst_Y", dst2)
cv2.imshow("dst3_XY", dst3)
cv2.waitKey()  
cv2.destroyAllWindows()  

 图像翻转结果:

3. 仿射变换

       仿射变换是一种保持点、直线和面之间的平行关系的线性变换。简单来说,它是一种几何变换,包括了平移、缩放、旋转和剪切等操作,可以把一个图形变换成另一个图形,而不改变图形的基本结构。

       Opencv使用cv2.warpAffine()方法实现仿射变换效果,语法结构如下:

dst:cv2.wrapAffine(src, M, dsize, flags, borderMode, borderValue)

参数说明:

src:原始图像

M:一个二行三列的矩阵, 根据此矩阵的值变换原图中的像素位置

dsize:输出图像的尺寸大小

flags:可选参数, 插值方式

borderMode:可选参数, 边界类型

borderValue:可选参数, 边界值, 默认为0

返回值说明:

dst:输出图像

M叫做仿射矩阵, 实际上是一个2X3的列表:

                                      [[a, b, c],[d, e, f]]

输出图像按照以下公式进行计算

                                      (横坐标)新x = 原x  乘以 a + 原y 乘以 b + c 

                                    (纵坐标)新y = 原y  乘以 d + 原y 乘以 e + f

下面介绍创建M的两种方式:

                                        import numpy as np

                                        M = np.zeros((2, 3), np.float32)

                                        improt numpy as np

                                        M = np.float32([[1, 2, 3],[4, 5, 6]])

3.1 平移

M = [[1, 0, 水平移动的距离], [0, 1, 垂直移动的距离]]

若水平移动距离为正数,则向右移动

若垂直移动距离为正数, 则向下移动

实现代码如下(右下方平移):

import cv2
import numpy as np
img = cv2.imread(r"C:\Users\cgs\Desktop\pictures\5(2).jpg")  
rows = len(img)  # 图像像素行数
cols = len(img[0])  # 图像像素列数
M = np.float32([[1, 0, 50],  # 横坐标向右移动50像素
                [0, 1, 100]])  # 纵坐标向下移动100像素
dst = cv2.warpAffine(img, M, (cols, rows))
cv2.imshow("img", img)  # 原图
cv2.imshow("dst", dst)  # 仿射变换效果
cv2.waitKey()  
cv2.destroyAllWindows()  

操作结果图片如下:

大家可以自行修改M的值来尝试进行其他方向的移动!!! 

3.2 旋转

Opencv提供了getRotationMatrix2D()方法来自动计算出旋转图像的M矩阵,语法格式如下:

M = getRotationMatrix2D(certer, angle, scale)

参数说明:

certer:旋转的中心点坐标

angle:旋转的角度(正数逆时针, 负数顺时针)

scale:缩放比例(浮点类型)

返回值说明:

M:计算出的仿射矩阵 

 旋转实现代码:

import cv2
img = cv2.imread(r"C:\Users\cgs\Desktop\pictures\5(2).jpg")  
rows = len(img)  # 图像像素行数
cols = len(img[0])  # 图像像素列数
center = (rows / 2, cols / 2)  # 图像的中心点
M = cv2.getRotationMatrix2D(center, 30, 0.8)  # 以图像为中心,逆时针旋转30度,缩放0.8倍
dst = cv2.warpAffine(img, M, (cols, rows))  # 按照M进行仿射
cv2.imshow("img", img)  # 原图
cv2.imshow("dst", dst)  # 仿射变换效果
cv2.waitKey()  
cv2.destroyAllWindows()  

操作图像结果:

3.3 倾斜

OpenCV通过定位图像的三个点来计算倾斜效果(左上, 右上,左下),并根据这三个点的位置变化计算其他像素的位置变化。OpenCV提供了getSffineTransform()方法来激素那倾斜图像的M矩阵。语法格式如下:

M = cv2.getAffineTransform(src, dst)

参数说明:

src: 原图三个点坐标, 格式为3行2列的32位浮点数列表

dst: 倾斜图像的三个点坐标, 格式为3行2列的32位浮点数列表

返回值说明:

M:计算出的仿射矩阵

 实现向右倾斜效果:

import cv2
import numpy as np
img = cv2.imread(r"C:\Users\cgs\Desktop\pictures\5(2).jpg")  
rows = len(img)  # 图像像素行数
cols = len(img[0])  # 图像像素列数
p1 = np.zeros((3, 2), np.float32)  # 32位浮点型空列表,原图三个点
p1[0] = [0, 0]  # 左上角点坐标
p1[1] = [cols - 1, 0]  # 右上角点坐标
p1[2] = [0, rows - 1]  # 左下角点坐标
p2 = np.zeros((3, 2), np.float32)  # 32位浮点型空列表,倾斜图三个点
p2[0] = [50, 0]  # 左上角点坐标,向右挪50像素
p2[1] = [cols - 1, 0]  # 右上角点坐标,位置不变
p2[2] = [0, rows - 1]  # 左下角点坐标,位置不变
M = cv2.getAffineTransform(p1, p2)  # 根据三个点的变化轨迹计算出M矩阵
dst = cv2.warpAffine(img, M, (cols, rows))  # 按照M进行仿射
cv2.imshow('img', img)  # 原图
cv2.imshow('dst', dst)  # 仿射变换效果
cv2.waitKey()  
cv2.destroyAllWindows()  

效果图像:

 大家可以尝试如何将图像进行向左倾斜!!!

示例代码入下:

import cv2
import numpy as np
img = cv2.imread(r"C:\Users\cgs\Desktop\pictures\5(2).jpg")  
rows = len(img)  # 图像像素行数
cols = len(img[0])  # 图像像素列数
p1 = np.zeros((3, 2), np.float32)  # 32位浮点型空列表,原图三个点
p1[0] = [0, 0]  # 左上角点坐标
p1[1] = [cols - 1, 0]  # 右上角点坐标
p1[2] = [0, rows - 1]  # 左下角点坐标
p2 = np.zeros((3, 2), np.float32)  # 32位浮点型空列表,倾斜图三个点
p2[0] = [0, 0]  # 左上角点坐标不变
p2[1] = [cols - 1 - 50, 0]  # 右上角点坐标向左移动50像素
p2[2] = [50, rows - 1]  # 左下角点坐标向右移动50像素
M = cv2.getAffineTransform(p1, p2)  # 根据三个点的变化轨迹计算出M矩阵
dst = cv2.warpAffine(img, M, (cols, rows))  # 按照M进行仿射
cv2.imshow('img', img)  # 原图
cv2.imshow('dst', dst)  # 仿射变换效果
cv2.waitKey()  
cv2.destroyAllWindows()  

效果图像: 

 

4.透视

OpenCV需要通过定位图像的四个点来计算透视效果,该操作不保证图像的“平直性”和“平行性”。OpenCV通过warpPerspective()方法来实现透视效果,语法结构如下:

dst = cv2.warpPerspective(src, M, dsize, flags, boarderMode, boarderValue)

参数说明:

src:原始图像

M:3行3列矩阵

dsize:输出图像尺寸大小

flags:可选参数, 插值方式

borderMode:可选参数, 边界类型

borderValue:可选参数, 边界值

返回值说明:

dst:透视变换后的输出图像

OpenCV提供了getPerspectiveTransform()方法来计算M矩阵, 该方法语法结构如下:

M = cv2.getPerspectiveTransform(src, dst)

参数说明:

src: 原图四个点坐标, 格式为4行2列的32位浮点数列表

dst: 透视图的四个点坐标

返回值说明:

M:计算出的仿射矩阵

 模拟从底部观察图像得到的透视效果:

import cv2
import numpy as np
img = cv2.imread(r"C:\Users\cgs\Desktop\pictures\5(2).jpg")  
rows = len(img)  # 图像像素行数
cols = len(img[0])  # 图像像素列数
p1 = np.zeros((4, 2), np.float32)  # 32位浮点型空列表,保存原图四个点
p1[0] = [0, 0]  # 左上角点坐标
p1[1] = [cols - 1, 0]  # 右上角点坐标
p1[2] = [0, rows - 1]  # 左下角点坐标
p1[3] = [cols - 1, rows - 1]  # 右下角点坐标
p2 = np.zeros((4, 2), np.float32)  # 32位浮点型空列表,保存透视图四个点
p2[0] = [90, 0]  # 左上角点坐标,向右移动90像素
p2[1] = [cols - 90, 0]  # 右上角点坐标,向左移动90像素
p2[2] = [0, rows - 1]  # 左下角点坐标,位置不变
p2[3] = [cols - 1, rows - 1]  # 右下角点坐标,位置不变
M = cv2.getPerspectiveTransform(p1, p2)  # 根据四个点的变化轨迹计算出M矩阵
dst = cv2.warpPerspective(img, M, (cols, rows))  # 按照M进行仿射
cv2.imshow('img', img)  # 原图
cv2.imshow('dst', dst)  # 仿射变换效果
cv2.waitKey()  
cv2.destroyAllWindows()  

效果图像:

 

 大家也来试试如下实现从顶部观察图像实现的透视效果吧!!!

下面是我给出的示例:

import cv2
import numpy as np
img = cv2.imread(r"C:\Users\cgs\Desktop\pictures\5(2).jpg")  
rows = len(img)  # 图像像素行数
cols = len(img[0])  # 图像像素列数
p1 = np.zeros((4, 2), np.float32)  # 32位浮点型空列表,保存原图四个点
p1[0] = [0, 0]  # 左上角点坐标
p1[1] = [cols - 1, 0]  # 右上角点坐标
p1[2] = [0, rows - 1]  # 左下角点坐标
p1[3] = [cols - 1, rows - 1]  # 右下角点坐标
p2 = np.zeros((4, 2), np.float32)  # 32位浮点型空列表,保存透视图四个点
p2[0] = [0, 0]  # 左上角点坐标位置不变
p2[1] = [cols - 1, 0]  # 右上角点坐标位置不变
p2[2] = [90, rows - 1]  # 左下角点坐标向右移动90像素
p2[3] = [cols - 90, rows - 1]  # 右下角点坐标向左移动90像素
M = cv2.getPerspectiveTransform(p1, p2)  # 根据四个点的变化轨迹计算出M矩阵
dst = cv2.warpPerspective(img, M, (cols, rows))  # 按照M进行仿射
cv2.imshow('img', img)  # 原图
cv2.imshow('dst', dst)  # 仿射变换效果
cv2.waitKey()  
cv2.destroyAllWindows()  

效果图像:

 

本章节内容就到此结束了,欢迎大家继续关注后续内容!!! 

  • 18
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值