Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

ROI/ Bounding Box selection of Mat images in OpenCV

I'm trying to write a program that opens my laptops camera and gets a video stream and writes it to a video file on my computer. You should be able to pause and unpause the video, the pause option is added because I want to select an object within the video and the location of the object might differ. The issue I am facing is, that every time I run the program on Visual C++(with OpenCV 3.1), when I first press the r button(for pause), even though the video appears to be paused, if the location of the object changes(from the moment I press pause till the moment I've selected the ROI), in the new window that contains the ROI I'll have what it is in that moment in that area, even though the object has moved, so the video is not actually paused, only the writing to the video file stops. Another problem I am facing, is that after selecting the ROI, I cant pause/unpause the writing to the video file(it works just fine when I'm not selecting the ROI). I really need a still image because I have to use it in further processing.

Please help me find the problem.

#include <iostream>     // std::cout, std::endl
#include <iomanip>      // std::setfill, std::setw
#include <opencv\cv.h>
#include <opencv2/highgui/highgui.hpp>
#include <time.h>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include<opencv2\imgproc.hpp>

using namespace std;
using namespace cv;

Point point1, point2; /* vertical points of the bounding box */
int drag = 0;
Rect rect; /* bounding box */
Mat img, roiImg; /* roiImg - the part of the image in the bounding box */
int select_flag = 0;

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

if (event == CV_EVENT_MOUSEMOVE && drag)
{
/* mouse dragged. ROI being selected */
Mat img1 = img.clone();
point2 = Point(x, y);
rectangle(img1, point1, point2, CV_RGB(255, 0, 0), 3, 8, 0);
imshow("PausedVideo", img1);
}

if (event == CV_EVENT_LBUTTONUP && drag)
{
point2 = Point(x, y);
rect = Rect(point1.x, point1.y, x - point1.x, y - point1.y);
drag = 0;
roiImg = img(rect);
}

if (event == CV_EVENT_LBUTTONUP)
{
/* ROI selected */
select_flag = 1;
drag = 0;
}
}

string intToString(int number) {


std::stringstream ss;
ss << number;
return ss.str();
}

int main(int argc, char* argv[])
{
bool recording = false;
bool startNewRecording = false;
int inc = 0;
bool firstRun = true;

VideoCapture cap(0); // open the video camera no. 0
VideoWriter oVideoWriter;//create videoWriter object, not initialized yet

if (!cap.isOpened())  // if not success, exit program
{
cout << "ERROR: Cannot open the video file" << endl;
return -1;
}

namedWindow("MyVideo", CV_WINDOW_AUTOSIZE); //create a window called "MyVideo"

double dWidth = cap.get(CV_CAP_PROP_FRAME_WIDTH); //get the width of frames of the video
double dHeight = cap.get(CV_CAP_PROP_FRAME_HEIGHT); //get the height of frames of the video

cout << "Frame Size = " << dWidth << "x" << dHeight << endl;

//set framesize for use with videoWriter
Size frameSize(static_cast<int>(dWidth), static_cast<int>(dHeight));

while (1) {

if (startNewRecording == true) {

    oVideoWriter = VideoWriter("P:/MyVideo" + intToString(inc) + ".avi", CV_FOURCC('D', 'I', 'V', '3'), 20, frameSize, true); //initialize the VideoWriter object 
                                                                                                                              //oVideoWriter  =             VideoWriter("D:/MyVideo"+intToString(inc)+".avi", (int)cap.get(CV_CAP_PROP_FOURCC), 20, frameSize, true); //initialize the VideoWriter object 
    recording = true;
    startNewRecording = false;
    cout << "New video file created P:/MyVideo" + intToString(inc) + ".avi " << endl;

    if (!oVideoWriter.isOpened()) //if not initialize the VideoWriter successfully, exit the program
    {
        cout << "ERROR: Failed to initialize video writing" << endl;
        getchar();
        return -1;
    }

}

bool bSuccess = cap.read(img); // read a new frame from video

if (!bSuccess) //if not success, break loop
{
    cout << "ERROR: Cannot read a frame from video file" << endl;
    break;
}

//if we're in recording mode, write to file
if (recording) {

    oVideoWriter.write(img);

    imshow("MyVideo", img); //show the frame in "MyVideo" window

}
else
{
    cvSetMouseCallback("MyVideo", mouseHandler, NULL);
    if (select_flag == 1)
    {
        recording = true;
        imshow("ROI", roiImg); /* show the image bounded by the box */
    }
    rectangle(img, rect, CV_RGB(255, 0, 0), 3, 8, 0);
    //imshow("MyVideo", img);

}

switch (waitKey(10)) {

case 114:
    //'r' has been pressed.
    //toggle recording mode
    recording = !recording;

    if (firstRun == true) {

        cout << "New Recording Started" << endl;
        oVideoWriter = VideoWriter("P:/MyVideo0.avi", CV_FOURCC('D', 'I', 'V', '3'), 20, frameSize, true);

        if (!oVideoWriter.isOpened())
        {
            cout << "ERROR: Failed to initialize video writing" << endl;
            getchar();
            return -1;
        }
        firstRun = false;

    }
    else {
        if (!recording)cout << "Recording Stopped" << endl;

        else cout << "Recording Started" << endl;
    }
    break;

case 110:
    //'n' has been pressed
    //start new video file
    startNewRecording = true;
    cout << "New Recording Started" << endl;
    //increment video file name
    inc += 1;
    break;
case 27:
    //'esc' has been pressed
    //exit program.
    cout << "Exit Program" << endl;
    return 0;

}

}

return 0;

}