OpenCV实现常见的四种图像几何变换


Posted in Python onApril 01, 2022

准备图片

选择一张shape为(500,500,3)的梵高的《星月夜》以便示例。

OpenCV实现常见的四种图像几何变换

1. 缩放 cv2.resize()方法

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

src 原图(的数组)

dsize: 输出图像的大小 格式:(a,b)。

设定dsize后就无需再设置fx和fy

fx 可选参数 水平方向缩放比

fy 可选参数 垂直方向缩放比

fx和fy不同于dsize,fx和fy是各是一个比值,如设为2,则表示放大2倍,设为1/2则表示缩小到原来的1/2

import cv2
img = cv2.imread("The_Starry_Night.jpg")

dst1 = cv2.resize(img, (200, 200))
dst2 = cv2.resize(img, (900, 900))
cv2.imshow("img", img)
cv2.imshow("dst1", dst1)
cv2.imshow("dst2", dst2)
cv2.waitKey()
cv2.destroyAllWindows()

执行结果如图所示,相比原图,图像得到了指定大小的缩小与放大。

OpenCV实现常见的四种图像几何变换

使用fx和fy参数,则需要手动把dsize设为None。

import cv2
img = cv2.imread("The_Starry_Night.jpg")  
# 将宽缩小到原来的1/3、高缩小到原来的1/2
dst3 = cv2.resize(img, None, fx=1 / 3, fy=1 / 2) 
# 将宽高扩大2倍
dst4 = cv2.resize(img, None, fx=2, fy=2)  
cv2.imshow("img", img)
cv2.imshow("dst3", dst3) 
cv2.imshow("dst4", dst4) 
cv2.waitKey() 
cv2.destroyAllWindows()

结果呈现:

OpenCV实现常见的四种图像几何变换

2. 翻转 cv2.flip()方法

flip(src, flipCode, dst=None)

src 图像(数组)

flipCode 翻转代码。可以是0,正数,负数。0表示沿X轴(水平方向的轴)翻转。1表示沿Y轴(竖直方向的轴)翻转。

负数表示同时沿X轴和Y轴翻转。

讲原图经过着三种翻转后,与原图拼在一块,呈现出了这种奇观:

import cv2
img = cv2.imread("The_Starry_Night.jpg")
dst1 = cv2.flip(img, 0)
dst2 = cv2.flip(img, 1)
dst3 = cv2.flip(img, -1)
cv2.imshow("img", img)
cv2.imshow("dst1", dst1)
cv2.imshow("dst2", dst2)
cv2.imshow("dst3", dst3)
cv2.waitKey()
cv2.destroyAllWindows()

OpenCV实现常见的四种图像几何变换

将翻转结果放在同一张画布中

import cv2
import numpy as np
img = cv2.imread("The_Starry_Night.jpg")
dst1 = cv2.flip(img, 0)
dst2 = cv2.flip(img, 1)
dst3 = cv2.flip(img, -1)
a, b, c = img.shape
canvas = np.ones((2 * a, 2 * b, c), np.uint8) * 255
canvas[0:b, 0:a] = img
canvas[b:2*b, 0:a] = dst1
canvas[0:b, a:2*a] = dst2
canvas[b:2*b, a:2*a] = dst3
cv2.imshow("pic", canvas)
cv2.waitKey()
cv2.destroyAllWindows()
# 保存图片
# cv2.imwrite("final_pic", canvas)

结果呈现:

OpenCV实现常见的四种图像几何变换

3. 仿射变换 warpAffine()方法

常见的仿射变换有平移,旋转和倾斜变换。

仿射变换使用cv2.warpAffine()方法完成

warpAffine(src, M, dsize, dst=None, flags=None, borderMode=None, borderValue=None)

src 原图

M 是一个二行三列的矩阵,也称仿射矩阵。warpAffine方法根据此矩阵的值来变换像素的位置。

M = [[a, b, c], [d, e, f]],则像素的变换公式为:

X = x × a + y × b + c

Y = x × d + y × e + f

其中x,y指原像素的x、y轴坐标。X,Y指变换后的X,Y坐标。

dsize 输出图像的尺寸。(不带放缩,增大的部分用黑色色素(0)填充)

这三个参数是常用的参数。其余参数建议使用默认值。

flags表示插入方式,borderMode是边界类型,borderValue表示边界值(默认0)。dst表示反射变换后输出的图像。

3.1 平移

以将《星月夜》向左平移50个像素,向下平移100个像素为例。

则M数组应写为[[1, 0, 50], [0, 1, 100]]:

