opencv学习笔记三十四:透视变换
程序员文章站
2023-12-27 09:02:57
...
透视变换(Perspective Transformation)是将图片投影到一个新的视平面(Viewing Plane),也称作投影映射(Projective Mapping)。通用的变换公式为:
u,v是原始图片左边,对应得到变换后的图片坐标x,y,其中。
变换矩阵可以拆成4部分,表示线性变换,比如scaling,shearing和ratotion。用于平移,产生透视变换。所以可以理解成仿射等是透视变换的特殊形式。经过透视变换之后的图片通常不是平行四边形(除非映射视平面和原来平面平行的情况)。
简单的看一个正方形到四边形的变换:
变换的4组对应点可以表示成:
根据变换公式得到:
定义几个辅助变量:
都为0时变换平面与原来是平行的,可以得到:
不为0时,得到:
求解出的变换矩阵就可以将一个正方形变换到四边形。反之,四边形变换到正方形也是一样的。于是,我们通过两次变换:四边形变换到正方形+正方形变换到四边形就可以将任意一个四边形变换到另一个四边形。
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);
}
}
参考文献:https://blog.csdn.net/xiaowei_cqu/article/details/26471527