Saturday, 14 May 2011

Handling mouse events

We can monitor the mouse movements to trigger different events, lets start with setting a ROI( Region Of Interest ) using the clicking of left mouse button.

The code is :

#include "cv.h"
#include "highgui.h"
CvPoint point;
int drag = 0;
void mouse_callback(int event, int x, int y, int flags, void* img)
{
  if (event == CV_EVENT_LBUTTONDOWN)
  {
    point = cvPoint(x, y);
    drag = 1;
  }
  else if (event == CV_EVENT_MOUSEMOVE && drag)
  {
    IplImage* img1 = cvCloneImage((IplImage*) img);
    cvRectangle(img1, point, cvPoint(x, y), CV_RGB(255, 0, 0), 1, 8, 0);
    cvShowImage("img", img1);
  }
  else if (event == CV_EVENT_LBUTTONUP)
  {
    drag = 0;
  }
}


int main()
{
 IplImage* img = cvLoadImage("C:/Users/amit/Desktop/myblog/ball detection/pan.jpg");

 cvNamedWindow("img", 1);
 
 cvSetMouseCallback("img", mouse_callback, img);
  cvShowImage("img", img);

  cvWaitKey(0);

  cvDestroyAllWindows();
  cvReleaseImage(&img);
return 0;
}

Explanation
What happens in this code is that when we click the left mouse, then the event is set to CV_EVENT_LBUTTONDOWN, which implies the pressing of left mouse button and the drag is set. Now on dragging the mouse with left button pressed, the rectangle is formed with corners, one end with where it was first clicked and where it is now.
When we release the left button, then the event is set to CV_EVENT_LBUTTONUP, and thus we get the ROI as required.

Application:

1.  It has a very good application. We can use it to track an object of a color let it be a ball like we described in previous tutorial. What we do is we select the ROI and thus find the ranges of HUE, SATURATION and VALUE for the ball color, and then using shape detection like before, we can detect ball.

The code is :

