When you retrieve contours from an image, you should get 2 contours per blob - one inner and one outer. Consider the circle below - since the circle is a line with a pixel width larger than one, you should be able to find two contours in the image - one from the inner part of the circle and one from the outer part.
Using OpenCV, I want to retrieve the INNER contours. However, when I use findContours (), I only seem to be getting the outer contours. How would I retrieve the inner contours of a blob using OpenCV?
I am using the C++ API, not C therefore only suggest functions that use the C++ API. (i.e. findContours () rather than cvFindContours ())
Thanks.
Contours are defined as the line joining all the points along the boundary of an image that are having the same intensity. Contours come handy in shape analysis, finding the size of the object of interest, and object detection. OpenCV has findContour() function that helps in extracting the contours from the image.
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.
I ran this code on your image and it returned an inner and outer contour.
#include <iostream>
#include "opencv2/core/core.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
int main(int argc, const char * argv[]) {
cv::Mat image= cv::imread("../../so8449378.jpg");
if (!image.data) {
std::cout << "Image file not found\n";
return 1;
}
//Prepare the image for findContours
cv::cvtColor(image, image, CV_BGR2GRAY);
cv::threshold(image, image, 128, 255, CV_THRESH_BINARY);
//Find the contours. Use the contourOutput Mat so the original image doesn't get overwritten
std::vector<std::vector<cv::Point> > contours;
cv::Mat contourOutput = image.clone();
cv::findContours( contourOutput, contours, CV_RETR_LIST, CV_CHAIN_APPROX_NONE );
//Draw the contours
cv::Mat contourImage(image.size(), CV_8UC3, cv::Scalar(0,0,0));
cv::Scalar colors[3];
colors[0] = cv::Scalar(255, 0, 0);
colors[1] = cv::Scalar(0, 255, 0);
colors[2] = cv::Scalar(0, 0, 255);
for (size_t idx = 0; idx < contours.size(); idx++) {
cv::drawContours(contourImage, contours, idx, colors[idx % 3]);
}
cv::imshow("Input Image", image);
cvMoveWindow("Input Image", 0, 0);
cv::imshow("Contours", contourImage);
cvMoveWindow("Contours", 200, 0);
cv::waitKey(0);
return 0;
}
Here are the contours it found:
I think what Farhad is asking is to crop the contour from the original image.
To do that you will need to find the contour as explained above, then use a mask to get the inside from the original, and then crop the result into an image with the same size as the contour.
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