Unable to create a clear binary mask of an image

78 views Asked by At

I want to create binary mask of an image. I am using OpenCV, however the output is not as expected. I am using the following code -

import cv2
def create_adaptive_binary_mask(image_path):
      # Read the image
      img = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)

      # Apply adaptive thresholding
      binary_mask = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2)

      # Display or save the binary mask
      cv2.imshow('Adaptive Binary Mask', binary_mask)
      cv2.waitKey(0)
      cv2.destroyAllWindows()

create_adaptive_binary_mask('1.jpg')

Input Image: Input Image

Output Image:

enter image description here

Expected Output Image:

enter image description here

1

There are 1 answers

1
fmw42 On BEST ANSWER

This can be done using flood fill in Python/OpenCV.

  • Read the input
  • Set up mask for floodfill process
  • Apply flood fill providing adequate lodiff and hidiff arguments to account for JPG input artifacting around the outside of the tshirt
  • Erode the flood filled result to remove remaining slight white outline around the result
  • Use Numpy to change the remaining non-black colors to white to form the final mask
  • Save the results

Input:

enter image description here

import cv2
import numpy as np

# read image
img = cv2.imread('red_tshirt.jpg')
h, w = img.shape[:2]

# create zeros mask 2 pixels larger in each dimension
ff_mask = np.zeros([h + 2, w + 2], np.uint8)

# floodfill background with black
# set low and hi diffs appropriate to mostly remove jpg artifacts around the outside of tshirt
floodfill = cv2.floodFill(img, ff_mask, (0,0), (0,0,0), (5,5,5), (60,60,60), flags=8)[1]

# erode mask to remove remaining slight white border due to jpg artifacting
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3,3))
morph = cv2.morphologyEx(floodfill, cv2.MORPH_ERODE, kernel)

# make all other colors but black into white
mask = morph.copy()
mask = cv2.cvtColor(mask, cv2.COLOR_BGR2GRAY)
mask[mask!=0] = 255

# save mask
cv2.imwrite('red_tshirt_floodfill.jpg',floodfill)
cv2.imwrite('red_tshirt_morph.jpg',morph)
cv2.imwrite('red_tshirt_mask.jpg',mask)

# show the images
#cv2.imshow("thresh", thresh)
cv2.imshow("floodfill", floodfill)
cv2.imshow("morph", morph)
cv2.imshow("mask", mask)
cv2.waitKey(0)
cv2.destroyAllWindows()

Floodfilled Image:

enter image description here

Morphology Eroded Image:

enter image description here

Final Mask Image:

enter image description here