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读取指定目录下指定后缀文件并保存为docx
Apr 23 Python
python之matplotlib学习绘制动态更新图实例代码
Jan 23 Python
python:pandas合并csv文件的方法(图书数据集成)
Apr 12 Python
python实现nao机器人身体躯干和腿部动作操作
Apr 29 Python
由面试题加深对Django的认识理解
Jul 19 Python
Python使用QQ邮箱发送邮件实例与QQ邮箱设置详解
Feb 18 Python
python numpy库linspace相同间隔采样的实现
Feb 25 Python
jupyter使用自动补全和切换默认浏览器的方法
Nov 18 Python
Pyqt助手安装PyQt5帮助文档过程图解
Nov 20 Python
python 发送邮件的示例代码(Python2/3都可以直接使用)
Dec 03 Python
十个Python自动化常用操作,即拿即用
May 10 Python
写一个Python脚本下载哔哩哔哩舞蹈区的所有视频
May 31 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
php统计文件大小,以GB、MB、KB、B输出
2011/05/29 PHP
php分页函数示例代码分享
2014/02/24 PHP
Yii的Srbac插件用法详解
2016/07/14 PHP
checkbox 复选框不能为空
2009/07/11 Javascript
Extjs 继承Ext.data.Store不起作用原因分析及解决
2013/04/15 Javascript
屏蔽IE弹出"您查看的网页正在试图关闭窗口,是否关闭此窗口"的方法
2013/12/31 Javascript
javascript引用类型指针的工作方式
2015/04/13 Javascript
jquery在ie7下选择器的问题导致append失效的解决方法
2016/01/10 Javascript
深入浅析JavaScript中的作用域和上下文
2016/03/26 Javascript
基于javascript制作微博发布栏效果
2016/04/04 Javascript
jQuery筛选数组之grep、each、inArray、map的用法及遍历json对象
2016/06/20 Javascript
json格式的javascript对象用法分析
2016/07/04 Javascript
基于JavaScript实现图片连播和联级菜单实例代码
2017/07/28 Javascript
微信小程序左右滑动的实现代码
2017/12/15 Javascript
vue和webpack安装命令详解
2018/06/15 Javascript
vue.js提交按钮时进行简单的if判断表达式详解
2018/08/08 Javascript
Vue项目部署的实现(阿里云+Nginx代理+PM2)
2019/03/26 Javascript
详解关于webpack多入口热加载很慢的原因
2019/04/24 Javascript
JavaScript中的连续赋值问题实例分析
2019/07/12 Javascript
深入分析jQuery.one() 函数
2020/06/03 jQuery
Python实现接受任意个数参数的函数方法
2018/04/21 Python
如何用Python实现简单的Markdown转换器
2018/07/16 Python
python按照多个条件排序的方法
2019/02/08 Python
Python字典遍历操作实例小结
2019/03/05 Python
Python2和Python3的共存和切换使用
2019/04/12 Python
基于pycharm实现批量修改变量名
2020/06/02 Python
python 中的9个实用技巧,助你提高开发效率
2020/08/30 Python
html+css实现自定义图片上传按钮功能
2019/09/04 HTML / CSS
html5 Canvas画图教程(6)—canvas里画曲线之arcTo方法
2013/01/09 HTML / CSS
Sasa莎莎海外旗舰店:香港莎莎美妆平台
2018/03/21 全球购物
Bluebella法国官网:英国性感内衣品牌
2019/05/03 全球购物
违反校纪校规检讨书
2014/02/15 职场文书
学生安全责任书模板
2014/07/25 职场文书
奉献家乡演讲稿
2014/09/16 职场文书
意外伤害赔偿协议书范文
2014/09/23 职场文书
Go语言读取txt文档的操作方法
2022/01/22 Golang