Selecting a Region OpenCV
Asked Answered
C

3

9

I am new to OpenCV and I want to select a particular region in the video/image for detection. In my case I want to detect cars that are only in the road not in the parking lot.

Cosmetician answered 24/4, 2013 at 5:47 Comment(0)
H
13

Well, selecting cars requires use of training data. But to select an ROI (region of interest) is fairly simple:

Consider img = cv2.imread(image)

In that case, somewhere in your code, you can specify a region this way:

sub_image = img[y:y+h, x:x+w]

That will get the ROI once you specify the values, of course, not using 'x' or 'y', where h is the height and w is the width. Remember that images are just 2D matrices.

Use CascadeClassifier() to select the car(s) from the image(s). Documentation is found here. OpenCV comes packed with training data you can use to make classifications in the form of XML files.

Haith answered 24/4, 2013 at 6:2 Comment(0)
F
7

If you want to manually select a region of interest (ROI) to do some processing on it, then you may trying using mouse click event to select start and stop points of your ROI.

Once you have start and stop point you can use it to retrieve image from selected region.

The can be done on image or capture video frame.

bool roi_captured = false;
Point pt1, pt2;
Mat cap_img;
//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)
{

    switch(event)
    {
        case CV_EVENT_LBUTTONDOWN:
        {
            std::cout<<"Mouse Pressed"<<std::endl;

            if(!roi_capture)
            {
                pt1.x = x;
                pt1.y = y;
            }
            else
            {
                std::cout<<"ROI Already Acquired"<<std::endl;
            }
        break;
        }
        case CV_EVENT_LBUTTONUP:
        {
          if(!got_roi)
        {
            Mat cl;
            std::cout<<"Mouse LBUTTON Released"<<std::endl;

            pt2.x = x;
            pt2.y = y;
            cl = cap_img.clone();
            Mat roi(cl, Rect(pt1, pt2));
            Mat prev_imgT = roi.clone();
            std::cout<<"PT1"<<pt1.x<<", "<<pt1.y<<std::endl;
            std::cout<<"PT2"<<pt2.x<<","<<pt2.y<<std::endl;

            imshow("Clone",cl);

            got_roi = true;
        }
        else
        {
            std::cout<<"ROI Already Acquired"<<std::endl;
        }
        break;  
        }

    }

}
//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;

    std::cout<<"Video File "<<argv[1]<<std::endl;

    cv::VideoCapture input_video(argv[1]);

    namedWindow("My_Win",1);

    cvSetMouseCallback("My_Win", mouse_click, 0);

    sleep(1);

    while(input_video.grab())
    {
        cap_img.release();

        if(input_video.retrieve(cap_img))
        {
            imshow("My_Win", cap_img);
            if(!got_roi)
            {
                            //Wait here till user select the desire ROI
                waitKey(0);
            }
            else
            {
                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);

                    imshow("curr_img", curr_img);

            // Do remaining processing here on capture roi for every frame
                               waitKey(1);
                        }
                  }
}
}
Fid answered 24/4, 2013 at 8:4 Comment(0)
T
0

You didn't tag in what programming language you are writing with. Anyway, I answer you in python. (You can easily convert it to C++ if you want)

def mouse_drawing(event, x, y, flags, params):
    if event == cv2.EVENT_LBUTTONDOWN:
        car = img[y: y + carheight, x: x + carwidth]
        cv2.imwrite("car", car)

cv2.namedWindow("my_img")
cv2.setMouseCallback("my_img", mouse_drawing)

while True:
    cv2.imshow("my_img", img)
    key = cv2.waitKey(1)
    if key == 27:
        break

As in other answers was told, if you want to find cars automatically, that would be another problem and has to do with training data and other things.

Taboo answered 17/3, 2020 at 20:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.