/*终于懂啦鼠标函数my_mouse_callback被鼠标注册函数cvsetmousecallback注册到窗口Box Example*/
/*以后只要出现该窗口的地方就可调用该鼠标事件这就是为啥while循环里只有如下*/
// while(1){
//将image图像复制到temp中********/ cvCopyImage(image,temp);
//判断drawing_box的ture和false*/ if(drawing_box) draw_box(temp,box);
//如果为ture就调用draw_box函数并传入参数*/
//图像变量temp和cvRect变量box*/
//*在BoxExample窗口中显示图像变量temp中的图片*/cvShowImage("Box Example",temp);
//*等待15秒的按键esc*/ if(cvWaitKey(15)==27) break;
//*如果按啦esc就退出循环*/ }
/*而没有cvsetmousecallback的原因 应为循环里出现啦cvShowImage("Box Example",temp);在反复调用窗口的同时就会反复出现鼠标事件啦*/
/*鼠标拖动画图的话 就是3个动作
一:鼠标DOWN
二:鼠标MOVE
三:鼠标UP
关键就是让这几个动作连续起来如是就用WHILE(1)
*/
#include<cv.h>
#include<highgui.h>
/*声明鼠标回调函数 */ void my_mouse_callback(int event,int x,int y,int flags,void* param);
//CvRect 和cvRectangle 有啥区别
/*定义CvRect结构的box变量*/ CvRect box;
/*定义bool类型的变量drawing_box*/bool drawing_box=false;
/*并初始化为false */
/*声明画框的函数draw_box*/ void draw_box(IplImage* img, CvRect rect){
/*并传入图像结构的img变量和cvRect*/
/*的rect变量*/
/*使用cvRectangle函数*/ cvRectangle(
img,
cvPoint(box.x,box.y),
cvPoint(box.x+box.width,box.y+box.height),
cvScalar(0xff,0x00,0x00)
);
}
int main(int argc,char* argv[])
{
/*用cvRect函数初始化box变量*/ box=cvRect(-1,-1,0,0);
/*创造一图像并保存在image变量中*/ IplImage* image= cvCreateImage(cvSize(500,500),IPL_DEPTH_8U,3);
/*将image中的图像初始化为0*/ cvZero(image);
/*将image中的图像复制到temp变量中*/ IplImage* temp=cvCloneImage(image);
/*创建一个名为Box Example的窗口*/ cvNamedWindow("Box Example");
/*将鼠标函数mymousecallback注册到*/ cvSetMouseCallback("Box Example",my_mouse_callback,(void*)image);
/*窗口Box Example中 并将image图像*/
/*传到鼠标函数mymousecallback中*/ //在这个循环里有两个问题
//1.为什么要创建temp的image图像的复制版本
//2.为什么有if(drawing_box)draw_box(temp,box)联系上下文即为什么鼠标down的时候还要
//draw box
//这两个问题的解答见附录
/********************************/
/*使用while循环*/ while(1){
/*将image图像复制到temp中********/ cvCopyImage(image,temp);
/*判断drawing_box的ture和false*/ //if(drawing_box) draw_box(temp,box);
/*如果为ture就调用draw_box函数并传入参数*///if(drawing_box)draw_box(image,box);
/*图像变量temp和cvRect变量box*/
/*在BoxExample窗口中显示图像变量temp中的图片*/cvShowImage("Box Example",temp);
/*等待15秒的按键esc*/ //cvShowImage("Box Example",image);
if(cvWaitKey(15)==27) break;
/*如果按啦esc就退出循环*/ }
/********************************/
/*释放image图片*/ cvReleaseImage(&image);
/*释放temp图片*/ cvReleaseImage(&temp);
/*摧毁窗口BoxExample*/ cvDestroyWindow("Box Example");
}
/***************************/
/*鼠标函数mymousecallback的定义*/ void my_mouse_callback(int event,int x,int y,int flags,void* param ){
/*将传入的图片变量param中的图片传入*/ IplImage* image=(IplImage*)param;
/*图片变量image中*/
/*启动switch语句*/ switch(event){
/********用户鼠标move**********/ case CV_EVENT_MOUSEMOVE:{
/*判断drawing_box的ture和false*/ if(drawing_box)
/*如果为ture 则*/ {
/*cvRect结构变量box中的box.width等于*/ box.width=x-box.x;
/*鼠标所在位置的象素x坐标减去box的box.x*/ box.height=y-box.y;
/*box中的box.height等于*/ }
/*鼠标所在位置的象素y坐标减去box.y*/
}
break;
/***用户鼠标左键down***********/ case CV_EVENT_LBUTTONDOWN:{
/*将drawing_box变量赋值为true*/ drawing_box=true;//这里的drawing_box就相当于一个开关是ture就开关
/*将cvRect结构的box变量用cvRect赋值*/ //而这个开关的插座就是if(drawing_box)语句
/*其中赋值函数传入坐标x,y*/ box=cvRect(x,y,0,0);
}
break;
/****用户鼠标左键up********/ case CV_EVENT_LBUTTONUP:
{
/*将drawing_box变量赋值*/ drawing_box=false;
//这两个if语句是考虑到鼠标反向拖动时的情况下画框的实现
/***判断cvRect结构的变量box中的***/ if(box.width<0)
/*box.width是否小于0*/
/*如果是就*/ {
/*将cvRect结构的box的box.x值*/ box.x+=box.width;
/*加上box.width*/ box.width*=-1;
/*box的box.width乘以-1*/ }
/***判断cvRect结构的box中的**/ if(box.height<0)
/*box.height是否小于0*/ {
/*如果就是*/ box.y+=box.height;
/*将cvRect结构的box.y*/ box.height*=-1;
/*加上box.height*/ }
/*box.height乘以-1*/
/*调用函数draw_box*/ draw_box(image,box);
/*传入图像变量的image和cvRect结构的box*/ }
break;
}
}
/******************************************************************************/
/******************************副**********************************************/
/******************************录**********************************************/
/*问题1的解答:
先把用到temp的地方全部用image替换 即不使用temp看看程序结果咋样
结果就是你鼠标还没Up的时候 你的大框里不自觉的出现啦许多小框
经分析 temp的作用就是每次循环时用新创建的temp去掩盖已经成型的小框
这个小框其实是while循环里if语句画出来的 即第二个问题里的
**问题2的解答:
鼠标down的时候为什么要画框
先把while循环里的这句去掉然后运行程序 结果脱动鼠标时啥都没有 鼠标UP的时候才出现啦大框
故这个if语句就是实现拖动时的这个效果
***综合问题1问题2
其实问题2就是实现鼠标拖动时的效果 而问题1是消除其副作用*/