import cv2
import numpy as np
img = cv2.imread("The_Starry_Night.jpg")
rows = len(img)
cols = len(img[0])
M = np.float32([[1, 0, 50],
                [0, 1, 100]]) 
dst = cv2.warpAffine(img, M, (cols, rows))
cv2.imshow("img", img) 
cv2.imshow("dst", dst) 
cv2.waitKey() 
cv2.destroyAllWindows()

OpenCV实现常见的四种图像几何变换

如图所示,图像按照我们的预期成功被平移。

只是这样得到的图像有色素损失,我们丢失了超出画布之外的数据。

为了避免损失,可以取设置dsize参数来控制输出图像的大小。

修改后的代码如下:

import cv2
import numpy as np
img = cv2.imread("The_Starry_Night.jpg")
rows = len(img)
cols = len(img[0])
M = np.float32([[1, 0, 50],
                [0, 1, 100]])
dst = cv2.warpAffine(img, M, (cols+200, rows+200))
cv2.imshow("img", img)
cv2.imshow("dst", dst)
cv2.waitKey()
cv2.destroyAllWindows()

优化后的程序执行效果:

OpenCV实现常见的四种图像几何变换

3.2 旋转

旋转也是通过M矩阵来实现的,这个矩阵的运算较复杂,

OpenCV提供了getRotationMatrix2D()方法来计算旋转操作的M矩阵

getRotationMatrix2D(center, angle, scale)

center 指旋转中心的坐标

angle指旋转的角度

scale值缩放的比例。(旋转过程支持缩放)

import cv2
img = cv2.imread("The_Starry_Night.jpg")
rows = len(img) 
cols = len(img[0]) 
center = (rows / 2, cols / 2) 
M = cv2.getRotationMatrix2D(center, 30, 0.8) 
dst = cv2.warpAffine(img, M, (cols, rows)) 
cv2.imshow("img", img) 
cv2.imshow("dst", dst) 
cv2.waitKey() 
cv2.destroyAllWindows()

旋转效果如图所示:

OpenCV实现常见的四种图像几何变换

3.3 倾斜

OpenCV需要定位到图像的三个点的位置来计算倾斜效果,即左上角,右上角和左下角。

图像的倾斜也是根据M矩阵实现,得出矩阵的运算较复杂,通过getAffineTransform 方法实现。

语法

getAffineTransform(src, dst)

src是原图像的左上角,右上角和左下角三个点的坐标。三维数组格式,形如[[a, b], [c, d], [e, f]]。

dst是倾斜后这三个点预期的坐标。格式同上。

要保持左上,右下,左下三个点的顺序不能乱。

以将《星月夜》保持左下角和右上角坐标不变,左上角((0,0)处)向右移动150个像素长度。

代码如下:

import cv2
import numpy as np
img = cv2.imread("The_Starry_Night.jpg")
rows = len(img)
cols = len(img[0])
p1 = np.array([[0, 0], [cols - 1, 0], [0, rows - 1]], dtype=np.float32)
p2 = np.array([[150, 0], [cols - 1, 0], [0, rows - 1]], dtype=np.float32)
M = cv2.getAffineTransform(p1, p2)
dst = cv2.warpAffine(img, M, (cols, rows))
cv2.imshow('img', img)
cv2.imshow('dst', dst)
cv2.waitKey()
cv2.destroyAllWindows()

程序执行效果如下:

OpenCV实现常见的四种图像几何变换

4. 透视

透视的实现使用的是warpPerspective()方法,而不再是用于平移、旋转、倾斜的warpAffine()方法。

使用warpPerspective()方法也需要通过M矩阵来计算透视效果,计算透视的M矩阵可以使用getPerspectiveTransform()方法。

getPerspectiveTransform(src, dst, solveMethod=None)

该方法常用的参数有两个,分别为原图的四个点的坐标(scr) 和 透视后四个点的坐标(dst)。Opcv需要通过定位图像的这四个点来计算透视效果。四个点依次为左上,右上,左下,右下。

坐标格式为二维数组格式,形如[[a, b],[c, d],[e, f],[g, h]]。

示例代码如下:

import cv2
import numpy as np
img = cv2.imread("The_Starry_Night.jpg")
rows = len(img)
cols = len(img[0])
# 原图的四点坐标
p1 = np.zeros((4, 2), np.float32)
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)
p2[0] = [150, 0]
p2[1] = [cols - 150, 0]
p2[2] = [0, rows - 1]  # 不变
p2[3] = [cols - 1, rows - 1]  # 不变
M = cv2.getPerspectiveTransform(p1, p2)
dst = cv2.warpPerspective(img, M, (cols, rows))
cv2.imshow('The_Starry_Night', img)
cv2.imshow('The_Starry_Night2', dst)
cv2.waitKey()
cv2.destroyAllWindows()

