2012-06-04 2 views
5

Ich habe Video, wenn das Programm ausgeführt wird das erste Bild des Videos wird als ein Bild und der Benutzer darf ein Rechteck auf dem Bild, nachdem das Rechteck gezeichnet wird, zu zeichnen, Der Benutzer muss mit der rechten Maustaste auf das Bild klicken, um das Rechteck zu bestätigen. Wenn die Maus mit der rechten Maustaste geklickt wird, verschwindet das Bild und das Video beginnt mit dem gezeichneten Rechteck zu spielen.Einstellung ROI mit der Maus aus einem Rechteck auf einem Video

Ich kann das Rechteck perfekt zeichnen, aber ich kann dieses Rechteck nicht als ROI festlegen.

Was ich tun möchte, ist dieses Rechteck als Region of Interest (ROI) festlegen, um einige Bildverarbeitung auf dieser ROI zu tun. Ich kann das Rechteck, das ich als ROI zeichne, nicht festlegen.

Ich benutze OpenCV mit Visual Studio 2010. Später werde ich versuchen, dieses Programm in QT Creator zu integrieren.

Jede Hilfe würde geschätzt.

Vielen Dank im Voraus.

Mein vollständiger Code ist wie folgt:

#include <stdlib.h> 
#include <stdio.h> 
#include <math.h> 
#include <string.h> 
#include<opencv2\opencv.hpp> 
#include <opencv2\highgui\highgui.hpp> 
#include <opencv/highgui.h> 
#include <opencv/cxcore.h> 
#include <opencv\cvaux.h> 

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 < 0) 
     { 
      box.y += box.height; 
      box.height *= -1; 
     } 
     draw_box(image, box); 
     break; 
    case CV_EVENT_RBUTTONUP: 
     destroy=true; 
    } 
} 

int main() 
{ 
    const char* name = "Box Example"; 
    cvNamedWindow(name); 

    box = cvRect(0,0,1,1); 

    CvCapture* capture = cvCreateFileCapture("C:\\video.mp4"); 
    image = cvQueryFrame(capture); 

    IplImage* temp = cvCloneImage(image); 
// Set up the callback 
    cvSetMouseCallback(name, my_mouse_callback, (void*) image); 


//IplImage *img2 = cvCreateImage(cvGetSize(temp),temp->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; 
} 
+0

Wenn Sie sagen, Sie nicht in der Lage sind das Rechteck als ROI zu setzen, tun Sie Sie einen Fehlercode erhalten bedeuten? Kompiliert der Code? –

+0

Ja, ich habe einen Fehler erhalten, als ich auf das statische Bild geklickt habe. Es kompiliert korrekt aber –

Antwort

18

Sie fast da waren. Ein Problem jedoch: case CV_EVENT_RBUTTONUP muss break, und ich würde auch eine break auf default Fall hinzufügen.

Der folgende Code legt den ROI fest, führt eine einfache Graustufenverarbeitung durch und kopiert dann die verarbeitete ROI zurück in das ursprüngliche Bild.

Zu Testzwecken habe ich Ihren Code geändert, um meine Kamera zu verwenden, anstatt eine Datei zu laden.

Ausgang:

enter image description here

-Code:

#include <stdlib.h> 
#include <stdio.h> 
#include <math.h> 
#include <string.h> 

#include <cv.h> 
#include <highgui.h> 

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; 
} 
+1

** karlphillip vielen Dank. Du hast mich richtig verstanden. Was ich wollte. nochmals vielen Dank :) –

+0

Jetzt versuche ich den Code für die Eingabe von mehr als 1 ROIs zu bearbeiten. Mein Code akzeptiert nur einen ROI, wie Sie wissen. Irgendeine Idee, wie kann ich das tun? –

+0

Nicht im Moment, aber gehen Sie weiter und probieren Sie es selbst aus. Wenn Sie irgendwelche Probleme haben, kommen Sie zurück und stellen Sie eine neue Frage und informieren Sie mich auf Twitter, damit ich einen Blick darauf werfen kann. Viel Glück. – karlphillip