I need to find the number of inner holes in the below image.i.e my ultimate requirement is to detect and find the area of round shape black holes alone using contour hierarchy in opencv.No need to use any other algorithms.
Based on this link Using hierarchy in findContours () in OpenCV? i tried but it won't worked.
is there any other method to find the no of holes in the image?
here with i have attached the sample image and code.Can anybody give idea to find the inner black holes alone using hierarchy.I don't have a much experience in contour hierarchy.Thanks in advance. i used opencv c++ lib.
cv::Mat InputImage = imread("New Image.jpg");
int Err;
if(InputImage.empty() == 1)
{
InputImage.release();
cout<<"Error:Input Image Not Loaded"<<endl;
return 1;
}
cv::Mat greenTargetImage;
std::vector<cv::Mat> Planes;
cv::split(InputImage,Planes);
greenTargetImage = Planes[1];
cv::Mat thresholdImage = cv::Mat (greenTargetImage.size(),greenTargetImage.type());
cv::threshold(greenTargetImage,thresholdImage,128,255,THRESH_OTSU);
imwrite("thresholdImage.jpg",thresholdImage);
std::vector<std::vector<cv::Point>> contours;
std::vector<cv::Vec4i> hierarchy;
cv::findContours(thresholdImage,contours,hierarchy,cv::RETR_CCOMP,cv::CHAIN_APPROX_SIMPLE,cv::Point(-1,-1));
cout<<contours.size()<<endl;
cout<<hierarchy.size()<<endl;
int count = 0;
if (!contours.empty() && !hierarchy.empty())
{
for (int i = 0;i<contours.size();i++ )
{
if ( hierarchy[i][3] != -1)
{
cv::drawContours(InputImage,contours,i,CV_RGB(0,255,0),3);
count = count+1;
}
}
}
cout<<count<<endl; //No of inner holes in same level
imwrite("ContourImage.jpg",InputImage);
After applying this code i got the output count value is 11.But my requirement is count value should be 10 and also i need to draw only inner black holes alone not all boundaries of outer contours.Sorry for my english.
When finding contours in a binary image using cv2. findContours() , you can use contour hierarchy to select and extract specific contours within the image. Specifically, you can choose a contour retrieval mode to optionally return an output vector containing information about the image topology.
RETR_TREEIt retrieves all the contours and creates a full family hierarchy list.
cv2.RETR_EXTERNAL – retrieves only the extreme outer contours. cv2.RETR_LIST – retrieves all of the contours. method – contour approximation method. cv2.CHAIN_APPROX_NONE – stores all the contour points.
To draw the contours, cv. drawContours function is used. It can also be used to draw any shape provided you have its boundary points. Its first argument is source image, second argument is the contours which should be passed as a Python list, third argument is index of contours (useful when drawing individual contour.
Try this code works fine for me using hierarchy.
The idea is simple, just consider the contour which doesn’t have child.
That is
hierarchy[i][2]= -1
code:-
Mat tmp,thr;
Mat src=imread("img.jpg",1);
cvtColor(src,tmp,CV_BGR2GRAY);
threshold(tmp,thr,200,255,THRESH_BINARY_INV);
namedWindow("thr",0);
imshow("thr",thr);
vector< vector <Point> > contours; // Vector for storing contour
vector< Vec4i > hierarchy;
Mat dst(src.rows,src.cols,CV_8UC1,Scalar::all(0)); //create destination image
int count=0;
findContours( thr, contours, hierarchy,CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE ); // Find the contours in the image
for( int i = 0; i< contours.size(); i=hierarchy[i][0] ) // iterate through each contour.
{
Rect r= boundingRect(contours[i]);
if(hierarchy[i][2]<0){
rectangle(src,Point(r.x,r.y), Point(r.x+r.width,r.y+r.height), Scalar(0,0,255),3,8,0);
count++;
}
}
cout<<"Numeber of contour = "<<count<<endl;
imshow("src",src);
imshow("contour",dst);
waitKey();
Result:-
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