假设你有一张如下所示的图片 

[opencv]Homography应用:图像矫正_Opencv

 

 

 你想点击图中书的四个顶点,然后得到正放的书:

[opencv]Homography应用:图像矫正_#include_02

该如何做?
利用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 得到输出

#include 

using namespace cv;
using namespace std;

struct userdata{
Mat im;
vector points;
};


void mouseHandler(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()
{

// Read source image.
Mat im_src = imread("book1.jpg");

// 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 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 -- top left first and" << endl
<< "bottom left last -- and then hit ENTER" << endl;

// Show image and wait for 4 clicks.
imshow("Image", im_temp);
// Set the callback function for any mouse event
setMouseCallback("Image", mouseHandler, &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);

Talk is cheap. Show me the code