Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OpenCV findContours issue

I have the following code which performs background subtraction and then uses findContours to draw a boundary around the foreground object.

// frame - Input frame from a camera.
// output - Output frame to be displayed.
    void process(cv:: Mat &frame, cv:: Mat &output) {

    cv::cvtColor(frame, gray, CV_BGR2GRAY); 

    // initialize background to 1st frame
    if (background.empty())
        gray.convertTo(background, CV_32F);

    // convert background to 8U
    background.convertTo(backImage,CV_8U);

    // compute difference between current image and background
    cv::absdiff(backImage,gray,foreground);

    // apply threshold to foreground image
    cv::threshold(foreground,output,threshold,255,cv::THRESH_BINARY_INV);

    // accumulate background
    cv::accumulateWeighted(gray, background, learningRate, output);

    // Find regions of interest
    std::vector<std::vector<cv::Point> > v; // Detected foreground points

    cv::findContours(output,v,CV_RETR_LIST,CV_CHAIN_APPROX_NONE);

    // Sort to find the entry with the most points at the beginning.
            // This is done to overcome noisy input.
    std::sort(v.begin(), v.end(), DescendingCompare);

    cv::Mat drawing = frame;

    std::vector<std::vector<cv::Point>> contours_poly(1);

    // Determine an approximate polygon for v[0] which is the largest contour
    cv::approxPolyDP( cv::Mat(v[0]), contours_poly[0], 3, false );

    // Draw polygonal contour
     cv::Scalar color = cv::Scalar( 0,0,255 );
     cv::drawContours( drawing, contours_poly, 0, color, 2, 8, std::vector<cv::Vec4i>(), 0, cv::Point() );

     // Show in a window
    output = drawing;
    v.clear();

}

The image is just a blank white background but findContours() is returning a contour with the 4 edges of the image. This ends up being the largest contour found, negating my logic in the code.Is there anyway to fix this ? I want it to return a null vector when the screen is blank.

http://imgur.com/a/hJCQl

http://imgur.com/a/hJCQl

Also, can this code be improved in anyway to improve efficiency ?

like image 269
Madman Avatar asked Dec 02 '11 09:12

Madman


People also ask

What is cv2 findContours?

Output: We see that there are three essential arguments in cv2. findContours() function. First one is source image, second is contour retrieval mode, third is contour approximation method and it outputs the image, contours, and hierarchy. 'contours' is a Python list of all the contours in the image.

What is the output of findContours OpenCV?

You've seen that the findContours() function returns two outputs: The contours list, and the hierarchy.

How does OpenCV findContours work?

To put in simple words findContours detects change in the image color and marks it as contour. As an example, the image of number written on paper the number would be detected as contour. The part that you want to detect should be white like above numbers in 1st image.


1 Answers

Your background should be black (0) and any object you want to contour should be white( or >= 1). You have it reversed and that's why FindContours detects the background as a contour and not the object.

like image 109
Adrian Avatar answered Sep 18 '22 18:09

Adrian