|
利用OpenCV的函数warpPerspective()作图像的透视变换
图像的透视变换是指按照物体的成像投影规律进行变换。通过透视变换可以将图像投影到新的成像平面上。
图像的透视变换通常用来解决相机的视线与物体所在平面不垂直的问题。
比如,下面这幅图中,如果相机的视线与正方形是垂直的,那么应该是下面这样的成像效果:
但我们相机的视线很多时候与要拍摄的物体平面不垂直,比如下面示意图中的相机与物体平面:
当相机的视线与要拍摄的物体平面不垂直时,就照成了下面这样:
我们可以利用透视变换对上面的图像进行校正操作。
在OpenCV开发环境下,我们可以利用函数warpPerspective()作图像的透视变换。
利用函数warpPerspective()作图像的透视变换前需要有一个3×3的透视变换矩阵,可以利用函数getPerspectiveTransform()得到3×3的透视变换矩阵。
函数getPerspectiveTransform()的原型如下:
- Mat cv::getPerspectiveTransform(const Point2f src[],
- const Point2f dst[],
- int solveMethod = DECOMP_LU )
复制代码- retval=cv.getPerspectiveTransform(src, dst[, solveMethod])
复制代码
参数意义如下:
src—原图像中4个像素点的坐标,注意坐标值的数据类型为float。
dst—目标图像中4个像素点的坐标,注意坐标值的数据类型为float。
solveMethod—选择计算透视变换矩阵的方法,默认值为DECOMP_LU,其枚举值有如下这些:
DECOMP_LU:最佳主轴元素的高斯消元法。
DECOMP_SVD :奇异值分解(SVD)方法。
DECOMP_EIG :特征值分解法。
DECOMP_CHOLESKY :Cholesky分解法。
DECOMP_QR :QR分解法。
DECOMP_NORMAL :使用归一化公式,可以与前面的标志一起使用。
函数warpPerspective()的原型如下:
- void cv::warpPerspective(InputArray src,
- OutputArray dst,
- InputArray M,
- Size dsize,
- int flags = INTER_LINEAR,
- int borderMode = BORDER_CONSTANT,
- const Scalar & borderValue = Scalar() )
复制代码- dst=cv.warpPerspective(src, M, dsize[, dst[, flags[, borderMode[, borderValue]]]])
复制代码
参数意义如下:
src—输入图像。
M—尺寸为2×3的仿射变换矩阵。
dsize—输出图像的尺寸。
dst—仿射变换后的图像,与输入图像的数据类型相同,但是尺寸由参数dsize指定。
flags—插值方法和正反变换的标志位。
borderMode—像素边界外推方法的标志,详情见博文 https://www.hhai.cc/thread-178-1-1.html
borderValue—边界填充时的填充值,默认情况下为0。
Python示例代码如下:
代码中用到的图像下载链接:
https://pan.baidu.com/s/1ss1U5_0XbbEuXXFcTgGMUA?pwd=rlj2
[Python] 纯文本查看 复制代码 # -*- coding: utf-8 -*-
# 出处:昊虹AI笔记网(hhai.cc)
# 用心记录计算机视觉和AI技术
# 博主微信/QQ 2487872782
# QQ群 271891601
# 欢迎技术交流与咨询
# OpenCV的版本为4.4.0
import cv2 as cv
import numpy as np
import sys
if __name__ == '__main__':
# 读取图像并判断是否读取成功
img = cv.imread('F:/material/images/2022/2022-12/perspective_img2.png')
if img is None:
print('Failed to read noobcvqr.png.')
sys.exit()
h, w = img.shape[:-1]
size = (w, h)
# 透视变换前的四个角点坐标
src_points = np.array([[65, 70], [198, 67], [50, 164], [205, 163]], dtype='float32')
# 设置透视变换后四个角点坐标
max_pt = np.max(src_points)
dst_points = np.array([[50, 50], [180, 50], [50, 180], [180, 180]], dtype='float32')
# 计算透视变换矩阵
rotation = cv.getPerspectiveTransform(src_points, dst_points)
# 透视变换投影
img_warp = cv.warpPerspective(img, rotation, size)
# 展示结果
cv.imshow('src_img', img)
cv.imshow('perspective_img', img_warp)
cv.waitKey(0)
cv.destroyAllWindows()
代码说明:
透视变换前的四个点选取的就是图中正方形框的四个角点。
透视变换后的四个点的坐标就根据自己的需要自己设定了,不过也不是随便设定,比如在上面的代码中,我希望透视变换后的正方形是真正的正方形,那么四个点的坐标连接起来显然应该是一个是正方形。
运行结果如下图所示:
C++代码暂略,需要C++的朋友可以联系昊虹君,昊虹君可以把上面的代码改为C++代码。 |
|