#include "cv.h"
#include "highgui.h"
#include <iostream>
using namespace std;
CvPoint point;
int drag = 0;
int hmin=180,hmax=0,smin=256,smax=0,vmin=256,vmax=0,cnt=0,xs,ys,xe,ye;
IplImage* frame = NULL;
void mouse_callback(int event, int x, int y, int flags, void* img)
{
  if (event == CV_EVENT_LBUTTONDOWN)
  {
    point = cvPoint(x, y);
    drag = 1;cnt=10;
    if(cnt==10)
    {xs=x;ys=y;}
  }
  else if (event == CV_EVENT_MOUSEMOVE && drag)
  {
    IplImage* img1 = cvCloneImage((IplImage*) img);
    //cvRectangle(img1, point, cvPoint(x, y), CV_RGB(255, 0, 0), 1, 8, 0);
    //cvShowImage("img", img1);
    cvRectangle(frame, point, cvPoint(x, y), CV_RGB(255, 0, 0), 1, 8, 0);
    cvShowImage("video", frame);
    if(cnt==10)
    {xe=x;ye=y;}
  }
  else if (event == CV_EVENT_LBUTTONUP)
  {
    drag = 0;
    if(cnt==10)
    {cnt=cnt+1;}
  }

}
main()
{
int i,j,xa,ya;
     CvCapture* capture = cvCaptureFromCAM( 0 );
     if( !capture )
     {
             fprintf( stderr, "ERROR: capture is NULL \n" );
             getchar();
             return -1;
     }
    cvNamedWindow("video", CV_WINDOW_AUTOSIZE);
    cvNamedWindow("colordetect", CV_WINDOW_AUTOSIZE);

frame = cvQueryFrame( capture );
    CvSize size = cvGetSize(frame);
 IplImage *  stor    = cvCreateImage(size, IPL_DEPTH_8U, 3);
     IplImage *  hsv_frame    = cvCreateImage(size, IPL_DEPTH_8U, 3);
     IplImage*  thresholded   = cvCreateImage(size, IPL_DEPTH_8U, 1);
//  IplImage* img = cvLoadImage("C:/Users/amit/Desktop/myblog/ball detection/pan.jpg");
  //cvNamedWindow("img", 1);
  while(1)
     {

        //capture image from cam
         frame = cvQueryFrame( capture );
        // stor=cvCloneImage(frame);
         if( !frame )
         {
                 fprintf( stderr, "ERROR: frame is null...\n" );
                 getchar();
                 break;
         }

cvSetMouseCallback("video", mouse_callback, frame);
cvShowImage("video", frame);
 //cvShowImage("colordetect", thresholded);
if(cnt==11)
{cnt=0;
  cvDestroyAllWindows();

  cvNamedWindow("video", CV_WINDOW_AUTOSIZE);
    cvNamedWindow("colordetect", CV_WINDOW_AUTOSIZE);
    cvCvtColor(frame, hsv_frame, CV_BGR2HSV);

for(xa=xs+1;xa<xe;xa++)
{
for(ya=ys+1;ya<ye;ya++)
{
CvScalar s=cvGet2D(hsv_frame,xa,ya);
if(hmin > s.val[0])
{hmin = s.val[0];}
if(hmax < s.val[0])
{hmax = s.val[0];}

if(smin > s.val[1])
{smin = s.val[1];}

if(smax < s.val[1])
{smax = s.val[1];}
if(vmin > s.val[2])
{vmin = s.val[2];}

if(vmax < s.val[2])
{vmax = s.val[2];}
cout<<s.val[0]<<endl;

}
}
cout<<"thresholded"<<endl;
cout<<hmax<<"  "<<hmin<<endl;
cout<<smax<<"  "<<smin<<endl;
cout<<vmax<<"  "<<vmin<<endl;

 CvScalar hsv_min = cvScalar(hmin, smin, vmin, 0);
    CvScalar hsv_max =  cvScalar(hmax, smax, vmax, 0);
    while(1)
    {
        frame = cvQueryFrame( capture );
        if( !frame )
         {
                 fprintf( stderr, "ERROR: frame is null...\n" );
                 getchar();
                 break;
         }
         cvCvtColor(frame, hsv_frame, CV_BGR2HSV);
        //color detection
        cvInRangeS(hsv_frame, hsv_min, hsv_max, thresholded);
         // Memory for hough circles
        // CvMemStorage* storage = cvCreateMemStorage(0);
        cvSmooth( thresholded, thresholded, CV_GAUSSIAN, 11, 11 );
CvMemStorage* storage = cvCreateMemStorage(0);
        //shape detection-circle shape
         CvSeq* circles = cvHoughCircles(thresholded, storage, CV_HOUGH_GRADIENT, 2,thresholded->height/6, 100, 50, 10, 400);
         cout<<"no. of circles="<<circles->total;
         //drawing circle around the detected circle
         for (int i = 0; i < circles->total; i++)
         {
             float* p = (float*)cvGetSeqElem( circles, i );
             cout<<"x= "<<p[0]<<"y= "<<p[1]<<"r= "<<p[2]<<endl;
             cvCircle( frame, cvPoint(cvRound(p[0]),cvRound(p[1])),cvRound(p[2]), CV_RGB(255,0,0), 3, 8, 0 );
         }

 cvShowImage("video", frame);
 cvShowImage("colordetect", thresholded);
  cvReleaseMemStorage(&storage);
        if( (cvWaitKey(10) & 255) == 27 ) { //hmin=180,hmax=0,smin=256,smax=0,vmin=256,vmax=0;
            break;}
        }

    }

  if( (cvWaitKey(10) & 255) == 27 ) break;
     }
cvReleaseCapture( &capture );
  cvDestroyAllWindows();
  //cvReleaseImage(&);
}





2.  U can make ur Pong game in OpenCV. U can check out this video in youtube:
http://www.youtube.com/watch?v=abusTzgsYYM 

No comments:

Post a Comment