5/01/2014

(OpenCV Study) setMouseCallback function example source code, get rectangle coordinate of mouse drag on image.

This  source code is useful when you need retangle coordinate of mouse drag.
The rectangle coordinate is applied initial region for tracking.

refer to video and source code.

#include < stdio.h>
#include < iostream>

#include < opencv2\opencv.hpp>
//#include < opencv2/core/core.hpp>
//#include < opencv2/highgui/highgui.hpp>
//#include < opencv2/video/background_segm.hpp>
//#include < opencv2\gpu\gpu.hpp>
//#include < opencv2\legacy\legacy.hpp>

#ifdef _DEBUG        
#pragma comment(lib, "opencv_core247d.lib")
//#pragma comment(lib, "opencv_imgproc247d.lib")   //MAT processing
//#pragma comment(lib, "opencv_objdetect247d.lib") //HOGDescriptor
//#pragma comment(lib, "opencv_gpu247d.lib")
//#pragma comment(lib, "opencv_features2d247d.lib")
#pragma comment(lib, "opencv_highgui247d.lib")
//#pragma comment(lib, "opencv_ml247d.lib")
//#pragma comment(lib, "opencv_stitching247d.lib");
//#pragma comment(lib, "opencv_nonfree247d.lib");
//#pragma comment(lib, "opencv_video247d.lib")
//#pragma comment(lib, "opencv_legacy247d.lib")
#else
#pragma comment(lib, "opencv_core247.lib")
//#pragma comment(lib, "opencv_imgproc247.lib")
//#pragma comment(lib, "opencv_objdetect247.lib")
//#pragma comment(lib, "opencv_gpu247.lib")
//#pragma comment(lib, "opencv_features2d247.lib")
#pragma comment(lib, "opencv_highgui247.lib")
//#pragma comment(lib, "opencv_ml247.lib")
//#pragma comment(lib, "opencv_stitching247.lib");
//#pragma comment(lib, "opencv_nonfree247.lib");
//#pragma comment(lib, "opencv_video247.lib")
//#pragma comment(lib, "opencv_legacy247.lib")
#endif 

using namespace std;
using namespace cv;

bool selectObject = false;
Rect selection;
Point origin;
int trackObject = 0;
Mat image;


static void onMouse( int event, int x, int y, int, void* )
{
    if( selectObject )
    {
        selection.x = MIN(x, origin.x);
        selection.y = MIN(y, origin.y);
        selection.width = std::abs(x - origin.x);
        selection.height = std::abs(y - origin.y);

        selection &= Rect(0, 0, image.cols, image.rows);
    }

    switch( event )
    {
    case CV_EVENT_LBUTTONDOWN:
        origin = Point(x,y);
        selection = Rect(x,y,0,0);
        selectObject = true;
        break;
    case CV_EVENT_LBUTTONUP:
        selectObject = false;
        if( selection.width > 0 && selection.height > 0 )
            trackObject = -1;
        break;
    }
}


int main (void)  
{  
 

 VideoCapture cap(0);
 Mat frame;
 namedWindow( "Demo", 0 );
 setMouseCallback( "Demo", onMouse, 0 );

    for(;;)
    {
        
  cap >> frame;
        if( frame.empty() )
   break;

        frame.copyTo(image);
  

  if( selectObject && selection.width > 0 && selection.height > 0 )
        {
            Mat roi(image, selection);
            bitwise_not(roi, roi);
   printf("%d %d %d %d\n", selection.x, selection.y, selection.width, selection.height);
        }

  imshow( "Demo", image );

  if( waitKey(10) > 10 )
   break;
 }

 return 0;  
}  



