| | """ |
| | Mask and point painting utilities |
| | Adapted from MatAnyone demo |
| | """ |
| |
|
| | import cv2 |
| | import numpy as np |
| | from PIL import Image |
| |
|
| |
|
| | def mask_painter(input_image, input_mask, mask_color=5, mask_alpha=0.7, |
| | contour_color=1, contour_width=5): |
| | """ |
| | Paint mask on image with transparency |
| | |
| | Args: |
| | input_image: np.ndarray, (H, W, 3) |
| | input_mask: np.ndarray, (H, W), binary mask |
| | mask_color: int, color ID for mask |
| | mask_alpha: float, transparency |
| | contour_color: int, color ID for contour |
| | contour_width: int, width of contour |
| | |
| | Returns: |
| | painted_image: np.ndarray, (H, W, 3) |
| | """ |
| | assert input_image.shape[:2] == input_mask.shape, "Image and mask must have same dimensions" |
| | |
| | |
| | palette = np.array([ |
| | [0, 0, 0], |
| | [255, 0, 0], |
| | [0, 255, 0], |
| | [0, 0, 255], |
| | [255, 255, 0], |
| | [255, 0, 255], |
| | [0, 255, 255], |
| | [128, 128, 128], |
| | [255, 165, 0], |
| | [128, 0, 128], |
| | ]) |
| | |
| | mask_color_rgb = palette[mask_color % len(palette)] |
| | contour_color_rgb = palette[contour_color % len(palette)] |
| | |
| | |
| | painted_image = input_image.copy() |
| | colored_mask = np.zeros_like(input_image) |
| | colored_mask[input_mask > 0] = mask_color_rgb |
| | |
| | |
| | mask_region = input_mask > 0 |
| | painted_image[mask_region] = ( |
| | painted_image[mask_region] * (1 - mask_alpha) + |
| | colored_mask[mask_region] * mask_alpha |
| | ).astype(np.uint8) |
| | |
| | |
| | if contour_width > 0: |
| | contours, _ = cv2.findContours( |
| | input_mask.astype(np.uint8), |
| | cv2.RETR_EXTERNAL, |
| | cv2.CHAIN_APPROX_SIMPLE |
| | ) |
| | cv2.drawContours( |
| | painted_image, |
| | contours, |
| | -1, |
| | contour_color_rgb.tolist(), |
| | contour_width |
| | ) |
| | |
| | return painted_image |
| |
|
| |
|
| | def point_painter(input_image, input_points, point_color=8, point_alpha=0.9, |
| | point_radius=15, contour_color=2, contour_width=3): |
| | """ |
| | Paint points on image |
| | |
| | Args: |
| | input_image: np.ndarray, (H, W, 3) |
| | input_points: np.ndarray, (N, 2), [x, y] coordinates |
| | point_color: int, color ID for points |
| | point_alpha: float, transparency |
| | point_radius: int, radius of point circles |
| | contour_color: int, color ID for contour |
| | contour_width: int, width of contour |
| | |
| | Returns: |
| | painted_image: np.ndarray, (H, W, 3) |
| | """ |
| | if len(input_points) == 0: |
| | return input_image |
| | |
| | palette = np.array([ |
| | [0, 0, 0], |
| | [255, 0, 0], |
| | [0, 255, 0], |
| | [0, 0, 255], |
| | [255, 255, 0], |
| | [255, 0, 255], |
| | [0, 255, 255], |
| | [128, 128, 128], |
| | [255, 165, 0], |
| | [128, 0, 128], |
| | ]) |
| | |
| | point_color_rgb = palette[point_color % len(palette)] |
| | contour_color_rgb = palette[contour_color % len(palette)] |
| | |
| | painted_image = input_image.copy() |
| | |
| | for point in input_points: |
| | x, y = int(point[0]), int(point[1]) |
| | |
| | |
| | overlay = painted_image.copy() |
| | cv2.circle(overlay, (x, y), point_radius, point_color_rgb.tolist(), -1) |
| | cv2.addWeighted(overlay, point_alpha, painted_image, 1 - point_alpha, 0, painted_image) |
| | |
| | |
| | if contour_width > 0: |
| | cv2.circle(painted_image, (x, y), point_radius, contour_color_rgb.tolist(), contour_width) |
| | |
| | return painted_image |
| |
|