Home > Net >  How to fill the small hole of the binary image using opencv?
How to fill the small hole of the binary image using opencv?

Time:08-29

I have binary image, the image have many samll black-hole, I want to fill the hole so that I can get the object contours, but the cv.dilate method work not very well, can someone have good method do that?

The Image enter image description here

Need to fill the object like this(sample) enter image description here

CodePudding user response:

You can try applying iterative morphological operations (Erode Dilate). this should join the white blobs while preserving their size. Get the external contours and then just compute their bounding boxes. Depending on your original input (not the binary mask you posted) some tweaks could be made. Let's work with that binary image, this is the code:

# Imports:
import numpy as np
import cv2

# Image path
path = "D://opencvImages//"
fileName = "9ZL1r.png"

# Reading an image in default mode:
inputImage = cv2.imread(path   fileName)

# Deep Copy:
inputImageCopy = inputImage.copy()

# Convert RGB to grayscale:
grayscaleImage = cv2.cvtColor(inputImage, cv2.COLOR_BGR2GRAY)

# (Otsu) Threshold:
thresh, binaryImage = cv2.threshold(grayscaleImage, 0, 255, cv2.THRESH_BINARY   cv2.THRESH_OTSU)

# Apply Dilate   Erode:
kernel = np.ones((5, 5), np.uint8)
binaryImage = cv2.morphologyEx(binaryImage, cv2.MORPH_DILATE, kernel, iterations=5)
binaryImage = cv2.morphologyEx(binaryImage, cv2.MORPH_ERODE, kernel, iterations=5)

So far I've only read, thresholded and filtered the input image. This is the filtered result:

Looks good. Let's get the bounding rectangles:

# Find the EXTERNAL contours on the binary image:
contours, _ = cv2.findContours(binaryImage, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

# Look for the outer bounding boxes (no children):
for _, c in enumerate(contours):

    # Get the bounding rectangle:
    boundRect = cv2.boundingRect(c)

    # Draw the rectangle on the input image:
    # Get the dimensions of the bounding rect:
    rectX = boundRect[0]
    rectY = boundRect[1]
    rectWidth = boundRect[2]
    rectHeight = boundRect[3]

    # (Optional) Set color and draw:
    color = (0, 0, 255)
    cv2.rectangle(inputImageCopy, (int(rectX), int(rectY)),
                  (int(rectX   rectWidth), int(rectY   rectHeight)), color, 2)

    # Show image:
    cv2.imshow("Bounding Rectangles", inputImageCopy)
    cv2.waitKey(0)
  • Related