Ask Your Question
0

how can read a video from file, select ROI in first frame with rectangular and track obj?

asked 2017-02-09 04:32:26 -0600

asie gravatar image

updated 2017-02-09 06:11:09 -0600

LBerger gravatar image

it's my code. my first video frame loaded and I select a ROI. but when I choose ROI I cant see the rectangular. it' my firs problem. after that I don't know how track it with camshift algorithm.

please help me.

#include <opencv2/core/utility.hpp>
#include "opencv2/imgproc.hpp"
#include "opencv2/videoio.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/video/tracking.hpp"

#include <iostream>
#include <ctype.h>

using namespace cv;
using namespace std;


bool backprojMode = false;
bool selectObject = false;
int trackObject = 0;
bool showHist = true;
Rect selection;
int vmin = 10, vmax = 256, smin = 30;
Point pt1, pt2;
Mat cap_img;
int drag = 0;
void mouse_click(int event, int x, int y, int flags, void* param);

//In main open video and wait for roi event to complete by the use.
// You capture roi in pt1 and pt2 you can use the same coordinates for processing // //subsequent frame
int main(int argc, char *argv[])
{

int frame_num = 0;
int non_decode_frame = 0;
int count = 1, idx = 0;
int frame_pos = 0;

//cout << "Video File " << file << std::endl;

VideoCapture input_video("C:/Users/a/Desktop/PHD_TERM2/OPEN_CV/HW/2gui/gui2/data/trt1.avi");

//waitKey(30);
while (input_video.grab())
{
    cap_img.release();

    if (input_video.retrieve(cap_img))
    {
        namedWindow("My_Win", 1);
        rectangle(cap_img, pt1, pt2, CV_RGB(255, 0, 0), 3, 8, 0);
        imshow("My_Win", cap_img);
        setMouseCallback("My_Win", mouse_click, 0);


        //Wait here till user select the desire ROI
        waitKey();


        std::cout << "Got ROI disp prev and curr image" << std::endl;
        std::cout << "PT1" << pt1.x << " " << pt1.y << std::endl;
        std::cout << "PT2" << pt2.x << " " << pt2.y << std::endl;

        Mat curr_img_t1;
        Mat roi2(cap_img, Rect(pt1, pt2));
        Mat curr_imgT = roi2.clone();
        cvtColor(curr_imgT, curr_img_t1, CV_RGB2GRAY);

        rectangle(curr_imgT, pt1, pt2, CV_RGB(255, 0, 0), 3, 8, 0);
        imshow("curr_img", curr_imgT);

        // Do remaining processing here on capture roi for every frame
        waitKey(1);
    }
}

}

//Callback for mousclick event, the x-y coordinate of mouse button-up and button-down 
//are stored in two points pt1, pt2.
void mouse_click(int event, int x, int y, int flags, void *param)
{

if (event == CV_EVENT_LBUTTONDOWN && !drag && !selectObject)
{
    cout << "Mouse Pressed" << std::endl;

    selectObject = true;
    pt1.x = x;
    pt1.y = y;
    drag = 1;
}
if (event == CV_EVENT_LBUTTONUP && drag && !selectObject)
{

    Mat cl;
    std::cout << "Mouse LBUTTON Released" << std::endl;

    pt2.x = x;
    pt2.y = y;
    cout << "PT1" << pt1.x << ", " << pt1.y << std::endl;
    cout << "PT2" << pt2.x << "," << pt2.y << std::endl;

    rectangle(cap_img, pt1, pt2, CV_RGB(255, 0, 0), 3, 8, 0);
    imshow("Clone", cl);
    selectObject = true;
    drag = 0;
    trackObject = -1;

}
if (event == CV_EVENT_MOUSEMOVE && drag && !selectObject)
{
    Mat img1 = cap_img.clone();
    pt2.x = x;
    pt2.y = y;
    rectangle(img1, pt1, pt2, CV_RGB(255, 0, 0), 3, 8, 0);
    imshow("Select ROI", img1);
}

}
edit retag flag offensive close merge delete

2 answers

Sort by ยป oldest newest most voted
0

answered 2017-02-09 06:25:02 -0600

updated 2017-02-09 06:27:56 -0600

You need to call your mouse call back function outside the loop. Capture the first frame, call the mouse callback function to select your ROI, initialize your tracker and in the main function, get the second frame and update your tracker. OpenCV has examples for different trackers. Here's an example.

But here's the code for selecting ROI

#include <opencv2/opencv.hpp>
#include<iostream>

using namespace cv;
using namespace std;

Point point1, point2;
int drag = 0;
Rect roi;
Mat frame;

void mouse(int event, int x, int y, int flags, void* param)
{
    if (event == CV_EVENT_LBUTTONDOWN && !drag)
    {
        point1 = Point(x, y);
        drag = 1;
    }
    if (event == CV_EVENT_MOUSEMOVE && drag)
    {
        Mat img = frame.clone();
        point2 = Point(x, y);
        rectangle(img, point1, point2, Scalar(0, 0, 255), 1, 8, 0);
        imshow("Video", img);
    }
    if (event == CV_EVENT_LBUTTONUP && drag)
    {
        point2 = Point(x, y);
        drag = 0;
        roi = Rect(point1.x, point1.y, x - point1.x, y - point1.y);
    }
    if (event == CV_EVENT_LBUTTONUP)
    {
        drag = 0;
    }
}

int main()
{

    cout << "Select ROI and press any key to continue\n";
    VideoCapture cap(0);

    cap >> frame;//get the first frame

    imshow("Video", frame);
    cvSetMouseCallback("Video", mouse, NULL);//call the MouseCallBack function to select ROI

    /*initialize your tracker*/

    waitKey(0);

    while (1)
    {
        cap >> frame;//capture second frame

        /*Update your Tracker*/

        rectangle(frame, roi, Scalar(0, 0, 255), 1, 8, 0);
        imshow("Video", frame);

        if (waitKey(30) >= 0)
            break;
    }
    return 0;
}
edit flag offensive delete link more
0

answered 2017-02-09 06:08:23 -0600

LBerger gravatar image

updated 2017-02-09 06:18:13 -0600

There is good example using camshift here

About first frame you can make a loop with a condition : while (!IsRectSelect)

edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2017-02-09 04:32:26 -0600

Seen: 3,697 times

Last updated: Feb 09 '17