I have 2 images - one is the original image and the other is a mask of the same image that contains the to be extracted region in black. I want the final image to have white background and extracted region should be of same color as the original image.
For example, these are the 2 images - original and the mask
I want the final image to contain only the colored shirt with white background.
I tried to implement using the following code but it only generates the mask as inverted color and does not includes the colored shirt image.
def extract_cloth(input, mask, output):
if not os.path.exists(mask):
os.makedirs(mask)
if not os.path.exists(output):
os.makedirs(output)
input_image_filenames = [filename for filename in os.listdir(input) if filename.endswith('.png')]
for input_filename in input_image_filenames:
input_path = os.path.join(input, input_filename)
mask_filename = os.path.splitext(input_filename)[0] + '.png' # Change mask filename
mask_path = os.path.join(mask, mask_filename)
if os.path.exists(mask_path):
original_image = cv2.imread(input_path)
mask_image = cv2.imread(mask_path, cv2.IMREAD_GRAYSCALE)
# Invert the mask (black to white and vice versa)
inverted_mask = cv2.bitwise_not(mask_image)
# Extract cloth using original image and inverted mask
extracted_cloth = cv2.bitwise_and(original_image, original_image, mask=inverted_mask)
# Create a white background
white_background = 255 * np.ones_like(original_image, dtype=np.uint8)
# Combine extracted cloth with white background
extracted_cloth_on_white = cv2.bitwise_or(extracted_cloth, white_background, mask=inverted_mask)
output_filename = os.path.splitext(input_filename)[0] + '.png'
output_path = os.path.join(output, output_filename)
cv2.imwrite(output_path, extracted_cloth_on_white)
print(f'Saved: {output_path}')
else:
print(f'Mask not found for {input_filename}')```
My initial search with negative operation :
def extract_cloth(input, mask, output):
if not os.path.exists(mask):
os.makedirs(mask)
if not os.path.exists(output):
os.makedirs(output)
input_image_filenames = [filename for filename in os.listdir(input) if filename.endswith('.png')]
for input_filename in input_image_filenames:
input_path = os.path.join(input, input_filename)
mask_filename = os.path.splitext(input_filename)[0] + '.png' # Change mask filename
mask_path = os.path.join(mask, mask_filename)
if os.path.exists(mask_path):
original_image = cv2.imread(input_path)
mask_image = cv2.imread(mask_path, cv2.IMREAD_GRAYSCALE)
# Invert the mask (black to white and vice versa)
inverted_mask = cv2.bitwise_not(mask_image)
# Extract cloth using original image and inverted mask
extracted_cloth = cv2.bitwise_not(original_image, original_image, mask=inverted_mask)
# Create a white background
white_background = 255 * np.ones_like(original_image, dtype=np.uint8)
# Combine extracted cloth with white background
extracted_cloth_on_white = cv2.bitwise_not(extracted_cloth,white_background, mask=inverted_mask)
output_filename = os.path.splitext(input_filename)[0] + '.png'
output_path = os.path.join(output, output_filename)
cv2.imwrite(output_path, extracted_cloth_on_white)
print(f'Saved: {output_path}')
else:
print(f'Mask not found for {input_filename}')
My response with the code (more elegant) provided by fmw42 (+1) :
def extract_cloth(input, mask, output):
if not os.path.exists(mask):
os.makedirs(mask)
if not os.path.exists(output):
os.makedirs(output)
input_image_filenames = [filename for filename in os.listdir(input) if filename.endswith('.png')]
for input_filename in input_image_filenames:
input_path = os.path.join(input, input_filename)
mask_filename = os.path.splitext(input_filename)[0] + '.png' # Change mask filename
mask_path = os.path.join(mask, mask_filename)
if os.path.exists(mask_path):
original_image = cv2.imread(input_path)
mask_image = cv2.imread(mask_path, cv2.IMREAD_GRAYSCALE)
# Invert the mask (black to white and vice versa)
inverted_mask = cv2.bitwise_not(mask_image)
# Extract cloth using original image and inverted mask
extracted_cloth = cv2.bitwise_and(original_image, original_image, mask=inverted_mask)
extracted_cloth_on_white = extracted_cloth.copy()
extracted_cloth_on_white[mask_image==255] = (255,255,255)
output_filename = os.path.splitext(input_filename)[0] + '.png'
output_path = os.path.join(output, output_filename)
cv2.imwrite(output_path, extracted_cloth_on_white)
print(f'Saved: {output_path}')
else:
print(f'Mask not found for {input_filename}')