OpenCV2鼠标画框

f5ce6886b9bc11c7d48b3e8bed9c098c73d.jpg

#include <iostream>
#include <cv.h>
#include <highgui.h>

using namespace cv;
using namespace std;
CvRect box;
void draw_box( IplImage* img, CvRect rect )
{
    cvRectangle(img,
                cvPoint(box.x, box.y),  确定左上角坐标
                cvPoint(box.x+box.width,box.y+box.height),//确定右下角坐标
                cvScalar(0xff,0xff,0xff)    //线条白色
                );
}
bool drawing_box = false;
void my_mouse_callback(int event, int x, int y, int flags, void* param )
{
    IplImage *image = (IplImage*)param;  //鼠标事件对param图片结构做出更改

    switch(event)
    {
        case CV_EVENT_MOUSEMOVE:   //触发鼠标移动事件
        {
          if( drawing_box ) {
               box.width  = x-box.x;
               box.height = y-box.y;
             }
       }
        break;
        case CV_EVENT_LBUTTONDOWN: //触发左键按下事件
        {
          drawing_box = true;
          box = cvRect( x, y, 0, 0 );
        }
        break;
        case CV_EVENT_LBUTTONUP:  //"触发左键抬起事件"
       {
         drawing_box = false;
         if( box.width<0  ) {
           box.x+=box.width;
           box.width *=-1;
         }
         if( box.height<0 ) {
           box.y+=box.height;
           box.height*=-1;
         }
         draw_box( image, box );
       }
       break;
      default:
                break;
     }

    //     case CV_EVENT_RBUTTONDOWN: //"触发右键按下事件"
   // }
}



int main()
{
    cvNamedWindow( "Box namming"  );  //用来创建窗口显示图像
    void my_mouse_callback(int event, int x, int y, int flags, void* param );
    IplImage *image = cvCreateImage(cvSize(200, 200), IPL_DEPTH_8U, 3);  //定义了一个IplImage指针变量image,图像的大小是200×200,图像颜色深度8位,3通道图像。
    cvZero( image );//全变黑:将图像中的每个像素都置为0
    cvSetMouseCallback(   //鼠标事件发生
        "Box namming",    //指定窗口
        my_mouse_callback,  //回调函数名字注册到Box namming窗口
        (void*) image    //传入的函数的void* param 参数是(void*) image,//即我们前面定义的IplImage* image
      );

    /*void   cvSetMouseCallback( const  char*   window_name,
     *              CvMouseCallback  on_mouse,
     * void*   param=NULL );
     * window_name 窗口的名字。
     * on_mouse 指定窗口里每次鼠标事件发生的时候,被调用的函数指针。就是回调函数。
     * param 用户定义的传递到回调函数的参数,也就是传递额外的信息给回调函数的void  *param参数。
     * 鼠标事件响应采用回调函数的方式来处理。即,为了可以响应鼠标点击事件,首先必须创建一个回调函数
     * ,使鼠标点击事件发生时OpenCV可以调用这个函数。创建这个函数以后,需要在OpenCV中注册这个函数
     * ,以便特定窗口被触发鼠标事件以后,OpenCV可以正确调用这个函数。
     */
    IplImage* temp = cvCloneImage( image );
   // IplImage* temp = image;
    /*IplImage* cvCloneImage( const IplImage* image );
     * 在使用函数之前,不用开辟内存。该函数会自己开一段内存,
     * 然后复制好image里面的数据,然后把这段内存中的数据返回给你。
     * clone是把所有的都复制过来,也就是说不论你是否设置Roi,Coi等
     * 影响copy的参数,clone都会原封不动的克隆过来。
     * 在temp上画图——依然会触发鼠标事件,从而触发回调函数,从而实现了对图片image进行了操作。
     * “在结束之前,为了实时显示所画的图形,将所画的图放在temp变量中,待画图结束时在image中存放这一次画图的最终结果。”
     * 就是说我们之所以有一个temp,是因为如果没有temp,直接在image画,那么会显示过程,那么画一个矩形,一个大矩形由无数个小矩形组成,但我们只要最终结果。
   */
    box = cvRect(-1, -1, 50, 50);
    /*
     * 它是OpenCV里面的基本数据类型
     * 功能: 包含4个数据成员,x,y,width,height,通过定义矩形左上角坐标和矩形的宽和高来确定一个矩形。
     * OpenCV里面的基本数据类型
     * 结构体功能: 通过矩形左上角坐标和矩形的宽和高来确定一个矩形区域
     * typedef struct CvRect
     *  {
     *        int x; // 方形的左上角的x-坐标
     *        int y; // 方形的左上角的y-坐标
     *        int width; // 宽
     *       int height;  高
     * }
    */
    while (1) {
         cvCopy( image, temp );   //cvCopyImage
         /*void cvCopy( const CvArr* src, CvArr* dst, const CvArr* mask=NULL );
          * 如果设定了ROI等参数的时候,cvCopy只是复制被设定的区域,复制到一个和所设定参数相吻合的新的IplImage中。
          * 在使用这个函数之前,你必须用cvCreateImage()一类的函数先开一段内存,然后传递给dst。cvCopy会把src中的数据复制到dst的内存中。
          * copy就不一样,只会复制ROI区域等。用clone复制之后,源图像在内存中消失后,复制的图像也变了,而用copy复制,源图像消失后,复制的图像不变。
          */
         if( drawing_box ) draw_box( temp, box );
          cvShowImage( "Box namming", temp );
          if( cvWaitKey( 15 )==27 ) break;
    }
    cvReleaseImage( &image );
     cvReleaseImage( &temp );
     cvDestroyWindow( "Box Example" );
    return 0;
}

 

转载于:https://my.oschina.net/u/3919756/blog/1936070

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值