展示原图和透视后的图像效果:

OpenCV实现常见的四种图像几何变换

到此这篇关于OpenCV实现常见的四种图像几何变换的文章就介绍到这了,更多相关OpenCV图像几何变换内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
Python 执行字符串表达式函数(eval exec execfile)
Aug 11 Python
浅谈Python 字符串格式化输出(format/printf)
Jul 21 Python
Python编程实现双击更新所有已安装python模块的方法
Jun 05 Python
基于python的字节编译详解
Sep 20 Python
100行Python代码实现自动抢火车票(附源码)
Jan 11 Python
Django中ajax发送post请求 报403错误CSRF验证失败解决方案
Aug 13 Python
Python英文文章词频统计(14份剑桥真题词频统计)
Oct 13 Python
python 实现从高分辨图像上抠取图像块
Jan 02 Python
Python3.7下安装pyqt5的方法步骤(图文)
May 12 Python
python实现扫雷游戏的示例
Oct 20 Python
使用Python通过oBIX协议访问Niagara数据的示例
Dec 04 Python
python3列表删除大量重复元素remove()方法的问题详解
Jan 04 Python
关于Python使用turtle库画任意图的问题
Apr 01 #Python
python套接字socket通信
python文件与路径操作神器 pathlib
Python下载商品数据并连接数据库且保存数据
Python turtle编写简单的球类小游戏
Pandas实现DataFrame的简单运算、统计与排序
Mar 31 #Python
Pandas数据结构之Series的使用
Mar 31 #Python
You might like
在项目中寻找代码的坏命名
2012/07/14 PHP
php实现自动获取生成文章主题关键词功能的深入分析
2013/06/03 PHP
php 获取页面中指定内容的实现类
2014/01/23 PHP
PHP解密Unicode及Escape加密字符串
2015/05/17 PHP
PHP实现表单提交数据的验证处理功能【防SQL注入和XSS攻击等】
2017/07/21 PHP
jQuery代码优化 事件委托篇
2011/11/01 Javascript
javascript验证身份证完全方法具体实现
2013/11/18 Javascript
jquery如何获取复选框的值
2013/12/12 Javascript
javasctipt如何显示几分钟前、几天前等
2014/04/30 Javascript
JavaScript实现班级随机点名小应用需求的具体分析
2014/05/12 Javascript
JavaScript实现大数的运算
2014/11/24 Javascript
javascript中获取元素标签中间的内容的实现方法
2016/10/08 Javascript
JS操作input标签属性checkbox全选的实现代码
2017/03/02 Javascript
js实现颜色阶梯渐变效果(Gradient算法)
2017/03/21 Javascript
关于vue.js过渡css类名的理解(推荐)
2017/04/10 Javascript
Node.js中看JavaScript的引用
2017/04/22 Javascript
vuejs使用$emit和$on进行组件之间的传值的示例
2017/10/04 Javascript
jQuery实现的响应鼠标移动方向插件用法示例【附源码下载】
2018/08/28 jQuery
JavaScript实现简单轮播图效果
2018/12/01 Javascript
JavaScript中的事件与异常捕获详析
2019/02/24 Javascript
Threejs实现滴滴官网首页地球动画功能
2020/07/13 Javascript
解决vue组件销毁之后计时器继续执行的问题
2020/07/21 Javascript
Python实现的数据结构与算法之快速排序详解
2015/04/22 Python
微信跳一跳python辅助脚本(总结)
2018/01/11 Python
使用PyQt的QLabel组件实现选定目标框功能的方法示例
2020/05/19 Python
Python3.9最新版下载与安装图文教程详解(Windows系统为例)
2020/11/28 Python
用python读取xlsx文件
2020/12/17 Python
你正在寻找的CSS3 动画技术
2011/07/27 HTML / CSS
一款纯css3实现的颜色渐变按钮的代码教程
2014/11/12 HTML / CSS
使用CSS3美化HTML表单的技巧演示
2016/05/17 HTML / CSS
全球领先的鞋类零售商:The Walking Company
2016/07/21 全球购物
师范生见习总结范文
2015/06/23 职场文书
nginx前后端同域名配置的方法实现
2021/03/31 Servers
利用python实时刷新基金估值(摸鱼小工具)
2021/09/15 Python
Java无向树分析 实现最小高度树
2022/04/09 Javascript
使用CSS实现百叶窗效果示例代码
2023/05/07 HTML / CSS