欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

opencv学习笔记三十四:透视变换

程序员文章站 2023-12-27 09:02:57
...

透视变换(Perspective Transformation)是将图片投影到一个新的视平面(Viewing Plane),也称作投影映射(Projective Mapping)。通用的变换公式为:

opencv学习笔记三十四:透视变换

u,v是原始图片左边,对应得到变换后的图片坐标x,y,其中opencv学习笔记三十四:透视变换
变换矩阵opencv学习笔记三十四:透视变换可以拆成4部分,opencv学习笔记三十四:透视变换表示线性变换,比如scaling,shearing和ratotion。opencv学习笔记三十四:透视变换用于平移,opencv学习笔记三十四:透视变换产生透视变换。所以可以理解成仿射等是透视变换的特殊形式。经过透视变换之后的图片通常不是平行四边形(除非映射视平面和原来平面平行的情况)。

简单的看一个正方形到四边形的变换:
变换的4组对应点可以表示成:opencv学习笔记三十四:透视变换

根据变换公式得到:

opencv学习笔记三十四:透视变换

定义几个辅助变量:

opencv学习笔记三十四:透视变换

opencv学习笔记三十四:透视变换都为0时变换平面与原来是平行的,可以得到:

opencv学习笔记三十四:透视变换

opencv学习笔记三十四:透视变换不为0时,得到:

opencv学习笔记三十四:透视变换

求解出的变换矩阵就可以将一个正方形变换到四边形。反之,四边形变换到正方形也是一样的。于是,我们通过两次变换:四边形变换到正方形+正方形变换到四边形就可以将任意一个四边形变换到另一个四边形。

opencv学习笔记三十四:透视变换

 opencv中相关API函数:

计算透视矩阵(通过输入和输出图像中两组点计算透视矩阵):

findHomography( InputArray srcPoints, InputArray dstPoints,
                               OutputArray mask, int method = 0, double ransacReprojThreshold = 3 );

 

 图像的透视变换(利用透视矩阵对图像进行透视变换):

warpPerspective( InputArray src, OutputArray dst,
                                   InputArray M, Size dsize,
                                   int flags = INTER_LINEAR,
                                   int borderMode = BORDER_CONSTANT,
                                   const Scalar& borderValue = Scalar());

 点的透视变换(利用透视矩阵对点进行透视变换):

perspectiveTransform(InputArray src, OutputArray dst, InputArray m );

鼠标回调函数:

setMouseCallback(const String& winname, MouseCallback onMouse, void* userdata = 0);

 CV_EVENT_LBUTTONUP  (鼠标左键响应事件)
 CV_EVENT_RBUTTONUP (鼠标右键响应事件)

#include<opencv2\opencv.hpp>
#include<opencv2\xfeatures2d.hpp>
using namespace cv;
using namespace xfeatures2d;
using namespace std
;
vector<Point2f> srcTri(4);
vector<Point2f> dstTri(4);
int clickTimes = 0;  //在图像上单击次数
Mat src,dst;
Mat imageWarp;
void onMouse(int event, int x, int y, int flags, void *utsc);

	int main(int argc, char *argv[])
	{
		src = imread("2.jpg");
		namedWindow("src", CV_WINDOW_AUTOSIZE);
		imshow("src", src);	
		setMouseCallback("src", onMouse);
		waitKey();
		return 0;
	}
	void onMouse(int event, int x, int y, int flags, void *utsc)
	{
		if (event == CV_EVENT_LBUTTONUP)   //响应鼠标左键事件
		{
			circle(src, Point(x, y), 2, Scalar(0, 0, 255), 2);  //标记选中点
			imshow("wait ", src);
			srcTri[clickTimes].x = x;
			srcTri[clickTimes].y = y;
			clickTimes++;
		}
		if (clickTimes == 4)
		{
			dstTri[0].x = 0;
			dstTri[0].y = 0;	
			dstTri[1].x = 282;
			dstTri[1].y = 0;
			dstTri[2].x = 282 ;
			dstTri[2].y = 438;
			dstTri[3].x = 0;
			dstTri[3].y = 438;
					
			Mat H = findHomography(srcTri, dstTri, RANSAC);//计算透视矩阵
			warpPerspective(src, dst, H, Size(282, 438));//图像透视变换
			imshow("output", dst);
		}
	}

opencv学习笔记三十四:透视变换

 

参考文献:https://blog.csdn.net/xiaowei_cqu/article/details/26471527

相关标签: 透视变换

上一篇:

下一篇: