pythonopencvimage-processingmaskimage-thresholding

Unable to create a clear binary mask of an image


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


Solution

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

    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