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中json格式数据输出的简单实现方法
Oct 31 Python
python 链接和操作 memcache方法
Mar 04 Python
Django后台获取前端post上传的文件方法
May 28 Python
python高阶爬虫实战分析
Jul 29 Python
关于不懂Chromedriver如何配置环境变量问题解决方法
Jun 12 Python
pow在python中的含义及用法
Jul 11 Python
Django发送邮件和itsdangerous模块的配合使用解析
Aug 10 Python
Python如何实现强制数据类型转换
Nov 22 Python
使用python动态生成波形曲线的实现
Dec 04 Python
Python图像阈值化处理及算法比对实例解析
Jun 19 Python
python学习笔记之多进程
Aug 06 Python
python如何设置静态变量
Sep 07 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使用pear自带的mail类库发邮件的方法
2015/07/08 PHP
详解WordPress开发中wp_title()函数的用法
2016/01/07 PHP
PHP+Jquery与ajax相结合实现下拉淡出瀑布流效果【无需插件】
2016/05/06 PHP
PHP框架Laravel插件Pagination实现自定义分页
2020/04/22 PHP
php微信公众平台配置接口开发程序
2016/09/22 PHP
Z-Blog中用到的js代码
2007/03/15 Javascript
jquery 删除cookie失效的解决方法
2013/11/12 Javascript
JavaScript删除指定子元素代码实例
2015/01/13 Javascript
JavaScript原生对象之Number对象的属性和方法详解
2015/03/13 Javascript
javascript移动开发中touch触摸事件详解
2016/03/18 Javascript
js获取新浪天气接口的实现代码
2016/06/06 Javascript
浅析BootStrap栅格系统
2016/06/07 Javascript
jQuery数据检索中根据关键字快速定位GridView指定行的实现方法
2016/06/08 Javascript
JavaScript实现页面定时刷新(定时器,meta)
2016/10/12 Javascript
Vue.js 2.0学习教程之从基础到组件详解
2017/04/24 Javascript
jQuery实现左右滑动的toggle方法
2018/03/03 jQuery
Android 兼容性问题:java.lang.UnsupportedOperationException解决办法
2017/03/19 Python
Pycharm学习教程(4) Python解释器的相关配置
2017/05/03 Python
Python下实现的RSA加密/解密及签名/验证功能示例
2017/07/17 Python
深入浅析python with语句简介
2018/04/11 Python
Flask-Mail用法实例分析
2018/07/21 Python
python tornado使用流生成图片的例子
2019/11/18 Python
通过实例解析Python return运行原理
2020/03/04 Python
python3.6环境下安装freetype库和基本使用方法(推荐)
2020/05/10 Python
CSS3实现div从下往上滑入滑出效果示例
2020/04/28 HTML / CSS
GAP美国官网:美国休闲时尚品牌
2016/08/26 全球购物
COSETTE官网:奢华,每天
2020/03/22 全球购物
外企C语言笔试题
2013/11/10 面试题
团日活动总结范文
2014/04/25 职场文书
解除劳动合同协议书范本
2014/09/13 职场文书
2014年社区居委会主任重阳节讲话稿
2014/09/25 职场文书
2014年酒店前台工作总结
2014/11/14 职场文书
学校教学管理制度
2015/08/06 职场文书
班主任工作经验交流会总结
2015/11/02 职场文书
2016廉洁教育心得体会
2016/01/20 职场文书
nginx+lua单机上万并发的实现
2021/05/31 Servers