3 comments:

  1. Hello, I have the following code, can you please help me with an advice.
    I have an error at SetMousecallback, more exacly at parameer onMouse (a pointer to member is not valid for a managed class) . I remain grateful.
    private: System::Void button5_Click(System::Object^ sender, System::EventArgs^ e) {

    src = mOriginalImagesAf.clone();
    namedWindow(winName, WINDOW_NORMAL);
    setMouseCallback(winName, onMouse, NULL);
    imshow(winName, src);

    }



    void checkBoundary(){
    //check croping rectangle exceed image boundary
    if (cropRect.width>img.cols - cropRect.x)
    cropRect.width = img.cols - cropRect.x;

    if (cropRect.height>img.rows - cropRect.y)
    cropRect.height = img.rows - cropRect.y;

    if (cropRect.x<0)
    cropRect.x = 0;

    if (cropRect.y<0)
    cropRect.height = 0;
    }

    void showImage(){
    img = src.clone();
    checkBoundary();
    if (cropRect.width>0 && cropRect.height>0){
    ROI = src(cropRect);
    imshow("cropped", ROI);
    }

    rectangle(img, cropRect, Scalar(0, 255, 0), 1, 8, 0);
    imshow(winName, img);
    }


    void onMouse(int event, int x, int y, int f, void*){


    switch (event){

    case CV_EVENT_LBUTTONDOWN:
    clicked = true;

    P1.x = x;
    P1.y = y;
    P2.x = x;
    P2.y = y;
    break;

    case CV_EVENT_LBUTTONUP:
    P2.x = x;
    P2.y = y;
    clicked = false;
    break;

    case CV_EVENT_MOUSEMOVE:
    if (clicked){
    P2.x = x;
    P2.y = y;
    }
    break;

    default: break;


    }


    if (clicked){
    if (P1.x>P2.x){
    cropRect.x = P2.x;
    cropRect.width = P1.x - P2.x;
    }
    else {
    cropRect.x = P1.x;
    cropRect.width = P2.x - P1.x;
    }

    if (P1.y>P2.y){
    cropRect.y = P2.y;
    cropRect.height = P1.y - P2.y;
    }
    else {
    cropRect.y = P1.y;
    cropRect.height = P2.y - P1.y;
    }

    }


    showImage();


    }

    ReplyDelete
  2. μ•ˆλ…•ν•˜μ„Έμš” 자꾸 질문 μ˜¬λ €λ“œλ € μ£„μ†‘ν•©λ‹ˆλ‹€.
    onMouse ν•¨μˆ˜μ—μ„œ selection &= Rect(0,0,image.cols, image.rows)λŠ” μ™œ ν•΄μ£ΌλŠ” κ²ƒμΈκ°€μš”?? x,y μ’Œν‘œλ₯Ό 날리고 width와 height κ°’λ§Œ 남기렀고 ν•˜λŠ”κ²ƒμΈκ°€μš”???
    λ‹΅λ³€ν•΄μ£Όμ‹œλ©΄ κ°μ‚¬ν•˜κ² μŠ΅λ‹ˆλ‹€.

    ReplyDelete
    Replies
    1. λ„€ μ•ˆλ…•ν•˜μ„Έμš”.
      닡변이 λŠ¦μ–΄μ„œ μ£„μ†‘ν•©λ‹ˆλ‹€.
      Rect & Rect λ₯Ό ν•œ μ΄μœ λŠ” μ„ νƒν•œ rect의 크기가 이미지보닀 크지 μ•Šκ²Œ ν•˜κΈ° μœ„ν•΄μ„œ μž…λ‹ˆλ‹€.
      μ—¬κΈ°μ„œλŠ” μ‹¬κ°ν•˜μ§„ μ•Šμ§€λ§Œ, rect 크기둜 μ–΄λ–€ μ˜μƒ 처리 연산을 ν• λ•Œ 이미지λ₯Ό λ²—μ–΄λ‚˜κ²Œ λ˜λŠ” 값이 μžˆμ„λ•Œ 였λ₯˜λ₯Ό λ°œμƒ μ‹œν‚¬ 수 μžˆμŠ΅λ‹ˆλ‹€.
      RectA & RectB μ΄λ ‡κ²Œ ν•˜λ©΄ μ€‘λ³΅λ˜λŠ” μ˜μ—­μ˜ rect값이 κ³„μ‚°λ©λ‹ˆλ‹€.
      κ·ΈλŸ¬λ‹ˆκΉ 제일 inbound ν•œ rectκ°€ λ§Œλ“€μ–΄ μ§€λŠ”λ°μš”..
      μ—¬κΈ°λ₯Ό μ°Έκ³ ν•˜μ„Έμš”.
      http://study.marearts.com/2014/09/opencv-tip-rect-bounding.html
      κ°μ‚¬ν•©λ‹ˆλ‹€.

      Delete