opencv 通過透視變換可以將圖像的整體或部分進行映射處理,實現其它的視覺效果。透視變換矩陣是核心,這裏給出如何根據兩幅圖像對應區域計算透視變換矩陣,以實現透視變換。可以用到相機標定等處理中。
兩種選點計算方式。
1、手動選點輸入計算
#include<iostream>
#include<opencv2/opencv.hpp>
#include "opencv2/features2d.hpp"
using namespace cv;
using namespace std;
int main()
{
Mat imgc = imread("D:/cal/c.jpg");
Mat imge = imread("D:/cal/e.jpg");
vector<Point2f> c_corners(4);
c_corners[0] = Point2f(246, 249);
c_corners[1] = Point2f(489, 649);
c_corners[2] = Point2f(587, 491);
c_corners[3] = Point2f(424, 69);
vector<Point2f> e_corners(4); //src點對應想放置的位置。例如旋轉
e_corners[0] = Point2f(348, 238);
e_corners[1] = Point2f(576, 585);
e_corners[2] = Point2f(661, 440);
e_corners[3] = Point2f(496, 66);
for (int i = 0; i < 4; i++) {
circle(imgc, c_corners[i], 5, { 0,0,255 }, 5);
circle(imge, e_corners[i], 5, { 0,255,0 }, 5);
}
namedWindow("imgc", WINDOW_KEEPRATIO); imshow("imgc", imgc);//觀察src.dst示意圖
namedWindow("imge", WINDOW_KEEPRATIO); imshow("imge", imge);
/*----------------------------------------- 獲取矩陣 --------------------------------------------------------------*/
Mat transform_M = getPerspectiveTransform(c_corners, e_corners);
cout << transform_M << endl;
waitKey();
return 0;
}
2、鼠標點擊取兩幅圖像對應點
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
struct userdata
{
Mat img;
vector<Point2f> 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->img, Point(x, y), 3, Scalar(0, 255, 255), 5);
namedWindow("Image_window", 0); setWindowProperty("Image_window", WND_PROP_FULLSCREEN, WINDOW_FULLSCREEN); imshow("Image_window", data->img);
if (data->points.size() < 4)
{
data->points.push_back(Point2f(x, y));
}
}
}
int main(int argc, char** argv)
{
Mat im_c = imread("D:/cal/c.jpg");
userdata data_c;
data_c.img = im_c;
namedWindow("Image_window", 0); setWindowProperty("Image_window", WND_PROP_FULLSCREEN, WINDOW_FULLSCREEN); imshow("Image_window", im_c);
setMouseCallback("Image_window", mouseHandler, &data_c);
waitKey(0);
Mat im_e = imread("D:/cal/e.jpg");
userdata data_e;
data_e.img = im_e;
namedWindow("Image_window", 0); setWindowProperty("Image_window", WND_PROP_FULLSCREEN, WINDOW_FULLSCREEN); imshow("Image_window", im_e);
setMouseCallback("Image_window", mouseHandler, &data_e);
waitKey(0);
Mat warpMatrix = getPerspectiveTransform(data_e.points, data_c.points);
cout << "warpMatrix= " << warpMatrix << endl;
getchar();
return 0;
}
鼠標取點會更方便一些。