OpenCV2鼠標畫框

#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;
}
相關文章
相關標籤/搜索