I need to retrieve the outermost contour of several silhouettes, possibly storing the contour coordinates in a clockwise or counterclockwise order. From what I've read, this kind of result can be archived by using OpenCV's Canny + findContours. Unfortunately, the majority of silhouettes I have to elaborate has jagged edges or holes, therefore, the "standard procedure" is not working properly. For instance, if my image is quite simple and without holes, the result is exactly as I want it (just the outermost contour and ordered coordinates): Cup example
In case of pictures with holes, I get a segmented outermost contour (different colours , see attached pictures) and it still displays the inner holes in the final image. I get the worst results with jagged edges. The holes are displayed and the contour is highly segmented (Cat). Holes and jagged edges
Code:
//add a small padding. Otherwise, in case of images where the border is partially cut out it won't be considered as a "closed" contour
int topbottom = (int) (0.05*image.rows);
int rightleft = (int) (0.05*image.cols);
copyMakeBorder( image, image, topbottom, topbottom, rightleft, rightleft, BORDER_CONSTANT);
//consider only alpha channel to create a silhouette
Mat silhouette;
vector<Mat> ch;
split(image, ch);
Canny(ch[3], silhouette, 100, 200);
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;
//find only the external contour
findContours( silhouette, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));
RNG rng(12345);
Mat drawing = Mat::zeros(silhouette.size(), CV_8UC3);
for(int i = 0; i < contours.size(); i++)
{
Scalar colour = Scalar(rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255));
drawContours(drawing, contours, i, colour, 1, 8, hierarchy, 0, Point());
}
Is there a way to avoid segmentation and remove the contours of the holes?