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.
Also, can this code be improved in anyway to improve efficiency ?
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.
You've seen that the findContours() function returns two outputs: The contours list, and the hierarchy.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With