關於透視投影的幾何知識,以及求解方法,可以參考
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 }
結果