# Opencv中Homography的使用

### What is Homography?

Two images of a scene are related by a homography under two conditions.

1. The two images are that of a plane (e.g. sheet of paper, credit card etc.).
2. The two images were acquired by rotating the camera about its optical axis. We take such images while generating panoramas.

As mentioned earlier, a homography is nothing but a 3×3 matrix as shown below. Let be a point in the first image and be the coordinates of the same physical point in the second image. Then, the Homography relates them in the following way If we knew the homography, we could apply it to all the pixels of one image to obtain a warped image that is aligned with the second image.

### How to find Homography? Figure 2. Two images of the same 3D plane ( top of the book ) are related by a Homography

If we know 4 or more corresponding points in the two images, we can use the OpenCV function findHomography to find the homography. An example of four corresponding points is shown in the Figure above. The red, green, yellow and orange points are corresponding points.

Internally the function findHomography solves a linear system of equations to find the homography, but in this post we will not go over that math.

Let’s check the usage.

C++

 1 findHomography(points1, points2, h)

Python

 1 h, status =  cv2.findHomography(points1, points2)

where, points1 and points2 are vectors/arrays of corresponding points, and h is the homography matrix.

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、warpPerspective 得到输出

#include <opencv2/opencv.hpp>

using namespace cv;

using namespace std;

struct userdata{

Mat im;

vector<Point2f> points;

};

void mouseDealer(int event, int x, int y, int flags, void* data_ptr)

{

if  ( event == EVENT_LBUTTONDOWN )

{

userdata *data = ((userdata *) data_ptr);

circle(data->im, Point(x,y),3,Scalar(0,0,255), 5, CV_AA);

imshow("Image", data->im);

if (data->points.size() < 4)

{

data->points.push_back(Point2f(x,y));

}

}

}

void main(char argc,char ** argv)

{

// Destination image. The aspect ratio of the book is 3/4

Size size(300,400);

Mat im_dst = Mat::zeros(size,CV_8UC3);

// Create a vector of destination points.

vector<Point2f> pts_dst;

pts_dst.push_back(Point2f(0,0));

pts_dst.push_back(Point2f(size.width - 1, 0));

pts_dst.push_back(Point2f(size.width - 1, size.height -1));

pts_dst.push_back(Point2f(0, size.height - 1 ));

// Set data for mouse event

Mat im_temp = im_src.clone();

userdata data;

data.im = im_temp;

cout << "Click on the four corners of the book -- 顺时针方向" << endl;

// Show image and wait for 4 clicks.

imshow("Image", im_temp);

// Set the callback function for any mouse event

setMouseCallback("Image", mouseDealer, &data);

waitKey(0);

// Calculate the homography

Mat h = findHomography(data.points, pts_dst);

// Warp source image to destination

warpPerspective(im_src, im_dst, h, size);

// Show image

imshow("Image", im_dst);

waitKey(0);

} ©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客 