OpenCV图像几何变换专题(缩放、翻转、仿射变换及透视)(python为工具) 【Open_CV系列(五)】
ʚʕ̯•͡˔•̯᷅ʔɞ 🍹欢迎各路大佬来到小啾主页指点☀️欢迎大家前来学习OpenCV图像几何变换专题 – Open_CV系列博文第五篇,我是侯小啾。 本期blog可以作为日常复制的脚手架代码来运用。 ✨博客主页:云雀编程小窝 🌹꧔ꦿ 🌹꧔ꦿ博文内容如对您有所帮助,还请给个点赞 + 关注 + 收藏✨
如有疑问欢迎随时在评论区交流。☀️
选择一张shape为(500,500,3)的梵高的《星月夜》以便示例。
cv2.resize(src, dsize, dst=None, fx=None, fy=None, interpolation=None)
fx和fy不同于dsize,fx和fy是各是一个比值,如设为2,则表示放大2倍,设为1/2则表示缩小到原来的 1 2 \displaystyle \frac{1}{2} 21。
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()
执行结果如图所示,相比原图,图像得到了指定大小的缩小与放大。
使用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()
结果呈现:
flip(src, flipCode, dst=None)
讲原图经过着三种翻转后,与原图拼在一块,呈现出了这种奇观:
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()
将翻转结果放在同一张画布中
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)
结果呈现:
常见的仿射变换有平移,旋转和倾斜变换。 仿射变换使用cv2.warpAffine()方法完成
warpAffine(src, M, dsize, dst=None, flags=None, borderMode=None, borderValue=None)
这三个参数是常用的参数。其余参数建议使用默认值。 flags表示插入方式,borderMode是边界类型,borderValue表示边界值(默认0)。dst表示反射变换后输出的图像。
以将《星月夜》向左平移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()
如图所示,图像按照我们的预期成功被平移。 只是这样得到的图像有色素损失,我们丢失了超出画布之外的数据。 为了避免损失,可以取设置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()
优化后的程序执行效果:
旋转也是通过M矩阵来实现的,这个矩阵的运算较复杂, OpenCV提供了getRotationMatrix2D()方法来计算旋转操作的M矩阵
getRotationMatrix2D(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需要定位到图像的三个点的位置来计算倾斜效果,即左上角,右上角和左下角。 图像的倾斜也是根据M矩阵实现,得出矩阵的运算较复杂,通过getAffineTransform 方法实现。
语法
getAffineTransform(src, 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()
程序执行效果如下:
透视的实现使用的是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()
展示原图和透视后的图像效果:
🌹꧔ꦿ本系列blog传送门: ✨OpenCV图像处理基本操作 【Python-Open_CV系列(一)】 ✨OpenCV像素处理基本操作 【Python-Open_CV系列(二)】 ✨OpenCV之 BGR、GRAY、HSV色彩空间&色彩通道专题 【Python-Open_CV系列(三)】 ✨OpenCV绘制图像与文字(可作为脚手架代码)(python) 【Python-Open_CV系列(四)】 ✨OpenCV图像几何变换专题(缩放、翻转、仿射变换及透视)【python-Open_CV系列(五)】 ✨基于梵·高《向日葵》的 图像阈值处理专题(二值处理、反二值处理、截断处理、自适应处理及Otsu方法)【Python-Open_CV系列(六)】 ✨OpenCV基本功 之 图像的掩模、运算 & 合并专题 -小啾带学【Python-Open_CV系列(七)】 ✨《三英战吕布》 – 图像模板匹配 【Python-Open_CV系列(八)】 ✨OpenCV滤波器 龙门石窟篇【Python-Open_CV系列(九)】(均值滤波器、中值滤波器、高斯滤波器、双边滤波器) ✨Open_CV形态学运算专题 (腐蚀&膨胀、开&闭运算、梯度运算、顶帽运算黑帽运算 )【Python-Open_CV系列(十)】 ✨霍夫变换看不懂?小啾带你串一遍:OpenCV图形检测专题 这样学最简单【Python-Open_CV系列(十一)】 ✨小啾带你开天眼 之 开启py-OpenCV摄像头及视频处理【Python-Open_CV系列(十二)】 ✨小啾带你开天眼 之 人脸检测与识别(以及华强、皇叔、高祖配墨镜特效)【Python-Open_CV系列(十三)】
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。