Opencv中Homography

转自 https://blog.csdn.net/datase/article/details/78420251

  1. 什么是Homography
    在图1中有两张书的平面图,两张图分别有四个相对位置相同的点,Homography就是一个变换(3*3矩阵),将一张图中的点映射到另一张图中对应的点
    这里写图片描述

因为Homography是一个3*3矩阵,所以可以写成

两张图间的H映射关系就可以表示成
这里写图片描述

Homography应用:图像对齐

上面公式得出的H ,对于图一中的所有点都是正确的,换句话说,可以用H将第一个图中的点映射到第二张图。

如何得到一个Homography

要得到两张图片的H,就必须至少知道4个相同对应位置的点,opencv中可以利用findHomography正确得到


  
  
  1. // pts_src and pts_dst are vectors of points in source
  2. // and destination images. They are of type vector<Point2f>.
  3. // We need at least 4 corresponding points.
  4. Mat h = findHomography(pts_src, pts_dst);
  5. // The calculated homography can be used to warp
  6. // the source image to destination. im_src and im_dst are
  7. // of type Mat. Size is the size (width,height) of im_dst.
  8. warpPerspective(im_src, im_dst, h, size);
  • OpenCV C++ Homography的一个简单例子:

    
        
        
    1. #include "opencv2/opencv.hpp"
    2. using namespace cv;
    3. using namespace std;
    4. int main( int argc, char ** argv)
    5. {
    6. // Read source image.
    7. Mat im_src = imread( "book2.jpg");
    8. // Four corners of the book in source image
    9. vector<Point2f> pts_src;
    10. pts_src.push_back(Point2f( 141, 131));
    11. pts_src.push_back(Point2f( 480, 159));
    12. pts_src.push_back(Point2f( 493, 630));
    13. pts_src.push_back(Point2f( 64, 601));
    14. // Read destination image.
    15. Mat im_dst = imread( "book1.jpg");
    16. // Four corners of the book in destination image.
    17. vector<Point2f> pts_dst;
    18. pts_dst.push_back(Point2f( 318, 256));
    19. pts_dst.push_back(Point2f( 534, 372));
    20. pts_dst.push_back(Point2f( 316, 670));
    21. pts_dst.push_back(Point2f( 73, 473));
    22. // Calculate Homography
    23. Mat h = findHomography(pts_src, pts_dst);
    24. // Output image
    25. Mat im_out;
    26. // Warp source image to destination based on homography
    27. warpPerspective(im_src, im_out, h, im_dst.size());
    28. // Display images
    29. imshow( "Source Image", im_src);
    30. imshow( "Destination Image", im_dst);
    31. imshow( "Warped Source Image", im_out);
    32. waitKey( 0);
    33. }
    • 41

    Homography应用:图像矫正

    假设你有一张如下所示的图片
    这里写图片描述

    你想点击图中书的四个顶点,然后得到正放的书:
    这里写图片描述

    该如何做?
    利用Homography可以做到这点。
    1.首先获取书本四个顶点的坐标 pts_src
    2.然后我们需要知道书本的宽高比,此书的宽高比是3/4,所以可使输出图像的size 为300*400,就可设其四个点的坐标为(0,0),(299,0),(299,399),(0,399)保存在pts_dst中
    3.通过pts_src和pts_dst 获取homography
    4.对原图应用homography 得到输出

    
        
        
    1. #include <opencv2/opencv.hpp>
    2. using namespace cv;
    3. using namespace std;
    4. struct userdata{
    5. Mat im;
    6. vector<Point2f> points;
    7. };
    8. void mouseHandler( int event, int x, int y, int flags, void * data_ptr)
    9. {
    10. if ( event == EVENT_LBUTTONDOWN )
    11. {
    12. userdata *data = ((userdata *) data_ptr);
    13. circle(data->im, Point(x,y), 3,Scalar( 0, 0, 255), 5, CV_AA);
    14. imshow( "Image", data->im);
    15. if (data->points.size() < 4)
    16. {
    17. data->points.push_back(Point2f(x,y));
    18. }
    19. }
    20. }
    21. void main()
    22. {
    23. // Read source image.
    24. Mat im_src = imread( "book1.jpg");
    25. // Destination image. The aspect ratio of the book is 3/4
    26. Size size( 300 , 400 );
    27. Mat im_dst = Mat::zeros(size,CV_8UC3);
    28. // Create a vector of destination points.
    29. vector<Point2f> pts_dst;
    30. pts_dst.push_back(Point2f( 0, 0));
    31. pts_dst.push_back(Point2f(size.width - 1, 0));
    32. pts_dst.push_back(Point2f(size.width - 1, size.height - 1));
    33. pts_dst.push_back(Point2f( 0, size.height - 1 ));
    34. // Set data for mouse event
    35. Mat im_temp = im_src.clone();
    36. userdata data;
    37. data.im = im_temp;
    38. cout << "Click on the four corners of the book -- top left first and" << endl
    39. << "bottom left last -- and then hit ENTER" << endl;
    40. // Show image and wait for 4 clicks.
    41. imshow( "Image", im_temp);
    42. // Set the callback function for any mouse event
    43. setMouseCallback( "Image", mouseHandler, &data);
    44. waitKey( 0);
    45. // Calculate the homography
    46. Mat h = findHomography(data.points, pts_dst);
    47. // Warp source image to destination
    48. warpPerspective(im_src, im_dst, h, size);
    49. // Show image
    50. imshow( "Image", im_dst);
    51. waitKey( 0);
    52. }

    Homography应用:虚拟广告牌

    在足球或者棒球体育直播中,经常可以看到球场旁边有虚拟广告,并且还会根据地区,国家的不同播放不同的广告,这是如何做到的?
    看完此篇博客,你应该就能知道如何实现了。原理跟前一个差不多,这里直接上代码

    
        
        
    1. #include <opencv2/opencv.hpp>
    2. using namespace cv;
    3. using namespace std;
    4. struct userdata{
    5. Mat im;
    6. vector<Point2f> points;
    7. };
    8. void mouseHandler( int event, int x, int y, int flags, void * data_ptr)
    9. {
    10. if ( event == EVENT_LBUTTONDOWN )
    11. {
    12. userdata *data = ((userdata *) data_ptr);
    13. circle(data->im, Point(x,y), 3,Scalar( 0, 255, 255), 5, CV_AA);
    14. imshow( "Image", data->im);
    15. if (data->points.size() < 4)
    16. {
    17. data->points.push_back(Point2f(x,y));
    18. }
    19. }
    20. }
    21. int main( int argc, char ** argv)
    22. {
    23. // Read in the image.
    24. Mat im_src = imread( "first-image.jpg");
    25. Size size = im_src.size();
    26. // Create a vector of points.
    27. vector<Point2f> pts_src;
    28. pts_src.push_back(Point2f( 0, 0));
    29. pts_src.push_back(Point2f(size.width - 1, 0));
    30. pts_src.push_back(Point2f(size.width - 1, size.height - 1));
    31. pts_src.push_back(Point2f( 0, size.height - 1 ));
    32. // Destination image
    33. Mat im_dst = imread( "times-square.jpg");
    34. // Set data for mouse handler
    35. Mat im_temp = im_dst.clone();
    36. userdata data;
    37. data.im = im_temp;
    38. //show the image
    39. imshow( "Image", im_temp);
    40. cout << "Click on four corners of a billboard and then press ENTER" << endl;
    41. //set the callback function for any mouse event
    42. setMouseCallback( "Image", mouseHandler, &data);
    43. waitKey( 0);
    44. // Calculate Homography between source and destination points
    45. Mat h = findHomography(pts_src, data.points);
    46. // Warp source image
    47. warpPerspective(im_src, im_temp, h, im_temp.size());
    48. // Extract four points from mouse data
    49. Point pts_dst[ 4];
    50. for( int i = 0; i < 4; i++)
    51. {
    52. pts_dst[i] = data.points[i];
    53. }
    54. // Black out polygonal area in destination image.
    55. fillConvexPoly(im_dst, pts_dst, 4, Scalar( 0), CV_AA);
    56. // Add warped source image to destination image.
    57. im_dst = im_dst + im_temp;
    58. // Display image.
    59. imshow( "Image", im_dst);
    60. waitKey( 0);
    61. return 0;
    62. }

    这里写图片描述
    这里写图片描述

    结果:
    这里写图片描述

猜你喜欢

转载自blog.csdn.net/zhangjunhit/article/details/83028293