#include <stdio.h> #include <cv.h> #include <highgui.h> //Function declarations void onMouse(int event, int x, int y, int flags, void *param); //This will be called when the user performs a mouse action. CvContour* contourFromPosition(CvContour *contours, int x, int y); //Returns a pointer to the inner-most contour surrounding the given point char pointIsInsideContour(CvContour *contour, int x, int y); //Returns whether the given position is inside a contour int main (int argc, const char * argv[]) { // exit main program loop? char quit = 0; char grab_frame = 1; // allocated memory CvMemStorage *storage = cvCreateMemStorage(0); CvSeq *contours = 0; // initializes camera CvCapture *camera = cvCreateCameraCapture(0); if(!camera){ printf("Could not find a camera to capture from...\n"); return -1; } // get the video image size IplImage *imgsize; imgsize = cvQueryFrame( camera ); if( !imgsize ) return -1; // get a buffer image that is the same size as img1 and 2 IplImage *imggray1 = cvCreateImage( cvGetSize( imgsize ), IPL_DEPTH_8U, 1); IplImage *imggray2 = cvCreateImage( cvGetSize( imgsize ), IPL_DEPTH_8U, 1); IplImage *imggray3 = cvCreateImage( cvGetSize( imgsize ), IPL_DEPTH_8U, 1); IplImage *imgcross = cvCreateImage( cvGetSize( imgsize ), IPL_DEPTH_8U, 1); // create a window cvNamedWindow("Video", 0); // define kernal for image smoothing IplConvKernel *kernel = cvCreateStructuringElementEx(3, 3, 1, 1, CV_SHAPE_CROSS, NULL); // set the mouse callback function. cvSetMouseCallback("Video", onMouse, (void*) &contours); // exit the loop when the user sets quit to true by pressing the "esc" key while(!quit){ int c = cvWaitKey(30); //Wait 30 ms for the user to press a key. //Respond to key pressed. switch(c){ case 32: //Space grab_frame = !grab_frame; //Reverse the value of grab_frame. That way, the user can toggle by pressing the space bar. break; case 27: //Esc: quit application when user presses the 'esc' key. quit = 1; //Get out of loop break; }; //If we don't have to grab a frame, we're done for this pass. if(!grab_frame)continue; //Grab a frame from the camera. IplImage *img1 = cvQueryFrame(camera); if(!img1)continue; // convert from RGB to greyscale cvCvtColor(img1, imggray1, CV_RGB2GRAY); //Grab 2nd frame from the camera. IplImage *img2 = cvQueryFrame(camera); if(!img2)continue; // convert from RGB to greyscale before processing further. cvCvtColor(img2, imggray2, CV_RGB2GRAY); // compute difference cvAbsDiff( imggray1, imggray2, imggray3 ); // convert to bw IplImage* imgbw = cvCreateImage(cvGetSize(imggray3),IPL_DEPTH_8U,1); cvThreshold(imggray3, imgbw, 16, 255, CV_THRESH_BINARY); // apply convolution kernalwhiq cvMorphologyEx( imgbw, imgcross , NULL , kernel, CV_MOP_OPEN, 1); // find connected components cvFindContours(imgcross, storage, &contours, sizeof(CvContour), CV_RETR_TREE, CV_CHAIN_APPROX_NONE, cvPoint(0,0)); // Create a clone for contour coloring, or else, contours will be 0 at the end CvSeq *contours_replica = contours; // loop through all contours found for( ; contours_replica != 0; contours_replica = contours_replica->h_next ) { // draw contours area CvScalar color = CV_RGB( rand()&255, rand()&255, rand()&255 ); cvDrawContours( img1, contours_replica, color, color, -1, CV_FILLED, 8 ); CvRect r1 = cvBoundingRect(contours_replica, 1); // get the centroid of the contour CvPoint point = cvPoint( r1.x + (r1.width / 2), r1.y + (r1.height / 2) ); //fprintf(stderr, "x: %d y:%d\n", r1.x, r1.y); // draw circle on centroid // cvDrawCircle ( img1, point, 10, CV_RGB(255,0,0), 1, 8, 0 ) cvRectangle(img1, cvPoint(r1.x, r1.y), cvPoint((r1.x + r1.width),(r1.y + r1.height)), CV_RGB(255,0,0), 1, 8, 0); } // display the image in the window. cvShowImage("Video", img1); } //Clean up before quitting. cvDestroyAllWindows(); //Release the camera cvReleaseCapture(&camera); //release memory cvReleaseMemStorage(&storage); //Release images cvReleaseImage(&imggray1); cvReleaseImage(&imggray2); cvReleaseImage(&imggray3); cvReleaseImage(&imgcross); return 0; } // when clicks happen in window void onMouse(int event, int x, int y, int flags, void *param){ CvContour *contours = *(CvContour **)param; CvContour *ctr; // point to the specific contour the user clicked double area; // hold the area of the contour the user clicked // do not proceed if there is no contour if(!contours)return; //printf("contours: %d", contours); //"event" tells us what occured switch(event){ case CV_EVENT_LBUTTONDOWN: //single click case CV_EVENT_LBUTTONDBLCLK: //double click printf("Click: %d %d\n",x,y); //Write out where the user clicked. //Check if user click in contour ctr = contourFromPosition(contours, x, y); // if user did click inside contour if(ctr){ //Calculate the area of the contour. area = fabs(cvContourArea(ctr, CV_WHOLE_SEQ, 0)); printf("Area: %f\n",area); } break; } } CvContour* contourFromPosition(CvContour *contours, int x, int y){ CvContour *contour; CvContour *tmpContour=0, *output=0; // do not proceed if there is no contour if(!contours)return 0; // points to the first contour in the list contour = contours; while(contour){ // check if the point the user clicked on is inside the current contour, if yes... if(pointIsInsideContour(contour, x, y)){ output = contour; // check all the contours if(contour->v_next){ tmpContour = contourFromPosition((CvContour *)contour->v_next,x,y); if(tmpContour)output = tmpContour; } } // move to the following contour contour = (CvContour *)(contour->h_next); } return output; } // returns whether the (x,y) point is inside the given contour. char pointIsInsideContour(CvContour *contour, int x, int y){ //We know that a point is inside a contour if we can find one point in the contour that is immediately to the left, //one that is immediately on top, one that is immediately to the right and one that is immediately below the (x,y) point. //We will update the boolean variables below when these are found: char found_left=0, found_top=0, found_right=0, found_bottom=0; int count, i; CvPoint *contourPoint; // do not proceed if there is no contour if(!contour)return 0; count = contour->total; //The total field holds the number of points in the contour. for(i=0;i<count;i++){ //So, for every point in the contour... //We retrieve a pointer to the point at index i using the useful macro CV_GET_SEQ_ELEM contourPoint = (CvPoint *)CV_GET_SEQ_ELEM(CvPoint,contour,i); if(contourPoint->x == x){ //If the point is on the same vertical plane as (x,y)... if(contourPoint->y < y)found_top = 1; //and is above (x,y), we found the top. else found_bottom = 1; //Otherwise, it's the bottom. } if(contourPoint->y == y){ //Do the same thing for the horizontal axis... if(contourPoint->x < x)found_left = 1; else found_right = 1; } } return found_left && found_top && found_right && found_bottom; //Did we find all four points? }
7/1/12
Mouse event in OpenCV C++ is tough~
Was being frustrated last two days as I was having problems with cvSetMouseCallback in OpenCV. Thanks so much to Jean-Marc Pelletier, finally, the work-in-progress code is grabbing user click CvPoint(x,y), able to pass *param and check if the point resides in a contour.
Bài đăng phổ biến
-
1.1.1. THỰC HÀNH 4: THIẾT LẬP FORUM SỬ DỤNG PHP VÀ MYSQL Cài đặt MyBB Gói mã nguồn mở được cung cấp hoàn toàn miễn phí tại tran...
-
filed in Computers , Lattice Boltzmann Method , Personal on Jan.29, 2010 MPI in CodeBlocks Codeblocks is great application devel...
-
this posting is modified from http://aganse.blogspot.com/2012/05/installing-g77-on-ubuntu-1004-1110.html However, g77 is no longer being m...
-
For a small robot project I'm working on I needed a way to measure the robot's progress across the floor. There are various poss...
-
The OpenMP framework is a powerful way of doing concurrent programming in C, C++, and Fortran. The GNU Compiler Collection (GCC) version 4....
-
Step 1: Download and install Codeblocks and choose the default GNU GCC compiler. Step 2: Create a new test project. To ensure the openmp ...
-
Hướng dẫn cài đặt thư viện Open MPI - Cài đặt Open MPI: Download bản mới nhất của Open MPI openmpi-1.2.3.tar.gz tại : http://ww...
-
1.1. CẤU HÌNH TRUY CẬP TCP WRAPPER a) Cài đặt TCP Wrapper [root@linux ~]# yum -y install tcp_wrappers b) Kiểm t...
-
verview Building the SAGE software on Linux requires various tweaks, depending on the distribution being used. The necessary steps to bui...
-
Phần mềm học anh văn hiệu quả | Longman Dictionary of Contemporary English 5th Edition [Từ điển anh ngữ] Longman Dictionary of Co...