透视变换原理以及C++/opencv实现

部分转载自知乎透视变换 - 知乎 (zhihu.com)

1.什么是透视变换

透视变换通过投影的方式,把当前图像映射到另外一个平面,就像投影仪一样,如果幕布或者胶带其中任意一个与放映机发出的光纤不是垂直90度角的,那么投影到幕布上的图像就会发生畸变。这种畸变就是透视畸变的一种。

透视变换对畸变图像的校正需要取得畸变图像的 一组4个点的坐标, 和 目标图像的一组4个点的坐标, 通过两组坐标点可以计算出透视变换的变换矩阵,之后对整个原始图像执行变换矩阵的变换,就可以实现图像校正。

2.透视变换的数学原理

透视变换(Perspective Transformation)的本质是将图像投影到一个新的视平面,其通用变换公式如下:

透视变换原理以及C++/opencv实现_第1张图片

透视变换原理以及C++/opencv实现_第2张图片

 透视变换原理以及C++/opencv实现_第3张图片

 

也就是说:给定透视变换对应的四对像素点坐标,即可求得透视变换矩阵;反之,给定透视变换矩阵,即可对图像或像素点坐标完成透视变换

3.透视变换的代码实现(C++/OpenCv)

OpenCV提供了warpPerspective( )函数来实现图片的透视变换,只需要输入梯形四个顶点的坐标和目标画布四个角的坐标,即可自动完成转换。核心代码只有两行:首先读取两个坐标数组,计算变换矩阵;然后根据变换矩阵对原图进行透视变换,并输出到目标画布。

cv2.getPerspectiveTransform(src, dst) → retval
  • src:源图像中待测矩形的四点坐标
  • sdt:目标图像中矩形的四点坐标

原图像的四个坐标顺序应与目标图像中的四个坐标一 一随影,若都是顺时针则都是顺时针,若都是 Z 字型,则都是 Z 字型。

返回由源图像中矩形到目标图像矩形变换的矩阵,得到矩阵得有用才行啊,所以引出下面这个函数

cv2.warpPerspective(src, M, dsize[, dst[, flags[, borderMode[, borderValue]]]]) → dst
  • src:输入图像
  • M:变换矩阵
  • dsize:目标图像shape
  • flags:插值方式,interpolation方法INTER_LINEAR或INTER_NEAREST
  • borderMode:边界补偿方式,BORDER_CONSTANT or BORDER_REPLICATE
  • borderValue:边界补偿大小,常值,默认为0
#include 
#include 
#include 
#include 

using namespace cv;
using namespace std;

int main()
{
	    Mat srcImage = imread("C:\\Users\\LY\\Desktop\\FringeImage_2022-11-19-20-46\\2.bmp");//"C:\Users\LY\Desktop\FringeImage_2022-11-19-20-46\1.bmp"
	    // 目标图像
	    Mat dstImage;
	    // 取原图四个顶点up
	    //Point2f AffinePointsSrc[4] = { Point2f(729.4169,577.4854), Point2f(1341.8,608.1793),Point2f(724.1677,1108.8),  Point2f(1340.7,1101.7) };
		//down
		Point2f AffinePointsSrc[4] = { Point2f(661.3996,770.9839), Point2f(1290.1,790.8698),Point2f(662.8568, 1311.7),  Point2f(1285.3, 1290.6) };
		//up
	    //Point2f AffinePointsDst[4] = { Point2f(923.902,612.663), Point2f(1567.42,635.797),Point2f(931.644,1188.41),  Point2f(1571.4,1162.16) };
	    //down
		Point2f AffinePointsDst[4] = { Point2f(923.435,609.981), Point2f(1567.35,632.982),Point2f(932.406,1185.72),  Point2f(1571.48,1159.49) };
		// 求出透视变换矩阵
	    Mat TransImage = getPerspectiveTransform(AffinePointsSrc, AffinePointsDst);
	    warpPerspective(srcImage, dstImage, TransImage, Size(srcImage.cols, srcImage.rows), INTER_CUBIC);
	    // 目标图像上的四个点上标记圆形
	    for (int i = 0; i < 4; i++)
	    {
	        circle(dstImage, AffinePointsDst[i], 2, Scalar(0, 0, 255), 2);
	    }
	    imshow("src", srcImage);
	    imshow("dst", dstImage);
		imwrite("C:\\Users\\LY\\Desktop\\dst_down2.bmp",dstImage);
	    waitKey();
}



 

你可能感兴趣的:(opencv,人工智能)