| import streamlit as st
|
| import cv2
|
| import numpy as np
|
| from PIL import Image
|
|
|
| def apply_mask(image_cv, mask, color=(0, 255, 0), alpha=0.5):
|
| """ Apply a mask to an image with given color and alpha blend """
|
| mask_bgr = np.zeros_like(image_cv)
|
| mask_bgr[mask > 0] = color
|
| return cv2.addWeighted(image_cv, 1 - alpha, mask_bgr, alpha, 0)
|
|
|
| def draw_points(image_cv, points, labels):
|
| """ Draw points on the image with different colors based on labels """
|
| for coord, label in zip(points, labels):
|
| color = (0, 255, 0) if label == 1 else (255, 0, 0)
|
| cv2.circle(image_cv, tuple(map(int, coord)), 5, color, -1)
|
| return image_cv
|
|
|
| def draw_boxes(image_cv, boxes):
|
| """ Draw boxes on the image """
|
| for box in boxes:
|
| x, y, w, h = map(int, box)
|
| cv2.rectangle(image_cv, (x, y), (x + w, y + h), (255, 0, 0), 2)
|
| return image_cv
|
|
|
| def show_masks(image, masks, scores, point_coords=None, box_coords=None, input_labels=None, borders=True):
|
| image_cv = np.array(image.convert("RGB"))[..., ::-1]
|
|
|
| for i, (mask, score) in enumerate(zip(masks, scores)):
|
| image_with_mask = apply_mask(image_cv, mask)
|
|
|
| if point_coords is not None:
|
| assert input_labels is not None
|
| image_with_mask = draw_points(image_with_mask, point_coords, input_labels)
|
|
|
| if box_coords is not None:
|
| image_with_mask = draw_boxes(image_with_mask, box_coords)
|
|
|
|
|
| image_with_mask = cv2.cvtColor(image_with_mask, cv2.COLOR_BGR2RGB)
|
| image_pil = Image.fromarray(image_with_mask)
|
|
|
|
|
| st.image(image_pil, caption=f"Mask {i+1}, Score: {score:.3f}", use_column_width=True)
|
|
|
|
|
| def apply_mask_to_image(image, mask):
|
|
|
| if isinstance(image, Image.Image):
|
| image = np.array(image)
|
| image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
|
|
|
|
|
| alpha_channel = (mask * 255).astype(np.uint8)
|
|
|
|
|
| masked_image = np.zeros((image.shape[0], image.shape[1], 4), dtype=np.uint8)
|
| for c in range(3):
|
| masked_image[..., c] = image[..., c] * mask
|
|
|
|
|
| masked_image[..., 3] = alpha_channel
|
|
|
| return masked_image
|
|
|
| def show_masks_1(image, masks, scores):
|
| mask_images = []
|
| for i, (mask, score) in enumerate(zip(masks, scores)):
|
|
|
| masked_image = apply_mask_to_image(image, mask)
|
|
|
|
|
| pil_image = Image.fromarray(cv2.cvtColor(masked_image, cv2.COLOR_BGRA2RGBA))
|
| mask_images.append((pil_image, score))
|
|
|
| return mask_images
|
|
|
|
|
| def apply_inverse_mask_to_image(image, mask):
|
|
|
| if isinstance(image, Image.Image):
|
| image = np.array(image)
|
| image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
|
|
|
|
|
| alpha_channel = (1 - mask) * 255
|
|
|
|
|
| inverse_masked_image = np.zeros((image.shape[0], image.shape[1], 4), dtype=np.uint8)
|
| for c in range(3):
|
| inverse_masked_image[..., c] = image[..., c] * (1 - mask)
|
|
|
|
|
| inverse_masked_image[..., 3] = alpha_channel.astype(np.uint8)
|
|
|
| return inverse_masked_image
|
|
|
| def show_inverse_masks(image, masks, scores):
|
| mask_images = []
|
| for i, (mask, score) in enumerate(zip(masks, scores)):
|
|
|
| inverse_masked_image = apply_inverse_mask_to_image(image, mask)
|
|
|
|
|
| pil_image = Image.fromarray(cv2.cvtColor(inverse_masked_image, cv2.COLOR_BGRA2RGBA))
|
| mask_images.append((pil_image, score))
|
|
|
| return mask_images
|
|
|
| import streamlit as st
|
| import cv2
|
| import numpy as np
|
| from PIL import Image
|
|
|
| def combine_mask_and_inverse(image, mask):
|
|
|
|
|
| if isinstance(image, Image.Image):
|
| image = np.array(image)
|
| image = cv2.cvtColor(image, cv2.COLOR_RGBA2BGR)
|
|
|
|
|
| masked_region = cv2.bitwise_and(image, image, mask=mask.astype(np.uint8))
|
|
|
|
|
| inverse_mask = 1 - mask
|
| inverse_masked_region = cv2.bitwise_and(image, image, mask=inverse_mask.astype(np.uint8))
|
|
|
|
|
| combined_image = cv2.add(masked_region, inverse_masked_region)
|
|
|
|
|
| combined_image_rgba = cv2.cvtColor(combined_image, cv2.COLOR_BGR2RGBA)
|
|
|
| return combined_image_rgba
|
|
|
| def show_combined_masks(image, masks, scores):
|
|
|
| mask_images = []
|
| for i, (mask, score) in enumerate(zip(masks, scores)):
|
|
|
| combined_image = combine_mask_and_inverse(image, mask)
|
|
|
|
|
| pil_image = Image.fromarray(combined_image)
|
| mask_images.append((pil_image, score))
|
|
|
| return mask_images
|
|
|
|
|
| def pixelate_area(image, mask, pixelation_level):
|
| """
|
| Apply pixelation to the masked area of an image.
|
| """
|
| pixelated_image = image.copy()
|
| h, w, _ = image.shape
|
|
|
| for y in range(0, h, pixelation_level):
|
| for x in range(0, w, pixelation_level):
|
| block = (slice(y, min(y + pixelation_level, h)), slice(x, min(x + pixelation_level, w)))
|
| if np.any(mask[block]):
|
| mean_color = image[block].mean(axis=(0, 1)).astype(int)
|
| pixelated_image[block] = mean_color
|
|
|
| return pixelated_image
|
|
|
| def combine_pixelated_mask(image, mask, pixelation_level=10):
|
| """
|
| Combine the pixelated masked areas with the original image.
|
| """
|
| image_np = np.array(image)
|
| mask_np = np.array(mask)
|
|
|
| pixelated_mask = pixelate_area(image_np, mask_np, pixelation_level)
|
| combined_image = Image.fromarray(pixelated_mask)
|
| return combined_image
|
|
|
|
|
| def change_hue(image, mask, hue_shift):
|
|
|
|
|
| hsv_image = cv2.cvtColor(image, cv2.COLOR_RGBA2RGB)
|
| hsv_image = cv2.cvtColor(hsv_image, cv2.COLOR_RGB2HSV)
|
|
|
|
|
| hsv_image[..., 0] = (hsv_image[..., 0] + hue_shift) % 180
|
|
|
|
|
| rgb_image = cv2.cvtColor(hsv_image, cv2.COLOR_HSV2RGB)
|
|
|
|
|
| hue_changed_image = np.array(image).copy()
|
| hue_changed_image[mask] = np.concatenate((rgb_image[mask], hue_changed_image[mask][..., 3:]), axis=-1)
|
|
|
| return hue_changed_image
|
|
|
| def combine_hue_changed_mask(image, mask, hue_shift):
|
|
|
| image_np = np.array(image)
|
| mask_np = np.array(mask).astype(bool)
|
|
|
| hue_changed_area = change_hue(image_np, mask_np, hue_shift)
|
| combined_image = Image.fromarray(hue_changed_area)
|
|
|
| return combined_image
|
|
|
| def replace_masked_area(original_image, replacement_image, mask):
|
|
|
| replacement_image = cv2.resize(replacement_image, (original_image.shape[1], original_image.shape[0]))
|
|
|
|
|
| replaced_image = original_image.copy()
|
|
|
|
|
| replaced_image[mask] = replacement_image[mask]
|
|
|
| return replaced_image
|
|
|
| def combine_mask_replaced_image(original_image, replacement_image, mask):
|
|
|
|
|
| original_np = np.array(original_image)
|
| replacement_np = np.array(replacement_image)
|
| mask_np = np.array(mask).astype(bool)
|
|
|
|
|
| replaced_area = replace_masked_area(original_np, replacement_np, mask_np)
|
| combined_image = Image.fromarray(replaced_area)
|
|
|
| return combined_image
|
|
|
| import streamlit as st
|
| from PIL import Image
|
|
|
| def resize_image(image, max_size=1024):
|
|
|
| width, height = image.size
|
|
|
|
|
| if width > height:
|
| scaling_factor = max_size / width
|
| else:
|
| scaling_factor = max_size / height
|
|
|
|
|
| if scaling_factor < 1:
|
|
|
| new_width = int(width * scaling_factor)
|
| new_height = int(height * scaling_factor)
|
|
|
|
|
| image_resized = image.resize((new_width, new_height))
|
| return image_resized
|
| else:
|
|
|
| return image
|
|
|
|
|
| def combine_mask_and_inverse_gen(original_img, generated_img, mask):
|
|
|
| original_img = original_img.convert("RGBA")
|
| generated_img = generated_img.convert("RGBA")
|
|
|
|
|
| generated_img = generated_img.resize(original_img.size)
|
|
|
|
|
| orig_array = np.array(original_img)
|
| gen_array = np.array(generated_img)
|
|
|
|
|
| mask = Image.fromarray((mask * 255).astype(np.uint8))
|
| mask = mask.resize(original_img.size, Image.NEAREST)
|
| bool_mask = np.array(mask).astype(bool)
|
|
|
|
|
| if bool_mask.ndim == 2:
|
| bool_mask = bool_mask[:, :, np.newaxis]
|
|
|
|
|
| combined_array = np.where(bool_mask, gen_array, orig_array)
|
|
|
|
|
| combined_img = Image.fromarray(combined_array, "RGBA")
|
| return combined_img
|
|
|