好久沒有更新博客了,今天臨時起意,將以前寫的示例代碼整理了一下,暫且發布一篇,希望對大家有用!
代碼一:點擊時顯示坐標,鼠標移動時不顯示。
[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