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正则表达式介绍
Aug 06 Python
python实现斐波那契递归函数的方法
Sep 08 Python
Python环境搭建之OpenCV的步骤方法
Oct 20 Python
Python学生成绩管理系统简洁版
Apr 05 Python
Python之读取TXT文件的方法小结
Apr 27 Python
django 解决manage.py migrate无效的问题
May 27 Python
使用Python实现将list中的每一项的首字母大写
Jun 11 Python
python爬虫开发之PyQuery模块详细使用方法与实例全解
Mar 09 Python
Python实现Excel自动分组合并单元格
Feb 22 Python
Python源码解析之List
May 21 Python
Python学习之包与模块详解
Mar 19 Python
Python中np.random.randint()参数详解及用法实例
Sep 23 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
smarty模板中拼接字符串的方法
2014/02/14 PHP
PHP时间函数使用详解
2019/03/21 PHP
JavaScript 撑出页面文字换行
2009/06/15 Javascript
事件模型在各浏览器中存在差异
2010/10/20 Javascript
javascript延时加载之defer测试
2012/12/28 Javascript
一段非常简单的js判断浏览器的内核
2014/08/17 Javascript
jQuery插件animateSlide制作多点滑动幻灯片
2015/06/11 Javascript
Easyui form combobox省市区三级联动
2016/01/13 Javascript
jQuery头像裁剪工具jcrop用法实例(附演示与demo源码下载)
2016/01/22 Javascript
jQuery中inArray方法注意事项分析
2016/01/25 Javascript
angular双向绑定模拟探索
2016/12/26 Javascript
jQuery实现复选框的全选和反选
2017/02/02 Javascript
vue 实现 ios 原生picker 效果及实现思路解析
2017/12/06 Javascript
使用Vue的slot插槽分发父组件内容实现高度复用、更加灵活的组件(推荐)
2018/05/01 Javascript
vue实现form表单与table表格的数据关联功能示例
2019/01/29 Javascript
利用Dectorator分模块存储Vuex状态的实现
2019/02/05 Javascript
详解vue-template-admin三级路由无法缓存的解决方案
2020/03/10 Javascript
es6函数之尾递归用法实例分析
2020/04/25 Javascript
Python中为feedparser设置超时时间避免堵塞
2014/09/28 Python
Python手机号码归属地查询代码
2016/05/04 Python
python队列通信:rabbitMQ的使用(实例讲解)
2017/12/22 Python
浅谈python中requests模块导入的问题
2018/05/18 Python
flask中的wtforms使用方法
2018/07/21 Python
Python3爬虫学习入门教程
2018/12/11 Python
python圣诞树编写实例详解
2020/02/13 Python
Python常用模块函数代码汇总解析
2020/08/31 Python
CSS3圆角边框和边界图片效果实例
2016/07/01 HTML / CSS
美国在线购买内衣网站:HerRoom
2020/02/22 全球购物
秋季运动会广播稿
2014/02/22 职场文书
“四风”问题自我剖析材料思想汇报
2014/09/23 职场文书
毕业证代领委托书
2014/09/26 职场文书
餐饮食品安全责任书
2015/01/29 职场文书
2015年度培训工作总结范文
2015/04/02 职场文书
慈善献爱心倡议书
2015/04/27 职场文书
世界各国短波电台对东亚播送时间频率表(SW)
2021/06/28 无线电
动态规划之使用备忘录来改进Javascript函数
2022/04/07 Javascript