您的位置:首页 > 汽车 > 新车 > OpenCV仿射变换和透视变换函数(C++)

OpenCV仿射变换和透视变换函数(C++)

2024/9/18 5:43:43 来源:https://blog.csdn.net/qq_44924694/article/details/132354584  浏览:    关键词:OpenCV仿射变换和透视变换函数(C++)

文章目录

    • 引言
    • 图像仿射变换 warpAffine()
      • 图像的旋转
      • 仿射变换
    • 透视变换 warpPerspective()
    • 透视变换例子
    • 参考文献

**仿射变换相关函数**
cv::transform():对一组点进行仿射变换
cv::warpAffine():对整幅图像进行仿射变换
cv::getAffineTransform():从一组点计算仿射变换矩阵
cv::getRotationMatrix2D():计算旋转矩阵
**投影变换相关的函数**
cv::perspectiveTransform():对一组点进行透射变换/投影变换
cv::warpPerspective():对整幅图像进行透视变换/投影变换
cv::getPerspectiveTransform():获取透视变换/投影变换矩阵
cv::findHomography():计算单应性矩阵

引言

图像的几何变换通常包括拉伸、缩放、扭曲和旋转等操作。

对于平面区域来说,分为两类几何转换:

  • 仿射变换(affine transform),基于2x3矩阵进行变换。指图像可以通过一系列的几何变换来实现平移、旋转等多种操作。该变换能够保持图像的平直性和平行性。平直性是指图像经过仿射变换后,直线仍然是直线;平行性是指图像在完成仿射变换后,平行线仍然是平行线
  • 透视变换(perspective transform),基于3x3矩阵进行变换。透视变换将视锥体转换为长方体形状,视锥体的近端比远端小,具有扩大相机附近物体的效果。透视变换可以改变平行关系,将矩形映射为任意四边形。

图像仿射变换 warpAffine()

图像的旋转

getRotationMatrix2D()函数通过输入旋转中心、旋转角度、旋转过程两轴的比例因子,获得一个Mat类型的旋转矩阵对象:

Mat cv::getRotationMatrix2D(Point2f center,double angle,double scale   //两轴的比例因子,输入1则不缩放)    

旋转变换是仿射变换的一个特殊情况,将此矩阵用于仿射变换函数即可仅作图像旋转

仿射变换

仿射变换又称为三点变换。如果知道目标变换前后的三个像素点坐标之间的关系,即可求出仿射变换矩阵M。

opencv提供了getAffineTransform函数用于计算仿射变换矩阵:

//只需要提供原图像和目标图像的三个点的坐标
Mat cv::getAffineTransform(const Point2f src[],const Point2f dst[]   //输入点类数组)
void cv::warpAffine(InputArray src,OutputArray dst,InputArray M,        //仿射变换矩阵MSize dsize,int flags = INTER_LINEAR,    //插值方法int borderMode = BORDER_CONSTANT,    //像素边界外推方法const Scalar & nprderValue = Scalar())

注:仿射变换的矩阵M是2×3的矩阵

透视变换 warpPerspective()

透视变换:按照物体的成像投影规律将图像重新投影。常见用例是修正镜头与拍摄目标存在斜角时产生的图像畸变。
在这里插入图片描述

使用getPerspectiveTransform()函数获取变换矩阵

//只需要提供原图像和目标图像的四个点的坐标
Mat cv::getPerspectiveTransform(const Point2f src[],const Point2f dst[],int solveMethod = DECOMP_LU //求解方法                             )

在不知道四个坐标点的情况下,可以使用原图和目标图的匹配点计算变换矩阵:

Mat cv::findHomography	(	InputArray 	srcPoints,InputArray 	dstPoints,int 	method = 0,double 	ransacReprojThreshold = 3,OutputArray 	mask = noArray(),const int 	maxIters = 2000,const double 	confidence = 0.995 
)

method参数详解:

method	计算单应矩阵所使用的方法。不同的方法对应不同的参数,具体如下:
0 - 利用所有点的常规方法
RANSAC - RANSAC-基于RANSAC的鲁棒算法
LMEDS - 最小中值鲁棒算法
RHO - PROSAC-基于PROSAC的鲁棒算法

使用warpPerspective()函数应用透视变换

void cv::warpPerspective(InputArray src,OutputArray dst,InputArray M,        //变换矩阵MSize dsize,int flags = INTER_LINEAR,    //插值方法int borderMode = BORDER_CONSTANT,    //像素边界外推方法const Scalar & nprderValue = Scalar())

注:透视变换的矩阵M是3×3的矩阵

透视变换例子

#include<opencv2/opencv.hpp>
using namespace cv;
using namespace std;struct callbackP
{Mat src;int clickTimes = 0;        //在图像上单击次数vector<Point2f> srcTri;
};void onMouse(int event, int x, int y, int flags, void *utsc)
{callbackP cp = *(callbackP*)utsc;  // 先转换类型,再取数据if (event == EVENT_LBUTTONUP)      //响应鼠标左键事件{circle((*(callbackP*)utsc).src, Point(x, y), 2, Scalar(0, 0, 255), 2);  //标记选中点imshow("wait ", (*(callbackP*)utsc).src);(*(callbackP*)utsc).srcTri.push_back(Point2f(x, y));cout << "x:" << x << " " << "y:" << y << endl;(*(callbackP*)utsc).clickTimes++;if ((*(callbackP*)utsc).clickTimes == 4){cout << "按任意键继续!" << endl;}}
}int main(int argc, char *argv[])
{vector<Point2f> dstTri(4);Mat dst;callbackP utsc;utsc.src = imread("tt.jpg");namedWindow("src", WINDOW_AUTOSIZE);imshow("src", utsc.src);cout << "从需要透视变换区域的左上角开始,顺时针依次点矩形的四个角!" << endl;setMouseCallback("src", onMouse, (void*)&utsc);  //类型转换waitKey();if (utsc.clickTimes == 4){dstTri[0].x = 0;dstTri[0].y = 0;dstTri[1].x = utsc.srcTri[1].x - utsc.srcTri[0].x;dstTri[1].y = 0;dstTri[2].x = utsc.srcTri[1].x - utsc.srcTri[0].x;dstTri[2].y = utsc.srcTri[2].y - utsc.srcTri[1].y;dstTri[3].x = 0;dstTri[3].y = utsc.srcTri[2].y - utsc.srcTri[1].y;//计算透视矩阵Mat M = findHomography(utsc.srcTri, dstTri, RANSAC);//图像透视变换warpPerspective(utsc.src, dst, M, Size((utsc.srcTri[1].x - utsc.srcTri[0].x), (utsc.srcTri[2].y - utsc.srcTri[1].y)));imshow("output", dst);imwrite("3p.jpg", dst);cout << "透视变换矩阵:" << M << endl;waitKey();}else{cout << "需要从左上角开始,顺时针依次点矩形的四个角!" << endl;cout << "现在点击了" << utsc.clickTimes << "次" << endl;}在这里插入图片描述cv::destroyAllWindows();return 0;
}

在这里插入图片描述

参考文献

图像几何变换(仿射变换和透视变换…)及python-opencv实现
OpenCV学习笔记 02
opencv的单应性矩阵

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com