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')
Output Image:
Expected Output Image:
This can be done using flood fill in Python/OpenCV.
Input:
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:
Morphology Eroded Image:
Final Mask Image: