Reputation: 125
I have an image and I want to detect the holes inside my object (to use it to calculate area for each hole). Here is my image after an operation using opencv.
The problem is that the background and the hole has the same color.
So I don't know what to do to separate them and I don't know what algorithm I should use to detect the holes.
cv::threshold(channel[1], channel[1], 190, 255, CV_THRESH_BINARY);
cv::Mat element = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3));
cv::morphologyEx(channel[1], channel[1], cv::MORPH_OPEN, element);
cv::dilate(channel[1], channel[1], element);
cv::bitwise_not(channel[1], channel[1]);
cv::imwrite("green_after.bmp", channel[1]);
cv::Mat dist;
cv::distanceTransform(channel[1], dist, CV_DIST_L2, 3);
cv::imwrite("dist.bmp", dist);
cv::normalize(dist, dist, 0, 1., cv::NORM_MINMAX);
cv::imwrite("dist2.bmp", dist);
cv::threshold(dist, dist, .1, 1., cv::THRESH_BINARY);
cv::imwrite("dist3.bmp", dist);
cv::normalize(dist, dist, 0.0, 255.0, cv::NORM_MINMAX);
cv::imwrite("dist4.bmp", dist);
cv::Mat invSrc = cv::Scalar::all(255) - dist;
cv::imwrite("dist5.bmp", invSrc);
What should I do next?
Upvotes: 4
Views: 4511
Reputation: 4808
The first steps are the binarisation and invertation. With these steps you get a binary image with black background, white objects and black holes.
Next I offer you to use findContour method with parameter CV_RETR_CCOMP (or with CV_RETR_TREE):
This method with CV_RETR_CCOMP parameter finds the external contours of all white objects and determines also the internal contours of each hole. "It retrieves all of the contours and organizes them into a two-level hierarchy. At the top level, there are external boundaries of the components. At the second level, there are boundaries of the holes. If there is another contour inside a hole of a connected component, it is still put at the top level."
If you have the contours of the holes in a hierarchical structure you can continue the image processing with moment calculation, bounding rectangle calculation etc. (Contour Features).
The usage of the findContour method is written at this question:
Using hierarchy in findContours () in OpenCV?
Upvotes: 2
Reputation: 6824
You can do template matching - an application of cross-correlation in image processing - very simple.
If you happen to have templates of the image above (i.e. the expected image with no holes or any gaps). You can perform a Xcorrelation i.e. template matching to determine if there are any holes. If there are no holes, you should get a perfect match, otherwise no match. As @Hans commented below, the background is still white - which makes it a bit tricky.
Have a look at this - http://docs.opencv.org/doc/tutorials/imgproc/histograms/template_matching/template_matching.html
One of the solution that I can think about is:
1) Subtract your image from a totally black background image of the same size i.e. all the pixel values of white image should correspond to all whites.
2) Look at the indices. Those are your holes in the actual image.
Upvotes: 0