关于透视投影的几何知识,以及求解方法,可以参考
http://media.cs.tsinghua.edu.cn/~ahz/digitalimageprocess/chapter06/chapt06_ahz.htm
http://blog.csdn.net/xiaowei_cqu/article/details/26471527
此外,opencv1那本书183页也有讲
这里,实现一个贴图,主要参考
http://www.cnblogs.com/tiandsp/p/4033071.html
那篇博客用的matlab,这里使用opencv2实现
原图
代码
1 #include <cv.h> 2 #include <highgui.h> 3 #include <iostream> 4 #include <vector> 5 #include <fstream> 6 7 using namespace std; 8 using namespace cv; 9 10 Mat rawImg, dstImg,boardImg,dstboard,maskboard; 11 vector<Point2f>srcQuad(4); 12 vector<Point2f>dstQuad(4); 13 14 void on_mouse(int event, int x, int y, int flags, void *ustc)//event鼠标事件代号,x,y鼠标坐标,flags拖拽和键盘操作的代号 15 { 16 Point pt;//坐标点; 17 char coordinateName[16]; 18 static int n=0; 19 20 if (event == CV_EVENT_LBUTTONDOWN)//左键按下,读取坐标,并在图像上该点处划圆 21 { 22 pt = Point(x, y); 23 cout << x << " " << y << endl; 24 dstQuad[n] = pt; 25 n++; 26 circle(boardImg, pt, 2, Scalar(255, 0, 0, 0), CV_FILLED, CV_AA, 0);//划圆 27 sprintf(coordinateName, "(%d,%d)", x, y); 28 putText(boardImg, coordinateName, pt, FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 0, 0, 255), 1, 8);//在窗口上显示坐标 29 if (n >= 4) 30 { 31 //imshow("board", boardImg); 32 cvDestroyAllWindows(); 33 } 34 } 35 } 36 int main() 37 { 38 rawImg = imread("lena.jpg",0);//图片路径 39 boardImg = imread("board.jpg",0); 40 dstboard = boardImg.clone(); 41 cvNamedWindow("board",0); 42 setMouseCallback("board",on_mouse,0); 43 imshow("board",boardImg); 44 waitKey(0); 45 imshow("raw", rawImg); 46 imshow("board", boardImg); 47 int imgHeigth = rawImg.rows; 48 int imgWidth = rawImg.cols; 49 int dstHeigth = boardImg.rows; 50 int dstWidth = boardImg.cols; 51 srcQuad[0] = Point2f(0,0);//左上 右上 左下 右下 52 srcQuad[1] = Point2f(imgWidth-1, 0); 53 srcQuad[2] = Point2f(0, imgHeigth - 1); 54 srcQuad[3] = Point2f(imgWidth - 1, imgHeigth - 1); 55 /*dstQuad[0] = Point2f(imgWidth*0.05, imgHeigth*0.33); 56 dstQuad[1] = Point2f(imgWidth*0.9, imgHeigth*0.25); 57 dstQuad[2] = Point2f(imgWidth*0.2, imgHeigth*0.7); 58 dstQuad[3] = Point2f(imgWidth*0.8, imgHeigth*0.9);*/ 59 for (int i = 0; i < 4; i++) 60 cout << dstQuad[i] << endl; 61 62 Mat warpMatrix = getPerspectiveTransform(srcQuad, dstQuad); 63 cout << warpMatrix << endl; 64 warpPerspective(rawImg, dstImg, warpMatrix, Size(dstWidth, dstHeigth)); 65 66 threshold(dstImg, maskboard, 0, 1, THRESH_BINARY); 67 cout << "begin a test of cout to file." << endl; 68 // 保存cout流缓冲区指针 69 streambuf* coutBuf = cout.rdbuf(); 70 ofstream of("out.txt"); 71 // 获取文件out.txt流缓冲区指针 72 streambuf* fileBuf = of.rdbuf(); 73 // 设置cout流缓冲区指针为out.txt的流缓冲区指针 74 cout.rdbuf(fileBuf); 75 cout << maskboard << endl; 76 77 of.flush(); 78 of.close(); 79 // 恢复cout原来的流缓冲区指针 80 cout.rdbuf(coutBuf); 81 //imshow("rawboard", dstboard); 82 cout << "Write Personal Information over..." << endl; 83 for (int i = 0; i < dstHeigth - 1; i++) 84 for (int j = 0; j < dstWidth - 1; j++) 85 dstImg.at<uchar>(i, j) = dstImg.at<uchar>(i, j)*maskboard.at<uchar>(i, j) 86 + dstboard.at<uchar>(i, j)*(1-maskboard.at<uchar>(i, j)); 87 imshow("result", dstImg); 88 waitKey(); 89 return 0; 90 }
结果