#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...
-
Mathworks Matlab R2012a-ISO Mathworks Matlab R2012a-ISO - MATLAB® is a high-level technical computing language and in...
-
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...
-
1.1.1. CẤU HÌNH FTP SERVER Mô hình và yêu cầu hệ thống Cấu hình cho phép người dùng anonymous và local user upload dữ liệu lên ...
-
1.1. DỊCH VỤ FTP 1.1.1. GIỚI THIỆU FTP FTP được viết tắt từ chuỗi File Transfer Protocol. Giao thức này được xây dựng ...
-
1.1.1. THỰC HÀNH 1: CẤU HÌNH APACHE WEB SERVER MÔ HÌNH VÀ YÊU CẦU BÀI TẬP MÔ HÌNH HOẠT ĐỘNG Kiểm tra nội ...
-
The OpenMP framework is a powerful way of doing concurrent programming in C, C++, and Fortran. The GNU Compiler Collection (GCC) version 4....
-
How to Install Canon LBP Printers in Ubuntu MAR 20 TH , 2010 UPDATE 4 : Version 2.4 added support for printer models LBP6000 and LBP6...
-
Phát hiện mặt người dựa trên các đặc trưng Haar-like 02:00 Computer Vision and Application Phát hiện mặt người là bài toán cơ bản...