Runtime ROI Selection using Mouse

Oct 14, 2009 | Tags: OpenCV | del.icio.us del.icio.us | digg Digg

A few days ago, a reader ask me about selecting ROI using mouse. I thought that such a code would be useful so I wrote the code below. It loads an image, and you define the ROI by dragging your mouse.

Listing 1: Runtime ROI Selection using Mouse

  1. #include <stdio.h>
  2. #include "cv.h"
  3. #include "highgui.h"
  4.  
  5. IplImage* img0, * img1;
  6. CvPoint   point;
  7. int       drag = 0;
  8.  
  9. void
  10. mouseHandler(int event, int x, int y, int flags, void* param)
  11. {
  12.     /* user press left button */
  13.     if (event == CV_EVENT_LBUTTONDOWN && !drag)
  14.     {
  15.         point = cvPoint(x, y);
  16.         drag  = 1;
  17.     }
  18.  
  19.     /* user drag the mouse */
  20.     if (event == CV_EVENT_MOUSEMOVE && drag)
  21.     {
  22.         img1 = cvClone(img0);
  23.        
  24.         cvRectangle(
  25.             img1,
  26.             point,
  27.             cvPoint(x, y),
  28.             CV_RGB(255, 0, 0),
  29.             1, 8, 0
  30.         );
  31.        
  32.         cvShowImage("img", img1);
  33.     }
  34.  
  35.     /* user release left button */
  36.     if (event == CV_EVENT_LBUTTONUP && drag)
  37.     {
  38.         img1 = cvClone(img0);
  39.        
  40.         cvSetImageROI(
  41.             img1,
  42.             cvRect(
  43.                 point.x,
  44.                 point.y,
  45.                 x - point.x,
  46.                 y - point.y
  47.             )
  48.         );
  49.        
  50.         cvNot(img1, img1);    // or do whatever with the ROI
  51.        
  52.         cvResetImageROI(img1);
  53.         cvShowImage("img", img1);
  54.         drag = 0;
  55.     }
  56.  
  57.     /* user click right button: reset all */
  58.     if (event == CV_EVENT_RBUTTONUP)
  59.     {
  60.         cvShowImage("img", img0);
  61.         drag = 0;
  62.     }
  63. }
  64.  
  65. int
  66. main(int argc, char** argv)
  67. {
  68.     if (argc != 2)
  69.     {
  70.         fprintf(stderr, "Usage: %s <image>\n", argv[0]);
  71.         return 1;
  72.     }
  73.  
  74.     img0 = cvLoadImage(argv[1], 1);
  75.  
  76.     cvNamedWindow("img", 1);
  77.     cvSetMouseCallback("img", mouseHandler, NULL);
  78.     cvShowImage("img", img0);
  79.     cvWaitKey(0);
  80.     cvDestroyWindow("img");
  81.     cvReleaseImage(&img0);
  82.     cvReleaseImage(&img1);
  83.  
  84.     return 0;
  85. }
  86.  

Some final notes: you define the ROI by dragging the mouse from the upper left corner to the bottom right corner. Otherwise it generates errors. I will leave you to fix the bugs.

Update on April 14th, 2010:

Compiling the code above using C++ compiler generates error:

error C2440: '=' : cannot convert from 'void *' to 'IplImage *'
1> Conversion from 'void*' to pointer to non-'void' requires an explicit cast

This is because cvClone() at line 22 and 38 returns void* while img1 is type of IplImage*. To fix this bug, simply replace:

img1 = cvClone(img0)

with:

img1 = cvCloneImage(img0)

Thanks to sycluap for reporting this.

Related Articles

Recommended Book

9 Comments

sycluap on Apr 14, 2010:

Hi, good tutorial over there!
Tried on this Runtime ROI selection using mouse, but encounter error:

error C2440: '=' : cannot convert from 'void *' to 'IplImage *'
Conversion from 'void*' to pointer to non-'void' requires an explicit cast

Tried for a long time, but no clue. Appreciate if you can enlighten me on this matter. Thanks!

Nash on Apr 14, 2010:

Replace the code at line 22 and 38:

img1 = cvClone(img0);

with this:

img1 = cvCloneImage(img0);

sycluap on Apr 15, 2010:

Hi Nash,

Thanks for the response. It works.

sycluap on Apr 15, 2010:

Hi Nash,

Tried on the sample program, and would like to know further how do I be able to utilize the ROI selected and act as a template for matching on continuous predefined time interval image captured from webcam, to detect the image differences?

Christine X on Apr 17, 2010:

Hi Mr Nash,

can you please help me in a project that i have in opencv?i have tried everything i know and didn't work out.well,i have an image (capture from a video sequence) and there is a curve on it.i mark the curve with the mouse manually at the first frame and i save its points in an array and i want opencv to locate it automatically at the next frames since it is moving and it is in a different location every time.

i would really appreciate it if you could please enlighten me with a useful idea on how i could do this because i'm really desparate!

well,thnx in advance!i'm waiting for your answer impatiently!

Nash on Apr 19, 2010:

Try template matching.

mithun on Jul 23, 2010:

Hi,Nash
I am working on hand gesture recognition.I am able to substract hand pulm from background using color segmentation.Now i have to track it.for that i have to make a bounding box over segmented region.Please help me on that.

Kilo Foxtrot on Aug 9, 2010:

AAAARGH I've been searching for this !!!

Thank you thank you thank you Brother Nash !!!!

Jazakullah. Terima kasih.

Kyaw on Nov 26, 2010:

Hi Nash,


Thank you for your lots of contribution here. I am searching the ways to get the distances between mouse events however I couldn't manage to solve.

Pls advise me and I am looking forward to hearing from you since I am in rush in my demo.


Thanks and best regards


Leave a comment

Name (required)
Email (will not be published) (required)
Website

Characters left = 1000