cvSetMouseCallback函数(注册鼠标相应回调函数)
鼠标操作涉及两个函数,第一个是cvSetMouseCallback,这个函数注册一个回调函数。使用方法如下:
cvSetMouseCallback("TestWin", TestCallBack, Context);
前两个参数分别是窗口的名字和回调函数,最后一个参数需要稍微解释一下,这个参数会作为参数传递给回调函数,从而也就可以在主进程与回调函数之间交换上下文。这样就不需要设置大量的全局变量而破坏了整体程序的结构。
鼠标操作需要的第二函数是由开发者自己编写的,这个函数具有下面的原型:
void Foo(int event, int x, int y, int flags, void* param);
观察这个函数的参数,第一个参数是event表达了当前的鼠标事件,鼠标事件的类型有如下几种:
#define CV_EVENT_MOUSEMOVE 0
#define CV_EVENT_LBUTTONDOWN 1
#define CV_EVENT_RBUTTONDOWN 2
#define CV_EVENT_MBUTTONDOWN 3
#define CV_EVENT_LBUTTONUP 4
#define CV_EVENT_RBUTTONUP 5
#define CV_EVENT_MBUTTONUP 6
#define CV_EVENT_LBUTTONDBLCLK 7
#define CV_EVENT_RBUTTONDBLCLK 8
#define CV_EVENT_MBUTTONDBLCLK 9
定义的名字已经很好解释了其中的定义。第二个、第三个参数给出了当前鼠标的位置。需要注意的是,这个位置不是相对于窗口或者整个屏幕的,而是相对于Image的。当然这个本身和OpenCV显示的方式是一致的,毕竟我们对于窗口的操作是在Image的基础上完成的。
第三个参数告诉我们当前按键的情况,具体标志如下:
#define CV_EVENT_FLAG_LBUTTON 1
#define CV_EVENT_FLAG_RBUTTON 2
#define CV_EVENT_FLAG_MBUTTON 4
#define CV_EVENT_FLAG_CTRLKEY 8
#define CV_EVENT_FLAG_SHIFTKEY 16
#define CV_EVENT_FLAG_ALTKEY 32
很容易看出,只需要执行(flag & CV_EVENT_FLAG_LBUTTON)的操作就可以检测左键是否按下,对于其他按键也是类似的。
cvPutText函数(在图像中加入文本)
void cvPutText( CvArr* img, const char* text, CvPoint org, const CvFont* font, CvScalar color );
img :输入图像。
text :显示字符串。
org:第一个字符左下角的坐标。
font :字体结构初始化。
color :文本的字体颜色。
函数 cvPutText 将具有指定字体的和指定颜色的文本加载到图像中。加载到图像中的文本被感兴趣的矩形框圈定。
cvInitFont函数(字体结构初始化)
void cvInitFont( CvFont* font, int font_face, double hscale, double vscale,
double shear=0, int thickness=1, int line_type=8 );
font :字体初始化。
font_face :字体名称标识符。
CV_FONT_HERSHEY_SIMPLEX - 正常大小无衬线字体。
CV_FONT_HERSHEY_PLAIN - 小号无衬线字体。
CV_FONT_HERSHEY_DUPLEX - 正常大小无衬线字体比 CV_FONT_HERSHEY_SIMPLEX 更复杂)
CV_FONT_HERSHEY_COMPLEX - 正常大小有衬线字体。
CV_FONT_HERSHEY_TRIPLEX - 正常大小有衬线字体 ( 比 CV_FONT_HERSHEY_COMPLEX更复杂)
CV_FONT_HERSHEY_COMPLEX_SMALL - CV_FONT_HERSHEY_COMPLEX 的小译本。
CV_FONT_HERSHEY_SCRIPT_SIMPLEX - 手写风格字体。
CV_FONT_HERSHEY_SCRIPT_COMPLEX - 比 CV_FONT_HERSHEY_SCRIPT_SIMPLEX 更复杂。
参数能够由一个值和可选择的 CV_FONT_ITALIC 字体标记合成。就是斜体字。
hscale :字体宽度。如果等于 1.0f,字符的宽度是最初的字体宽度。如果等于 0.5f,字符的宽度是最初的字体宽度的一半。
vscale:字体高度。如果等于 1.0f,字符的高度是最初的字体高度。如果等于 0.5f,字符的高度是最初的字体高度的一半。
shear :字体的斜度。当值为 0时 ,字符不倾斜。当值为 1.0f时,字体倾斜 45度。
thickness :字体笔划的粗细程度。
line_type :字体笔划的类型,见 cvLine 的描述。
函数 cvInitFont 完成对文本的描述。
sprintf函数(把格式化的数据写入某个字符串)
int sprintf( char *buffer, const char *format [, argument] … );
返回值:字符串长度(strlen)
程序代码:
#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)&&(flags))//鼠标左键按下事件发生
{
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;
}