Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Add cv::waitKey with some delay to the end of your for(;;) loop:

cv::Mat frame;
const char* src_window = "Select ROI";

int drag = 0, select_flag = 0;

cv::Point point1, point2;
bool callback = false;

void mouseHandler(int event, int x, int y, int flags, void* param);

int main(int argc, char** argv)
{
    cv::VideoCapture cap;

    if( argc == 1 || (argc == 2 && strlen(argv[1]) == 1 && isdigit(argv[1][0])))
        cap.open(argc == 2 ? argv[1][0] - '0' : 0);
    else if( argc == 2 )
    cap.open(argv[1]);

    if( !cap.isOpened() )
    {
        std::cout << "Could not initialize capturing...\n";
        return 0;
    }

    cap >> frame;

    cv::namedWindow(src_window,CV_WINDOW_AUTOSIZE);
    cv::imshow(src_window,frame);
    cv::setMouseCallback(src_window,mouseHandler,0);

    for (;;)
    {
        if(callback)
        {
            cap >> frame;
            if( frame.empty() )
                    break;
            cv::imshow(src_window,frame);
        }

        cv::waitKey(5);
    }

    return 0;
}

void mouseHandler(int event, int x, int y, int flags, void* param)
{
    if (event == CV_EVENT_LBUTTONDOWN && !drag && !select_flag)
    {
        /* left button clicked. ROI selection begins */
        point1 = cv::Point(x, y);
        drag = 1;
    }

    if (event == CV_EVENT_MOUSEMOVE && drag && !select_flag)
    {
        /* mouse dragged. ROI being selected */
        cv::Mat img1 = frame.clone();
        point2 = cv::Point(x, y);
        cv::rectangle(img1, point1, point2, CV_RGB(255, 0, 0), 3, 8, 0);
        cv::imshow(src_window, img1);
    }

    if (event == CV_EVENT_LBUTTONUP && drag && !select_flag)
    {
        cv::Mat img2 = frame.clone();
        point2 = cv::Point(x, y);
        drag = 0;
        select_flag = 1;
        cv::imshow(src_window, img2);
        callback = true;
    }
}

Add cv::waitKey with some delay to the end of your for(;;) loop:loop.

From the documentation: This function is the only method in HighGUI that can fetch and handle events, so it needs to be called periodically for normal event processing unless HighGUI is used within an environment that takes care of event processing.

cv::Mat frame;
const char* src_window = "Select ROI";

int drag = 0, select_flag = 0;

cv::Point point1, point2;
bool callback = false;

void mouseHandler(int event, int x, int y, int flags, void* param);

int main(int argc, char** argv)
{
    cv::VideoCapture cap;

    if( argc == 1 || (argc == 2 && strlen(argv[1]) == 1 && isdigit(argv[1][0])))
        cap.open(argc == 2 ? argv[1][0] - '0' : 0);
    else if( argc == 2 )
    cap.open(argv[1]);

    if( !cap.isOpened() )
    {
        std::cout << "Could not initialize capturing...\n";
        return 0;
    }

    cap >> frame;

    cv::namedWindow(src_window,CV_WINDOW_AUTOSIZE);
    cv::imshow(src_window,frame);
    cv::setMouseCallback(src_window,mouseHandler,0);

    for (;;)
    {
        if(callback)
        {
            cap >> frame;
            if( frame.empty() )
                    break;
            cv::imshow(src_window,frame);
        }

        cv::waitKey(5);
    }

    return 0;
}

void mouseHandler(int event, int x, int y, int flags, void* param)
{
    if (event == CV_EVENT_LBUTTONDOWN && !drag && !select_flag)
    {
        /* left button clicked. ROI selection begins */
        point1 = cv::Point(x, y);
        drag = 1;
    }

    if (event == CV_EVENT_MOUSEMOVE && drag && !select_flag)
    {
        /* mouse dragged. ROI being selected */
        cv::Mat img1 = frame.clone();
        point2 = cv::Point(x, y);
        cv::rectangle(img1, point1, point2, CV_RGB(255, 0, 0), 3, 8, 0);
        cv::imshow(src_window, img1);
    }

    if (event == CV_EVENT_LBUTTONUP && drag && !select_flag)
    {
        cv::Mat img2 = frame.clone();
        point2 = cv::Point(x, y);
        drag = 0;
        select_flag = 1;
        cv::imshow(src_window, img2);
        callback = true;
    }
}