Impostazione della ROI con il mouse da un rettangolo su un video

Ho un video, quando il programma viene eseguito il primo fotogramma del video viene preso come immagine e l’utente può disegnare un rettangolo sull’immagine, dopo che il rettangolo è stato disegnato, l’utente deve fare clic con il pulsante destro del mouse sull’immagine per confermare il rettangolo. Quando il mouse fa clic destro sull’immagine scompare e il video inizia a giocare con il rettangolo disegnato su di esso.

Sono in grado di disegnare perfettamente il rettangolo ma non posso impostare quel rettangolo come ROI.

Quello che voglio fare è impostare quel rettangolo come Regione di interesse (ROI) per fare un po ‘di elaborazione delle immagini su quel ROI. Non riesco a impostare il rettangolo che disegno come ROI.

Sto usando OpenCV con Visual Studio 2010. In seguito proverò ad integrare questo programma in QT creator.

Qualsiasi aiuto sarebbe apprezzato.

Grazie in anticipo.

Il mio codice completo è il seguente:

#include  #include  #include  #include  #include #include  #include  #include  #include  using namespace cv; using namespace std; void my_mouse_callback( int event, int x, int y, int flags, void* param ); bool destroy=false; CvRect box; IplImage* image; IplImage* frame2; bool drawing_box = false; void draw_box( IplImage* img, CvRect rect) { cvRectangle( img, cvPoint(box.x, box.y), cvPoint(box.x+box.width,box.y+box.height), cvScalar(0,0,255) ,2); CvRect rect2=cvRect(box.x,box.y,box.width,box.height); //cvSetImageROI(image, rect2); //here I wanted to set the drawn rect as ROI } // Implement mouse callback void my_mouse_callback( int event, int x, int y, int flags, void* param ){ IplImage* image = (IplImage*) param; switch( event ){ case CV_EVENT_MOUSEMOVE: if( drawing_box ) { box.width = x-box.x; box.height = y-box.y; } break; case CV_EVENT_LBUTTONDOWN: drawing_box = true; box = cvRect( x, y, 0, 0 ); break; case CV_EVENT_LBUTTONUP: drawing_box = false; if( box.width < 0 ) { box.x += box.width; box.width *= -1; } if( box.height depth,temp->nChannels); //cvNot(temp,temp); /* copy subimage */ //cvCopy(temp, temp, NULL); // Main loop while( 1 ) { if(destroy) {cvDestroyWindow(name); break;} cvCopyImage( image, temp ); if( drawing_box ) draw_box( temp, box ); cvMoveWindow(name, 200, 100); cvShowImage( name, temp ); if( cvWaitKey( 15 )==27 ) break; } //cvReleaseImage( &image ); cvReleaseImage( &temp ); cvDestroyWindow( name ); cvNamedWindow( "Example2", CV_WINDOW_AUTOSIZE ); cvMoveWindow("Example2", 150, 150); while(1) { frame2 = cvQueryFrame( capture ); draw_box(frame2,box); if( !frame2 ) break; cvShowImage( "Example2", frame2 ); char c = cvWaitKey(33); if( c == 27 ) break; } cvReleaseCapture( &capture ); cvDestroyWindow( "Example2" ); return 0; } 

Eri quasi lì. Un problema però: case CV_EVENT_RBUTTONUP bisogno di break , e vorrei anche aggiungere una break sul caso default .

Il codice seguente imposta la ROI, esegue una semplice elaborazione in scala di grigi su di essa e quindi copia la ROI elaborata nuovamente sull’immagine originale.

A scopo di test ho cambiato il tuo codice per usare la mia macchina fotografica invece di caricare un file.

Uscita :

inserisci la descrizione dell'immagine qui

