#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...
-
1.1.1. TẠO WEBSITE CHO NGƯỜI DÙNG Mô hình và yêu cầu bài tập Hướng dẫn thực hiện a. Tạo userdir 1) Khai báo Us...
-
Hướng dẫn sử dụng thư viện OpenCV 00:08 Computer Vision and Application OpenCV là một thư viện mã nguỗn mở rất mạnh hỗ trợ cho vi...
-
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...
-
Mathworks Matlab R2012a-ISO Mathworks Matlab R2012a-ISO - MATLAB® is a high-level technical computing language and in...
-
5.4. DỊCH VỤ WEB 5.4.1. GIỚI THIỆU WEB SERVER Apache là một phần mềm có nhiều tính năng mạnh và linh hoạt dùng để làm Web Server. - Hỗ tr...
-
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...
-
Cài đặt SMARTY LIBRARY Copy các file thư viện Smarty vào /usr/local/lib/php/Smarty/ $> cd YOUR_DOWNLOAD_DIRECTORY $> gtar -zxvf...
-
How to Convert an OGV File to AVI in Ubuntu February 6 You might have used Istanbul http://goo.gl/aHdeo or Recordmydesktop http:...
-
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...