Ask Your Question
0

Using mouse to paint an area of video with OpenCV

asked 2013-08-27 09:12:14 -0600

Michele gravatar image

Hi!

I want to paint an area of my video using mouse when the video is paused, but I'm having a little problem. When I pause the video and try to paint a region, the painted area only appears after I press any key on my keyboard (which is not implemented it). I wonder what I could do to the painted area appears when I press the mouse button?

Thank you, : )

My code:

//mouse callback
void rotina_mouse(int event, int x, int y, int flags, void* param);
bool continua = false;

//function to paint
void pinta(IplImage* image, int x, int y){
     cvFloodFill (image, cvPoint (x,y), cvScalar(103), cvScalarAll(2), cvScalarAll(2), 0, CV_FLOODFILL_FIXED_RANGE , 0);
}

//main program
int _tmain(int argc, _TCHAR* argv[])
{
    cvNamedWindow ("saida", CV_WINDOW_AUTOSIZE);
    CvCapture* g_capture  = cvCreateFileCapture ("vid.avi");
    IplImage* frame = cvQueryFrame(g_capture);
    IplImage* temp = cvCloneImage( frame );
    cvSetMouseCallback("saida",rotina_mouse,(void*) frame);

    while(1){

        frame = cvQueryFrame(g_capture);    
        cvNot(frame, frame);
        cvCopyImage( frame, temp );
        cvShowImage("saida", temp);

        if(!frame) break;

        //pause with 'p'
        char e = cvWaitKey(33);
        if(e==112){

        while(1){
            cvCopyImage( frame, temp );
            cvShowImage("saida", temp);
            char d = cvWaitKey(0);
            if(d==112) break;
        }
        }

        //close video with'esc'
        if(e==27) break;
    }

    cvReleaseCapture (&g_capture);
    cvDestroyWindow("saida");

    return 0;   
}

//mouse callback
void rotina_mouse(int event, int x, int y, int flags, void* param) {
    IplImage* image = (IplImage*) param;
        switch( event ) {
            case CV_EVENT_MOUSEMOVE: {
                    if(continua==true)
                    pinta(image, x, y);         
            }
            break;
            case CV_EVENT_LBUTTONDOWN: {
                pinta(image, x, y);
                continua=true;
            }
            break;
            case CV_EVENT_LBUTTONUP: {
                continua=false;
            }
            break;
            default:
            break;
        }
}
edit retag flag offensive close merge delete

Comments

Use C++ interface and the Mat type instead of IplImage and your problem will disappear. What is going wrong is that you do not refresh your image during the mouse callback. You need to make a local copy of the image, then do an imshow in the same window of that local copy, and paste all adaptations after you leave the onmouse callback to the original image.

StevenPuttemans gravatar imageStevenPuttemans ( 2013-08-27 09:22:16 -0600 )edit

1 answer

Sort by ยป oldest newest most voted
0

answered 2013-08-27 09:55:42 -0600

berak gravatar image

i guess, you want to pause the videostream, not the processing loop ?

maybe all it needs is a slightly different control-structure:

bool paused = false;
while(1){
    if ( ! paused ) {
        frame = cvQueryFrame(g_capture);    
        if(!frame) break;
        cvNot(frame, frame);
        //cvCopyImage( frame, temp );  // what is this for ? you're drawing into 'frame', right ?
    }
    //cvShowImage("saida", temp);
    cvShowImage("saida", frame);
    char e = cvWaitKey(33);

    // toggle pause with 'p'
    if( e=='p' ) paused = ! paused; 
    // close video with'esc'
    if( e==27 ) break;
}

(also, what steven said, please use the c++ api instead!)

edit flag offensive delete link more

Comments

Hi! Thank you for helping me, =]. I modified this:

void pinta(IplImage* image, int x, int y){ cvFloodFill (image, cvPoint (x,y), cvScalar(103), cvScalarAll(2), cvScalarAll(2), 0, CV_FLOODFILL_FIXED_RANGE , 0); cvShowImage("saida",image); }

And it worked, =]!

Michele gravatar imageMichele ( 2013-08-27 16:00:09 -0600 )edit

Question Tools

Stats

Asked: 2013-08-27 09:12:14 -0600

Seen: 1,017 times

Last updated: Aug 27 '13