This example is that for this case.
And see the source code operation in video
...
//#include < time.h> #include < opencv2\opencv.hpp> //#include < opencv2\gpu\gpu.hpp> //#include < opencv2\stitching\detail\matchers.hpp > #include < string> #include < stdio.h> //#include < queue> #ifdef _DEBUG #pragma comment(lib, "opencv_core249d.lib") //#pragma comment(lib, "opencv_imgproc249d.lib") //MAT processing //#pragma comment(lib, "opencv_gpu249d.lib") #pragma comment(lib, "opencv_highgui249d.lib") //#pragma comment(lib, "opencv_objdetect249d.lib") //#pragma comment(lib, "opencv_calib3d249d.lib") //#pragma comment(lib, "opencv_nonfree249d.lib") //#pragma comment(lib, "opencv_features2d249d.lib") #else #pragma comment(lib, "opencv_core249.lib") //#pragma comment(lib, "opencv_imgproc249.lib") //#pragma comment(lib, "opencv_gpu249.lib") #pragma comment(lib, "opencv_highgui249.lib") //#pragma comment(lib, "opencv_objdetect249.lib") //#pragma comment(lib, "opencv_calib3d249.lib") //#pragma comment(lib, "opencv_nonfree249.lib") //#pragma comment(lib, "opencv_features2d249.lib") #endif using namespace std; using namespace cv; static void onMouse( int event, int x, int y, int, void* ); Point2f roi4point[4]={0,}; int roiIndex=0; bool oksign = false; Point2f MinDistFind(float x, float y, Point2f* inPoints); void PointOrderbyConner(Point2f* inPoints, int w, int h ); int main() { //image loading char fileName[100] = "./road-ahead.jpg"; //origin Mat GetImg = imread( fileName ); //copy for drawing Mat RoiImg; //window namedWindow( "set roi by 4 points", 0 ); //mouse callback setMouseCallback( "set roi by 4 points", onMouse, 0 ); //point selection until 4 points setting while(1) { if(oksign == true) //right button click break; //draw point RoiImg = GetImg.clone(); for(int i=0; i< roiIndex; ++i) circle(RoiImg, roi4point[i], 5,CV_RGB(255,0,255),5); imshow("set roi by 4 points", RoiImg); waitKey(10); } printf("points ordered by LT, RT, RB, LB \n"); PointOrderbyConner(roi4point, GetImg.size().width, GetImg.size().height); for(int i=0; i< 4; ++i) { printf("[%d] (%.2lf, %.2lf) \n",i, roi4point[i].x, roi4point[i].y ); } //drwaring RoiImg = GetImg.clone(); string TestStr[4]={"LT","RT","RB","LB"}; putText(RoiImg, TestStr[0].c_str(), roi4point[0], CV_FONT_NORMAL, 1, Scalar(255,255,255)); circle(RoiImg, roi4point[0], 3,CV_RGB(0,0,255)); int i; for(i=1; i< roiIndex; ++i) { line(RoiImg, roi4point[i-1], roi4point[i], CV_RGB(255,0,0),1 ); circle(RoiImg, roi4point[i], 1,CV_RGB(0,0,255),3); putText(RoiImg, TestStr[i].c_str(), roi4point[i], CV_FONT_NORMAL, 1, Scalar(255,255,255)); } line(RoiImg, roi4point[0], roi4point[i-1], CV_RGB(255,0,0),1 ); imshow("set roi by 4 points2", RoiImg); waitKey(0); } void PointOrderbyConner(Point2f* inPoints, int w, int h ) { vector< pair< float, float> > s_point; for(int i=0; i< 4; ++i) s_point.push_back( make_pair(inPoints[i].x, inPoints[i].y) ); //sort sort(s_point.begin(), s_point.end(), [](const pair< float, float>& A, const pair< float, float>& B){ return A.second < B.second; } ); if( s_point[0].first < s_point[1].first ) { inPoints[0].x = s_point[0].first; inPoints[0].y = s_point[0].second; inPoints[1].x = s_point[1].first; inPoints[1].y = s_point[1].second; }else{ inPoints[0].x = s_point[1].first; inPoints[0].y = s_point[1].second; inPoints[1].x = s_point[0].first; inPoints[1].y = s_point[0].second; } if( s_point[2].first > s_point[3].first ) { inPoints[2].x = s_point[2].first; inPoints[2].y = s_point[2].second; inPoints[3].x = s_point[3].first; inPoints[3].y = s_point[3].second; }else{ inPoints[2].x = s_point[3].first; inPoints[2].y = s_point[3].second; inPoints[3].x = s_point[2].first; inPoints[3].y = s_point[2].second; } } static void onMouse( int event, int x, int y, int, void* ) { if( event == CV_EVENT_LBUTTONDOWN && oksign==false) { //4 point select if(roiIndex>=4) { roiIndex=0; for(int i=0; i< 4; ++i) roi4point[i].x = roi4point[i].y =0; } roi4point[roiIndex].x = x; roi4point[roiIndex].y = y; //point coordinate print printf("-(%..2lf,%.2lf), 2:(%.2lf,%.2lf), 3:(%.2lf,%.2lf), 4:(%.2lf,%.2lf)\n", roi4point[0].x, roi4point[0].y,roi4point[1].x, roi4point[1].y,roi4point[2].x, roi4point[2].y,roi4point[3].x, roi4point[3].y ); roiIndex++; } if(event == CV_EVENT_RBUTTONDOWN) { //set point. if(roiIndex == 4) { oksign = true; printf("Warping Start!!!\n"); } } }---
After 4 points selection, click Right button on the mouse, then ordering start.
PointOrderbyConner function is main function for ordering any points to lt, rt, rb, lb.
The logic is..
1. sorted in descending order with respect to the y-coordinate.
2. at 2 coordinates of top in sorted vectors,
finding min x value coordinate in 2 vectors, min is LT, lager is RT.
2. at 2 coordinates of bottom in sorted vectors,
finding min x value coordinate in 2 vectors, min is LB, lager is RB.
1. sorted in descending order with respect to the y-coordinate.
2. at 2 coordinates of top in sorted vectors,
finding min x value coordinate in 2 vectors, min is LT, lager is RT.
2. at 2 coordinates of bottom in sorted vectors,
finding min x value coordinate in 2 vectors, min is LB, lager is RB.
sorry, my low English skill.
See source code more detail.
See source code more detail.
No comments:
Post a Comment