Fill holes holes/area in a binary image using OpenCV

Viewed 1230

I have below preprocessed rice image. I want to fill the rice with black color and then perform the inverse operation to find contours. I am trying to use Erosion/Dilation operation but not working. Below is the code snippet I am using.

First I used shadow removal algorithm then used adaptive thresholding which gives the Input image. Now, I want to change the Input image to the output image.

Original Image:

enter image description here

Input Image:

Input Image

Required Output Image:

Output Image

Code Snippet:

oposite = cv2.bitwise_not(img)

#Erosion
kernel = np.ones((3,3),np.uint8)
erosion = cv2.dilate(des,kernel,iterations = 1)
erosion = cv2.bitwise_not(erosion)
im_out = oposite + erosion

cv2.imshow("output", im_out)
cv2.waitKey(0)
1 Answers

You can create an HSV mask by using the cv2.COLOR_BGR2HSV flag in the cv2.cvtColor() method, and by using the cv2.inRange() method. I basically changed the maximum saturation value from 255 to 100:

import cv2
import numpy as np

img = cv2.imread("rice.jpg")
img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
lower = np.array([0, 0, 0])
upper = np.array([179, 100, 255])
mask = cv2.inRange(img_hsv, lower, upper)
cv2.imshow("Mask", mask)
cv2.waitKey(0)

Output:

enter image description here


If you're looking to make the grains thinner, you can turn down the maximum hue value, from 179 to, say,111, along with the maximum saturation value at 100:

import cv2
import numpy as np

img = cv2.imread("rice.jpg")
img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
lower = np.array([0, 0, 0])
upper = np.array([111, 100, 255])
mask = cv2.inRange(img_hsv, lower, upper)
cv2.imshow("Mask", mask)
cv2.waitKey(0)

Output:

enter image description here

Related