/* * set your OS! * * in order to include the correct files... */ //#define WINDOWS_OS #define MAC_OS /* * include files for Mac OS X */ #ifdef MAC_OS #include #include #include #include #include #include #include // for memset #include #include #include #include #include #include #include using namespace std; //#define ROOT_FOLDER "/Users/bfsnet/Desktop/SetWithOpenCV/" //#define ROOT_FOLDER "/Users/dodds/Desktop/SetWithOpenCV/" #define ROOT_FOLDER "/Users/jarthur/Desktop/SetWithOpenCV/" #endif #include "mainHelper.h" /* * global data for passing among * the main loop (in main) * the mouse-event handler (in mouseEventHandler) * the server (in runServerThread) */ IplImage *inputImage=0; // shared between mouse events and main loop int swapVerticalValues = 0; // shared between mouse events and main loop int drawingRectangle=0; // shared between mouse events and main loop CvPoint origin; // more rectangle-selection data CvRect selection; int runAlgorithm = 0; // shared between server and main loop int timeToQuitNow = 0; // shared between server and main loop ColorDefinition currentColor; // shared among mouse events, server, and main loop #include "serverStuff.h" /* * Mouse-event handling routine */ void mouseEventHandler( int event, int x, int y, int flags, void* param ) { int r,g,b; if ( !inputImage ) return; // no image, do nothing if (swapVerticalValues) y = inputImage->height - y; // platform-dependent! if ( event == CV_EVENT_MOUSEMOVE && drawingRectangle ) // are we pulling the corner of a rectangle? { // handle the geometry of the rectangle: selection.x = MIN(x,origin.x); selection.y = MIN(y,origin.y); selection.width = MIN( selection.x + CV_IABS(x - origin.x), inputImage->width ) - MAX( selection.x, 0 ); selection.height = MIN( selection.y + CV_IABS(y - origin.y), inputImage->height ) - MAX( selection.y, 0 ); } // end of rectangle-drawing if ( event == CV_EVENT_RBUTTONDOWN ) // did we right-click (or control-click?) { getrgb( inputImage, x, y, r, g, b ); printf(" right-click at (%d,%d): rgb=(%d,%d,%d)\n", x, y, r, g, b ) ; int N = 10; // acceptable color width currentColor.expandToFit( r+N, g+N, b+N ); // box of side 2N: upper corner currentColor.expandToFit( r-N, g-N, b-N ); // and lower corner currentColor.print(); } if ( event == CV_EVENT_LBUTTONDOWN ) // did we left-click? { if (!drawingRectangle) // if we weren't drawing, now we start drawing a rectangle { origin = cvPoint(x,y); selection = cvRect(x,y,1,1); drawingRectangle = 1; } else // if we were drawing a rectangle, now we're finished drawing it { currentColor.reset(); for ( int col=selection.x ; col<=selection.x+selection.width ; ++col) { for ( int row=selection.y ; row<=selection.y+selection.height ; ++row) { getrgb( inputImage, col, row, r, g, b ); currentColor.expandToFit( r, g, b ); } } currentColor.print(); drawingRectangle = 0; } } } // end of mouse event handler /* * MAIN */ int main( int argc, char** argv ) { /* * set up vision server */ int runServer = false; #ifdef MAC_OS pthread_t serverThread; // the identifier for the thread if (runServer) // do we want to run the server? { printf("Creating serverThread.\n"); int rc = pthread_create(&serverThread, NULL, runServerThread, NULL); if (rc) printf("ERROR in pthread_create: %d.\n", rc); } #endif /* * set up image input source */ enum { IMAGES_FROM_CAMERA, IMAGES_FROM_FOLDER, IMAGES_FROM_AVI_FILE }; int captureType = IMAGES_FROM_FOLDER; char* MOVIE_NAME = ROOT_FOLDER "path0.mpg"; char* FOLDER_NAME = ROOT_FOLDER "SetImages"; int MAX_FILE_NUMBER = 81; // the number of images in the folder int nextFileNumber = 0; // the next file number to read enum { LIVE, ONEFRAME, STILL }; // how are we now capturing int captureStatus = ONEFRAME; CvCapture* capture = 0; // the capture object to grab frames from a camera/avi file if ( captureType == IMAGES_FROM_CAMERA ) // initialize "capture," the image source capture = cvCaptureFromCAM( 0 ); // camera number zero, which is usually the one attached else if ( captureType == IMAGES_FROM_AVI_FILE ) capture = cvCaptureFromAVI( MOVIE_NAME ); else // captureType = IMAGES_FROM_FOLDER; capture = 0; /* * create windows for displaying images */ cvNamedWindow( "InputImage", CV_WINDOW_AUTOSIZE ); cvMoveWindow( "InputImage", 100, 100 ); cvSetMouseCallback( "InputImage", mouseEventHandler, 0 ); cvNamedWindow( "OutputImage", CV_WINDOW_AUTOSIZE ); cvMoveWindow( "OutputImage", 440, 100 ); /* * create an initial image, displayImage, and any other images... */ inputImage = cvCreateImage( cvSize(10,10), 8, 1 ); IplImage* outputImage = NULL; IplImage* frame = NULL; // image grabbed from camera /* * blob handling */ CBlobResult blobs; CBlob blobToShow; /* * MAIN LOOP */ while (!timeToQuitNow) { /* * INPUT IMAGE SETUP * * the goal here is to populate the _image_ variable with pixels * depending on the source in captureType */ if (captureStatus != STILL) { if (captureType == IMAGES_FROM_FOLDER) { char filename[255]; if (nextFileNumber > MAX_FILE_NUMBER || nextFileNumber < 0) nextFileNumber = 0; sprintf(filename,"%s/image%05d.bmp", FOLDER_NAME, nextFileNumber++); inputImage = cvLoadImage(filename, -1); // -1 means determine number of channels from format } else // captureType == IMAGES_FROM_AVI_FILE or IMAGES_FROM_CAMERA { frame = cvQueryFrame( capture ); if ( !frame ) { printf( "Frame not obtained when capturing!\n"); printf( "Setting captureStatus to STILL.\n"); captureStatus = STILL; } else // set up the destination image, if needed { CvSize frameSize = cvGetSize(frame); if ( frameSize.width != inputImage->width || frameSize.height != inputImage->height ) { cvReleaseImage( &inputImage ); inputImage = cvCreateImage( frameSize, 8, 3 ); inputImage->origin = frame->origin; } // image is OK and the right size, now cvCopy( frame, inputImage, 0 ); // copy the frame data into the image } } if (captureStatus == ONEFRAME) captureStatus = STILL; // we got our one frame... // now, we keep that image until an event asks to grab a new one } /* * OUTPUT IMAGE SETUP * * we need to make sure to set up the output images before processing! * (or other intermediate images) we check to be sure they're the right size... */ if ( outputImage == NULL || ( inputImage->width != outputImage->width || inputImage->height != outputImage->height ) ) { if (outputImage) cvReleaseImage( &outputImage ); outputImage = cvCreateImage( cvGetSize(inputImage), 8, 3 ); } cvCopy(inputImage, outputImage, NULL); // copy input to output image as a starting point for outputImage /* * OUR ALGORITHM/PROCESSING/VISUALIZATION */ if (runAlgorithm) { int b,r,g; // loop over the input image for ( int col=0 ; colwidth ; ++col) { for ( int row=0 ; rowheight ; ++row) { getrgb( inputImage, col, row, r, g, b ); if ( currentColor.pixelMatch( r, g, b ) ) setrgb( outputImage, col, row, 0, 255, 0 ); } // end row } // end col } /* * DRAW THE IMAGES TO SCREEN */ if (drawingRectangle) // shows a yellow rectangle when selecting a region cvRectangle(outputImage, cvPoint(selection.x,selection.y), // from here cvPoint(selection.x+selection.width, selection.y+selection.height), // to here CV_RGB(255,255,0),1,8,0); // yellow, 1 pixel thick, 8-connected cvShowImage( "InputImage", inputImage ); // render the input image cvShowImage( "OutputImage", outputImage ); // render the output image /* * HANDLE KEY PRESSES to an OpenCV window */ char cchar = (char) cvWaitKey(10); // waits for 10 ms to get a keypress // use cvWaitKey(0) in order to wait forever... if ( cchar == 27 ) break; // breaks on ESCape key switch( cchar ) // handle other key presses { case ' ': // stop and get one more frame { captureStatus = ONEFRAME; runAlgorithm = true; break; } case 'L': // restart live capturing { captureStatus = LIVE; printf("Getting one frame.\n"); break; } case 'R': // reset the current color definition { currentColor.reset(); } case 'O': // save params to File { currentColor.saveToFile( ROOT_FOLDER "colordef.txt" ); break; } case 'I': // get params from file { currentColor.loadFromFile( ROOT_FOLDER "colordef.txt" ); break; } case 'A': // turn on or off algorithm running { if (runAlgorithm) runAlgorithm = false; else runAlgorithm = true; break; } default: break; } // end of the keypress-handling switch statement } // end of the main image input - process - output loop /* * If we're here, some event triggered the main loop to quit */ timeToQuitNow = 1; // set our signal for the serverThread to quit printf("Main thread quitting...\n"); #ifdef MAC_OS sleep(1.0); // give it a moment... #endif #ifdef WINDOWS_OS Sleep(1000); #endif /* * release the OpenCV resources */ cvReleaseCapture(&capture); cvDestroyWindow( "InputImage" ); cvDestroyWindow( "OutputImage" ); return 0; }