好久沒有更新博客了,今天臨時起意,將以前寫的示例代碼整理了一下,暫且發布一篇,希望對大家有用! 代碼一:點擊時顯示坐標,鼠標移動時不顯示。 [cpp] #include <cv.h> #include <highgui.h> #include <stdio.h> IplImage* src=0; void on_mouse( int event, int x, int y, int flags, void* ustc) { CvFont font; cvInitFont(&font, CV_FONT_HERSHEY_SIMPLEX, 0.5, 0.5, 0, 1, CV_AA); if( event == CV_EVENT_LBUTTONDOWN ) { CvPoint pt = cvPoint(x,y); char temp[16]; sprintf(temp,"(%d,%d)",pt.x,pt.y); cvPutText(src,temp, pt, &font, cvScalar(255, 255, 255, 0)); cvCircle( src, pt, 2,cvScalar(255,0,0,0) ,CV_FILLED, CV_AA, 0 ); cvShowImage( "src", src ); } } int main() { src=cvLoadImage("lena.jpg",1); cvNamedWindow("src",1); cvSetMouseCallback( "src", on_mouse, 0 ); cvShowImage("src",src); cvWaitKey(0); cvDestroyAllWindows(); cvReleaseImage(&src); return 0; } 代碼二:鼠標移動時顯示坐標,點擊時不顯示坐標 [cpp] #include <cv.h> #include <highgui.h> #include <stdio.h> IplImage* src=0; IplImage* dst=0; void on_mouse( int event, int x, int y, int flags, void* ustc) { CvFont font; cvInitFont(&font, CV_FONT_HERSHEY_SIMPLEX, 0.5, 0.5, 0, 1, CV_AA); if( event == CV_EVENT_MOUSEMOVE ) { cvCopy(dst,src); CvPoint pt = cvPoint(x,y); char temp[16]; sprintf(temp,"(%d,%d)",pt.x,pt.y); cvPutText(src,temp, pt, &font, cvScalar(255, 255, 255, 0)); cvCircle( src, pt, 2,cvScalar(255,0,0,0) ,CV_FILLED, CV_AA, 0 ); cvShowImage( "src", src ); } } int main() { src=cvLoadImage("lena.jpg",1); dst=cvCloneImage(src); cvNamedWindow("src",1); cvSetMouseCallback( "src", on_mouse, 0 ); cvShowImage("src",src); cvWaitKey(0); cvDestroyAllWindows(); cvReleaseImage(&src); cvReleaseImage(&dst); return 0; } 代碼三:鼠標移動和點擊時均顯示坐標 [cpp] #include <cv.h> #include <highgui.h> #include <stdio.h> IplImage* src=0; IplImage* dst=0; void on_mouse( int event, int x, int y, int flags, void* ustc) { char temp[16]; CvPoint pt; CvFont font; cvInitFont(&font, CV_FONT_HERSHEY_SIMPLEX, 0.5, 0.5, 0, 1, CV_AA); if( event == CV_EVENT_MOUSEMOVE ) { cvCopy(dst,src); sprintf(temp,"(%d,%d)",x,y); pt = cvPoint(x,y); cvPutText(src,temp, pt, &font, cvScalar(255, 255, 255, 0)); cvCircle( src, pt, 2,cvScalar(255,0,0,0) ,CV_FILLED, CV_AA, 0 ); cvShowImage( "src", src ); } else if( event == CV_EVENT_LBUTTONDOWN ) { //cvCopy(dst,src); sprintf(temp,"(%d,%d)",x,y); pt = cvPoint(x,y); cvPutText(src,temp, pt, &font, cvScalar(255, 255, 255, 0)); cvCircle( src, pt, 2,cvScalar(255,0,0,0) ,CV_FILLED, CV_AA, 0 ); cvCopy(src,dst); cvShowImage( "src", src ); } } int main() { src=cvLoadImage("lena.jpg",1); dst=cvCloneImage(src); cvNamedWindow("src",1); cvSetMouseCallback( "src", on_mouse, 0 ); cvShowImage("src",src); cvWaitKey(0); cvDestroyAllWindows(); cvReleaseImage(&src); cvReleaseImage(&dst); return 0; } 代碼四,上面的代碼在邊界處處理的不好,坐標值顯示的不完全,下面是對代碼三的改進。下面的代碼還將點約束在圖像的幾何區域范圍內。 [cpp] #include <cv.h> #include <highgui.h> #include <stdio.h> #define max(a,b) (((a) > (b)) ? (a) : (b)) #define min(a,b) (((a) < (b)) ? (a) : (b)) //注意參數是有符號短整型,該函數的作用是使i限定為[a,b]區間內 int bound(short i,short a,short b) { return min(max(i,min(a,b)),max(a,b)); } IplImage* src=0; IplImage* dst=0; void on_mouse( int event, int x, int y, int flags, void* ustc) { char temp[16]; CvPoint pt; CvFont font; cvInitFont(&font, CV_FONT_HERSHEY_SIMPLEX, 0.5, 0.5, 0, 1, CV_AA); CvPoint tmp_pt = {-1,-1}; CvSize text_size; int baseline; if( event == CV_EVENT_MOUSEMOVE ) { cvCopy(dst,src); x=bound(x,0,src->width-1); y=bound(y,0,src->height-1); pt = cvPoint(x,y); cvCircle( src, pt, 2,cvScalar(255,0,0,0) ,CV_FILLED, CV_AA, 0 ); sprintf(temp,"(%d,%d)",x,y); cvGetTextSize(temp,&font,&text_size,&baseline); tmp_pt.x = bound(pt.x,0,src->width-text_size.width); tmp_pt.y = bound(pt.y,text_size.height+baseline,src->height-1-baseline); cvPutText(src,temp, tmp_pt, &font, cvScalar(255, 255, 255, 0)); cvShowImage( "src", src ); } else if( event == CV_EVENT_LBUTTONDOWN ) { //cvCopy(dst,src); pt = cvPoint(x,y); cvCircle( src, pt, 2,cvScalar(255,0,0,0) ,CV_FILLED, CV_AA, 0 ); sprintf(temp,"(%d,%d)",x,y); cvGetTextSize(temp,&font,&text_size,&baseline); tmp_pt.x = bound(pt.x,0,src->width-text_size.width); tmp_pt.y = bound(pt.y,text_size.height+baseline,src->height-1-baseline); cvPutText(src,temp, tmp_pt, &font, cvScalar(255, 255, 255, 0)); cvCopy(src,dst); cvShowImage( "src", src ); } } int main() { src=cvLoadImage("lena.jpg",1); dst=cvCloneImage(src); cvNamedWindow("src",1); cvSetMouseCallback( "src", on_mouse, 0 ); cvShowImage("src",src); cvWaitKey(0); cvDestroyAllWindows(); cvReleaseImage(&src); cvReleaseImage(&dst); return 0; } 代碼五,上面的代碼不能撤銷選定的坐標,下面的代碼對此進行了改進,右擊撤銷最近選擇的點,並用互補的顏色表示選擇的點和撤銷選定的點。除此之外還將選擇的坐標輸出到文件。在點的坐標前還有一個數表示點的選定次序。 [cpp] #include <cv.h> #include <highgui.h> #include <stdio.h> #include <vector> #include <fstream> using namespace std; #define max(a,b) (((a) > (b)) ? (a) : (b)) #define min(a,b) (((a) < (b)) ? (a) : (b)) //注意參數是有符號短整型,該函數的作用是使i限定為[a,b]區間內 int bound(short i,short a,short b) { return min(max(i,min(a,b)),max(a,b)); } CvScalar getInverseColor(CvScalar c) { CvScalar s; for(int i=0;i<=2;++i) { s.val[i]=255-c.val[i]; } return s; } IplImage* src=0; IplImage* dst=0; int n=0; vector<CvPoint> points; void on_mouse( int event, int x, int y, int flags, void* ustc) { CvPoint pt; CvPoint tmp_pt = {-1,-1}; CvFont font; cvInitFont(&font, CV_FONT_HERSHEY_SIMPLEX, 0.4, 0.4, 0, 1, CV_AA); char temp[16]; CvSize text_size; int baseline; CvScalar clrPoint=cvScalar(255,0,0,0); CvScalar clrText=cvScalar(255, 255, 255, 0); if( event == CV_EVENT_MOUSEMOVE ) { cvCopy(dst,src); x=bound(x,0,src->width-1); y=bound(y,0,src->height-1); pt = cvPoint(x,y); cvCircle( src, pt, 2,clrPoint ,CV_FILLED, CV_AA, 0 ); sprintf(temp,"%d (%d,%d)",n+1,x,y); cvGetTextSize(temp,&font,&text_size,&baseline); tmp_pt.x = bound(pt.x,0,src->width-text_size.width); tmp_pt.y = bound(pt.y,text_size.height+baseline,src->height-1-baseline); cvPutText(src,temp, tmp_pt, &font, clrText); cvShowImage( "src", src ); } else if( event == CV_EVENT_LBUTTONDOWN) { pt = cvPoint(x,y); points.push_back(pt); n++; cvCircle( src, pt, 2, clrPoint ,CV_FILLED, CV_AA, 0 ); sprintf(temp,"%d (%d,%d)",n,x,y); cvGetTextSize(temp,&font,&text_size,&baseline); tmp_pt.x = bound(pt.x,0,src->width-text_size.width); tmp_pt.y = bound(pt.y,text_size.height+baseline,src->height-1-baseline); cvPutText(src,temp, tmp_pt, &font, clrText); cvCopy(src,dst); cvShowImage( "src", src ); } else if( event == CV_EVENT_RBUTTONDOWN ) { if(!points.empty()) { cvCopy(dst,src); pt=points.back(); points.pop_back(); cvCircle( src, pt, 2, getInverseColor(clrPoint),CV_FILLED, CV_AA, 0 ); sprintf(temp,"%d (%d,%d)",n,pt.x,pt.y); --n; cvGetTextSize(temp,&font,&text_size,&baseline); tmp_pt.x = bound(pt.x,0,src->width-text_size.width); tmp_pt.y = bound(pt.y,text_size.height+baseline,src->height-1-baseline); cvPutText(src,temp, tmp_pt, &font, getInverseColor(clrText)); cvCopy(src,dst); cvShowImage( "src", src ); } } } int main() { src=cvLoadImage("lena.jpg",1); dst=cvCloneImage(src); cvNamedWindow("src",1); cvSetMouseCallback( "src", on_mouse, 0 ); cvShowImage("src",src); cvWaitKey(0); cvDestroyAllWindows(); cvReleaseImage(&src); cvReleaseImage(&dst); ofstream file("sample.txt"); if(!file) { cout << "open file error!"; return 1; } vector<CvPoint>::iterator it=points.begin(); for(;it!=points.end();++it) { file<< it->x<<','<<it->y<<endl; } file<<endl; file.close(); return 0; } 其的演示如下: sample.txt中的內容如下: [plain] 319,351 382,284 275,292 194,249 357,210 424,260 350,251 305,238 274,189 227,140 224,375