Codice :

 #include  #include  #include  #include  #include  #include  using namespace cv; using namespace std; void my_mouse_callback( int event, int x, int y, int flags, void* param ); bool destroy=false; CvRect box; bool drawing_box = false; void draw_box(IplImage* img, CvRect rect) { cvRectangle(img, cvPoint(box.x, box.y), cvPoint(box.x+box.width,box.y+box.height), cvScalar(0,0,255) ,2); CvRect rect2=cvRect(box.x,box.y,box.width,box.height); //cvSetImageROI(image, rect2); //here I wanted to set the drawn rect as ROI } // Implement mouse callback void my_mouse_callback( int event, int x, int y, int flags, void* param ) { IplImage* frame = (IplImage*) param; switch( event ) { case CV_EVENT_MOUSEMOVE: { if( drawing_box ) { box.width = x-box.x; box.height = y-box.y; } } break; case CV_EVENT_LBUTTONDOWN: { drawing_box = true; box = cvRect( x, y, 0, 0 ); } break; case CV_EVENT_LBUTTONUP: { drawing_box = false; if( box.width < 0 ) { box.x += box.width; box.width *= -1; } if( box.height < 0 ) { box.y += box.height; box.height *= -1; } draw_box(frame, box); } break; case CV_EVENT_RBUTTONUP: { destroy=true; } break; default: break; } } int main() { const char* name = "Box Example"; cvNamedWindow( name ); box = cvRect(0,0,1,1); CvCapture* capture = cvCaptureFromCAM(0); if (!capture) { printf("!!! Failed cvCaptureFromCAM\n"); return 1; } IplImage* image = cvQueryFrame(capture); if (!image) { printf("!!! Failed cvQueryFrame #1\n"); return 2; } IplImage* temp = cvCloneImage(image); // Set up the callback cvSetMouseCallback(name, my_mouse_callback, (void*) image); // Main loop while( 1 ) { if (destroy) { cvDestroyWindow(name); break; } cvCopyImage(image, temp); if (drawing_box) draw_box(temp, box); cvMoveWindow(name, 200, 100); cvShowImage(name, temp); if (cvWaitKey(15) == 27) break; } cvReleaseImage(&temp); cvDestroyWindow(name); cvNamedWindow("Example2", CV_WINDOW_AUTOSIZE); cvMoveWindow("Example2", 150, 150); // Retrieve a single frame from the device and set the ROI IplImage* vid_frame = cvQueryFrame(capture); if (!vid_frame) { printf("!!! Failed cvQueryFrame #2\n"); return 2; } cvSetImageROI(vid_frame, box); // Allocate space for a single-channel ROI (to store grayscale frames) IplImage* gray_roi = cvCreateImage(cvSize(box.width, box.height), IPL_DEPTH_8U, 1); IplImage* rgb_roi = cvCreateImage(cvSize(box.width, box.height), IPL_DEPTH_8U, 3); while(1) { if (!vid_frame) { vid_frame = cvQueryFrame(capture); if (!vid_frame) { printf("!!! Failed cvQueryFrame #3\n"); break; } } draw_box(vid_frame, box); // Set ROI and perform some processing (in this case, converting the ROI to grayscale) cvSetImageROI(vid_frame, box); cvCvtColor(vid_frame, gray_roi, CV_BGR2GRAY); //cvShowImage("Example2", gray_roi); /* At this point gray_roi has the size of thei ROI and contains the processed image. * For fun, we copy the processed image back to the original image and display it on the screen! */ cvCvtColor(gray_roi, rgb_roi, CV_GRAY2BGR); // As the ROI is still set, cvCopy is affected by it cvCopy(rgb_roi, vid_frame, NULL); // Now reset the ROI so cvShowImage displays the full image cvResetImageROI(vid_frame); cvShowImage("Example2", vid_frame); char c = cvWaitKey(33); if( c == 27 ) break; vid_frame = NULL; } cvSaveImage("processed.jpg", vid_frame); cvReleaseImage(&gray_roi); cvReleaseImage(&rgb_roi); cvReleaseCapture( &capture ); cvDestroyWindow( "Example2" ); return 0; }