Filling holes inside a binary object

fill holes python
hole filling in image processing
imfill 3d matlab
opencv fill image with color python
fill contour opencv python
matlab fill holes in binary image
remove small objects from binary image opencv
hole filling c++

I have a problem with filling white holes inside a black coins so that I can have only 0-255 binary image with filled black coins.. I have used 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 cvDrawContours function but I 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)

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 as follows:

You can see, there is no much difference in both the cases.

NB: gray - grayscale image, All codes are in OpenCV-Python

image processing - Filling holes inside a binary object, 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​)  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. 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.

A simple dilate and erode would close the gaps fairly well, I imagine. I think maybe this is what you're looking for.

A more robust solution would be to do an edge detect on the whole image, and then a hough transform for circles. A quick google shows there are code samples available in various languages for size invariant detection of circles using a hough transform, so hopefully that will give you something to go on.

The benefit of using the hough transform is that the algorithm will actually give you an estimate of the size and location of every circle, so you can rebuild an ideal image based on that model. It should also be very robust to overlap, especially considering the quality of the input image here (i.e. less worry about false positives, so can lower the threshold for results).

Filling holes in an image using OpenCV ( Python / C++ ), This tutorial describes a method for filling holes in a binary image in How do we fill all pixels inside the circular boundary with white ? ABSTRACT—This paper presents a new method for filling holes in objects of binary images. Further it analyses the performance of other existing holes filling operations n binary form ofi medical images. Hole filling operations are widely used in medical image processing today. Almost all the medical image

You might be looking for the Fillhole transformation, an application of morphological image reconstruction.

This transformation will fill the holes in your coins, even though at the cost of also filling all holes between groups of adjacent coins. The Hough space or opening-based solutions suggested by the other posters will probably give you better high-level recognition results.

Fill image regions and holes - MATLAB imfill, Input binary image, specified as a logical array of any dimension. Example: BW = imread('text.png');. Data Types: logical  Filling holes inside a binary object (4) A simple dilate and erode would close the gaps fairly well, I imagine. I think maybe this is what you're looking for. A more

Try using cvFindContours() function. You can use it to find connected components. With the right parameters this function returns a list with the contours of each connected components.

Find the contours which represent a hole. Then use cvDrawContours() to fill up the selected contour by the foreground color thereby closing the holes.

scipy.ndimage.morphology.binary_fill_holes, Fill the holes in binary objects. Parameters: input : array_like. n-dimensional binary array with holes to be filled. def fill_small_area_holes(mask, max_area): """Fill holes in the mask that are up to 'max area' (in terms of pixel-wise area). See also ndimage.binary_fill_holes if you want to fill all holes regardless of size.

I think if the objects are touched or crowded, there will be some problems using the contours and the math morophology opening. Instead, the following simple solution is found and tested. It is working very well, and not only for this images, but also for any other images.

here is the steps (optimized) as seen in http://blogs.mathworks.com/steve/2008/08/05/filling-small-holes/

let I: the input image

1. filled_I = floodfill(I). // fill every hole in the image.
2. inverted_I = invert(I)`.   
3. holes_I = filled_I AND inverted_I. // finds all holes 
4. cc_list = connectedcomponent(holes_I) // list of all connected component in holes_I.
5. holes_I = remove(cc_list,holes_I, smallholes_threshold_size) // remove all holes from holes_I having size > smallholes_threshold_size.
6. out_I = I OR holes_I. // fill only the small holes.

In short, the algorithm is just to find all holes, remove the big ones then write the small ones only on the original image.

[PDF] A Method for Filling Holes in Objects of Medical , of other existing holes filling operations in binary form of medical images. Hole filling from inside the object or from outside the object i.e., background. But user  However, the result of the above code cannot completely fill holes to the binary image. It means the output still remains the holes inside the circle.

Binary Image Operations, Grows the interior and exterior boundaries of objects by one pixel for each The Fill Holes operator performs the filling of objects in the displayed binary image. Identify , Classify and count objects in Matlab using Regionprops, bwlabel and ismember - Duration: 5:36. Anselm Griffin 40,401 views

cv2.floodFill Python Example, def fillhole(input_image): ''' input gray binary image get the filled image by '''​Select the largest object from a binary image and optionally fill holes inside it and​  fills holes in the binary image BW. A hole is a set of background pixels that cannot be reached by filling in the background from the edge of the image. A hole is a set of background pixels that cannot be reached by filling in the background from the edge of the image.

Flood-Fill Operations :: Morphological Operations (Image , The imfill function performs a flood-fill operation on binary and grayscale images. pixels (0's) to foreground pixels (1's), stopping when it reaches object boundaries. for binary image fill operations; Filling holes in binary or grayscale images fills the inside of the loop because, by default, the background is 4-​connected. I am trying to fill the "holes" of red blood cells in an image after performing binary threshold. Almost all red blood cells have a black center when inverting the binary threshold. I want to remove them. Example image:

Comments
  • Ok, I had a parameter problem i should use: cvDrawContours(gray, ptr, color, color, 0, CV_FILLED, 8); with 0 as max_level parameter. Hm now its filled with success :)
  • Try setting a larger StructuringElement, for example, 15,15. This might improve your 'open' procedure
  • Cool solution - Thanks! For me, the image opening method gave ~6ms execution time and the contour filling method gave ~3.5ms execution time. Working with video taken using cv2.VideoCapture(0) & my macbook pro. Any way to speed this up using numpy, or is that already being used by opencv?
  • @user391339: I don't think there is much to do anything on this to improve its speed, because it uses readymade opencv function, and they are optimized to their best. oh.. wait please !!!
  • @user391339: on second thought, I think using cv2.RETR_ExTERNAL instead of cv2.RETR_CCOMP may have a little improvement. I am not sure, you have to check it. But still, it will be of not much use. Instead, you can check whatelse take more time in your code and try to optimize it. By the way, it is only just 3.5ms. Why you need to improve its speed anyway?
  • but for opencv not for matlab
  • @lbstr: The page explains the theory mainly. I can't give you OpenCV code out of my head.
  • The link is dead.