How to use Callback to draw a rectangle in a video?
Hi, I'm trying to select a rectangle in a video, but when I run my code nothing shows up; this is the code I'm using:
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 (;;) {
cap >> frame;
if( frame.empty() )
break;
if (callback == false) {
cv::setMouseCallback(src_window,mouseHandler,0);
}
else {
cv::imshow(src_window,frame);
}
}
cv::waitKey(0);
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;
}
}
I don't know what can I be doing wrong. Thanks for your help.
UPDATE: Thanks to Vladislav Vinogradov now I can stream the video, but when I run the program it shows the first frame and stays like that until I click on the image, then starts the streaming, how can I modify this part so the streaming occurs since the beginning?
cap >> frame;
cv::namedWindow(src_window,CV_WINDOW_AUTOSIZE);
cv::imshow(src_window,frame);
for (;;) {
if (callback) {
cap >> frame;
if( frame.empty() )
break;
cv::imshow(src_window,frame);
}
else {
cap >> frame;
cv::setMouseCallback(src_window,mouseHandler,0);
}
cv::waitKey(5);
}