I have a problem with filling white holes inside a black coin so that I can have only 0-255 binary images with filled black coins. I have used a Median filter to accomplish it but in that case connection bridge between coins grows and it goes impossible to recognize them after several times of erosion... So I need a simple floodFill
like method in opencv
Here is my image with holes:
EDIT: floodfill
like function must fill holes in big components without prompting X, Y coordinates as a seed...
EDIT: I tried to use the cvDrawContours
function but it doesn't fill contours inside bigger ones.
Here is my code:
CvMemStorage mem = cvCreateMemStorage(0); CvSeq contours = new CvSeq(); CvSeq ptr = new CvSeq(); int sizeofCvContour = Loader.sizeof(CvContour.class); cvThreshold(gray, gray, 150, 255, CV_THRESH_BINARY_INV); int numOfContours = cvFindContours(gray, mem, contours, sizeofCvContour, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE); System.out.println("The num of contours: "+numOfContours); //prints 87, ok Random rand = new Random(); for (ptr = contours; ptr != null; ptr = ptr.h_next()) { Color randomColor = new Color(rand.nextFloat(), rand.nextFloat(), rand.nextFloat()); CvScalar color = CV_RGB( randomColor.getRed(), randomColor.getGreen(), randomColor.getBlue()); cvDrawContours(gray, ptr, color, color, -1, CV_FILLED, 8); } CanvasFrame canvas6 = new CanvasFrame("drawContours"); canvas6.showImage(gray);
Result: (you can see black holes inside each coin)
BW2 = imfill( BW ,'holes') fills holes in the input binary image BW . In this syntax, a hole is a set of background pixels that cannot be reached by filling in the background from the edge of the image. BW2 = imfill( BW , conn ,'holes') fills holes in the binary image BW , where conn specifies the connectivity.
Steps for implementing imfill in OpenCVThreshold the input image to obtain a binary image. Flood fill from pixel (0, 0). Notice the difference between the outputs of step 2 and step 3 is that the background in step 3 is now white. Invert the flood filled image ( i.e. black becomes white and white becomes black ).
The first hole-filling (HF1) step is used to fill in the holes in the depth image captured from 3D sensors. Holes also appear in the rendered color and depth images produced by the DIBR process. The second step is hole-filling for the rendered color (HF2), and the third step is hole-filling for the depth image (HF3).
Shift-click, right-click, or double-click to select a final point and start the fill operation.
There are two methods to do this:
1) Contour Filling:
First, invert the image, find contours in the image, fill it with black and invert back.
des = cv2.bitwise_not(gray) contour,hier = cv2.findContours(des,cv2.RETR_CCOMP,cv2.CHAIN_APPROX_SIMPLE) for cnt in contour: cv2.drawContours(des,[cnt],0,255,-1) gray = cv2.bitwise_not(des)
Resulting image:
2) Image Opening:
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(3,3)) res = cv2.morphologyEx(gray,cv2.MORPH_OPEN,kernel)
The resulting image is as follows:
You can see, there is not much difference in both cases.
NB: gray - grayscale image, All codes are in OpenCV-Python
Reference. OpenCV Morphological Transformations
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