当前位置:   article > 正文

OpenCV 透视变换 & 图像拼接_cv::getperspectivetransform

cv::getperspectivetransform

 A:OpenCV 透视变换

一:OpenCV透视变换的概念

仿射变换(affine transform)与透视变换(perspective transform)在图像还原、图像局部变化处理方面有重要意义。通常,在2D平面中,仿射变换的应用较多,而在3D平面中,透视变换又有了自己的一席之地。两种变换原理相似,结果也类似,可针对不同的场合使用适当的变换。

仿射变换和透视变换的数学原理不需深究,在应用层面,仿射变换是图像基于3个固定顶点的变换,如下图所示:

二:透视变换工作原理

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

(u,v)为原始图像像素坐标,(x=x’/w’,y=y’/w’)为变换之后的图像像素坐标。透视变换矩阵图解如下:

透视变换工作原理

仿射变换(Affine Transformation)可以理解为透视变换的特殊形式。透视变换的数学表达式为:

所以,给定透视变换对应的四对像素点坐标,即可求得透视变换矩阵;反之,给定透视变换矩阵,即可对图像或像素点坐标完成透视变换,如下图所示:

三:findHomography函数

这里重点分析findHomography函数参数和使用方法

findHomography: 计算多个二维点对之间的最优单映射变换矩阵 H(3行x3列) ,使用最小均方误差或者RANSAC方法。函数功能:找到两个平面之间的变换矩阵。

  1. Mat cv::findHomography ( InputArray srcPoints,
  2. InputArray dstPoints,
  3. int method = 0,
  4. double ransacReprojThreshold = 3,
  5. OutputArray mask = noArray(),
  6. const int maxIters = 2000,
  7. const double confidence = 0.995
  8. )

四:warpPerspective函数

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

warpPerspective参数说明:

1.src – 输入图像
2.dst – 大小为dsize且类型与src相同的输出图像
3.M – 3×3变换矩阵
4.dsize – 输出图像的大小

图中红点即为固定顶点,在变换先后固定顶点的像素值不变,图像整体则根据变换规则进行变换

同理,透视变换是图像基于4个固定顶点的变换,如图所示:

五:透视变换案例

这个例子中通过鼠标点击图片进行区域读取

六:getPerspectiveTransform函数

C++方式一:Mat getPerspectiveTransform(InputArray src, InputArray dst)

C++方式二:Mat getPerspectiveTransform(const Point2f src[], const Point2f dst[])

getPerspectiveTransform参数说明:

    src – 源图像中四边形顶点的坐标

    dst – 目标图像中相应四边形顶点的坐标。

该函数计算透视变换的3乘3矩阵,以便实现以下计算:

代码示例:

  1. int main( )
  2. {
  3. Point2f srcTri[4];
  4. Point2f dstTri[4];
  5. Mat warpPerspective_mat( 3, 3, CV_32FC1 );
  6. Mat src, warpPerspective_dst;
  7. /// Load the image
  8. src = imread( "lena.bmp", IMREAD_COLOR );
  9. /// Set the dst image the same type and size as src
  10. warpPerspective_dst = Mat::zeros( src.rows, src.cols, src.type() );
  11. /// 设置三组点,求出变换矩阵
  12. srcTri[0] = Point2f( 0,0 );
  13. srcTri[1] = Point2f( src.cols - 1,0 );
  14. srcTri[2] = Point2f( 0,src.rows - 1);
  15. srcTri[3] = Point2f(src.cols - 1,src.rows - 1);
  16. dstTri[0] = Point2f( 0,src.rows*0.13 );
  17. dstTri[1] = Point2f( src.cols*0.9,0 );
  18. dstTri[2] = Point2f( src.cols*0.2,src.rows*0.7 );
  19. dstTri[3] = Point2f( src.cols*0.8,src.rows );
  20. //计算3个二维点对之间的仿射变换矩阵(2行x3列)
  21. warpPerspective_mat = getPerspectiveTransform( srcTri, dstTri );
  22. //应用仿射变换,可以恢复出原图
  23. warpPerspective( src, warpPerspective_dst, warpPerspective_mat, src.size() );
  24. //显示结果
  25. namedWindow( source_window, WINDOW_AUTOSIZE );
  26. imshow( source_window, src );
  27. namedWindow( warpPerspective_window, WINDOW_AUTOSIZE );
  28. imshow( warpPerspective_window, warpPerspective_dst );
  29. /// 等待,直到用户退出
  30. waitKey(0);
  31. return 0;
  32. }

B:OpenCV 图像拼接

一:OpenCV图像特征采集

特征提取:

  一幅图中总存在着一些独特的像素点,这些点我们可以认为就是这幅图的特征,成为特征点。

计算机视觉领域特征提取:

获取一幅图中存在着一些独特的像素点。

解决两个问题:

      1、提取图片中的特征点

      2、解决尺度不变性问题,不同大小的图片获取到的特征是一样的。

      3、提取到的特征点要稳定,能被精确定位。

 

二:特征提取算法

三:特征提取

提取到的特征很粗糙,不是很精确的特征点,导致效果很差。

去粗取精,获取优秀的匹配点。

四:特征取精

取一幅图像中的一个SIFT关键点,并找出其与另一幅图像中欧式距离最近的前两个关键点,在这两个关键点中,如果最近的距离除以次近的距离得到的比率ratio少于某个阈值T,则接受这一对匹配点。

五:OpenCV透视转换

透视变换是按照物体成像投影规律进行变换,即将物体重新投影到新的成像平面。透视变换常用于机器人视觉导航研究中,由于相机视场与地面存在倾斜角使得物体成像产生畸变,通常通过透视变换实现对物体图像的校正。

六:透视矩阵

[u,v,w] 表示当前平面坐标的x,y,z,如果是平面,那么z=1。

[x',y',z'] 表示目标平面坐标的x,y,z,如果是平面,那么z=1。

通过以上公式,我们可以将透视矩阵理解为:透视矩阵是原始平面可目标平面之间的一种转换关系。

七:获取特征矩阵

根据图像的4个顶点来获取特征矩阵

  1. cv::Mat cv::getPerspectiveTransform( // 返回3x3透视变换矩阵
  2. const cv::Point2f* src, // 源图像四个顶点坐标(点数组)
  3. const cv::Point2f* dst // 目标图像上四个顶点的坐标(点数组)
  4. );

函数来计算透视矩阵H(3*3)

  1. findHomography    (   
  2. InputArray     srcPoints,//源平面中点的坐标矩阵.vector<Point2f>类型
  3. InputArray     dstPoints,//目标平面中点的坐标矩阵,vector<Point2f>类型
  4. int     method = 0,
  5. double     ransacReprojThreshold = 3,
  6. OutputArray     mask = noArray(),
  7. const int     maxIters = 2000,
  8. const double     confidence = 0.995
  9. )

使用cv::warpPerspective()进行透视变换

  1. void cv::warpPerspective(
  2. cv::InputArray src, // 输入图像
  3. cv::OutputArray dst, // 输出图像
  4. cv::InputArray M, // 3x3 变换矩阵
  5. cv::Size dsize, // 目标图像大小
  6. int flags = cv::INTER_LINEAR, // 插值方法
  7. int borderMode = cv::BORDER_CONSTANT, // 外推方法
  8. const cv::Scalar& borderValue = cv::Scalar() //常量边界时使用
  9. );

八:图像拷贝

图像拷贝:将一副图像拷贝到另一副图像上的过程:

九:图片拼接流程思想 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/153462
推荐阅读
相关标签
  

闽ICP备14008679号