Spaces:
Running
on
Zero
Running
on
Zero
import os | |
import cv2 | |
import numpy as np | |
from sam2.distinctipy import get_colors | |
from pycocotools import mask as Mask | |
def batch_visualize_masks(args, image, masks_rle, image_kpts, bboxes_xyxy, dt_bboxes, gt_masks_raw, bbox_ious, mask_ious, image_path=None, mask_out=False, alpha=1.0): | |
# Decode dt_masks_rle | |
dt_masks = [] | |
for mask_rle in masks_rle: | |
mask = Mask.decode(mask_rle) | |
dt_masks.append(mask) | |
dt_masks = np.array(dt_masks) | |
# Decode gt_masks_raw | |
gt_masks = [] | |
for gt_mask in gt_masks_raw: | |
if gt_mask is None: | |
gt_masks.append(np.zeros((image.shape[0], image.shape[1]), dtype=np.uint8)) | |
else: | |
# gt_mask_rle = Mask.frPyObjects(gt_mask, image.shape[0], image.shape[1]) | |
# gt_mask_rle = Mask.merge(gt_mask_rle) | |
gt_mask_rle = gt_mask | |
mask = Mask.decode(gt_mask_rle) | |
gt_masks.append(mask) | |
gt_masks = np.array(gt_masks) | |
# Generate random color for each mask | |
if mask_out: | |
dt_mask_image = dt_masks.max(axis=0) | |
dt_mask_image = (~ dt_mask_image.astype(bool)).astype(np.uint8) | |
dt_mask_image = cv2.resize(dt_mask_image, (image.shape[1], image.shape[0]), interpolation=cv2.INTER_NEAREST) | |
dt_mask_image = image * dt_mask_image[:, :, None] | |
dt_mask_image = cv2.addWeighted(image, 1-alpha, dt_mask_image, alpha, 0) | |
else: | |
colors = (np.array(get_colors(dt_masks.shape[0])) * 255).astype(int) | |
# colors = np.random.randint(0, 255, (dt_masks.shape[0], 3)) | |
# # Make sure no colors are too dark | |
# np.clip(colors, 50, 255, out=colors) | |
# Repeat masks to 3 channels | |
dt_masks = np.repeat(dt_masks[:, :, :, None], 3, axis=3) | |
gt_masks = np.repeat(gt_masks[:, :, :, None], 3, axis=3) | |
# Colorize masks | |
dt_masks = dt_masks * colors[:, None, None, :] | |
gt_masks = gt_masks * colors[:, None, None, :] | |
# # Remove masks that are too small | |
# dt_masks_area = dt_masks.any(axis=3).sum(axis=(1, 2)) | |
# dt_masks[dt_masks_area < 300*300] = 0 | |
# Collapse masks to 3 channels | |
dt_mask_image = dt_masks.max(axis=0) | |
gt_mask_image = gt_masks.max(axis=0) | |
# Convert to uint8 | |
dt_mask_image = dt_mask_image.astype(np.uint8) | |
gt_mask_image = gt_mask_image.astype(np.uint8) | |
# Resize masks to image size | |
dt_mask_image = cv2.resize(dt_mask_image, (image.shape[1], image.shape[0]), interpolation=cv2.INTER_NEAREST) | |
gt_mask_image = cv2.resize(gt_mask_image, (image.shape[1], image.shape[0]), interpolation=cv2.INTER_NEAREST) | |
# Add masks to image | |
if not mask_out: | |
dt_mask_image = cv2.addWeighted(image, 0.6, dt_mask_image, 0.4, 0) | |
# Draw contours around the masks | |
for mask, color in zip(dt_masks, colors): | |
color = color.astype(int).tolist() | |
mask = mask.astype(np.uint8) | |
mask = cv2.cvtColor(mask, cv2.COLOR_BGR2GRAY) | |
mask = cv2.resize(mask, (image.shape[1], image.shape[0]), interpolation=cv2.INTER_NEAREST) | |
contours, _ = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) | |
cv2.drawContours(dt_mask_image, contours, -1, color, 1) | |
gt_mask_image = cv2.addWeighted(image, 0.6, gt_mask_image, 0.4, 0) | |
# Draw keypoints | |
if image_kpts is not None and not mask_out: | |
for instance_kpts, color in zip(image_kpts, colors): | |
color = tuple(color.astype(int).tolist()) | |
for kpt in instance_kpts: | |
cv2.circle(dt_mask_image, kpt.astype(int)[:2], 3, color, -1) | |
cv2.circle(gt_mask_image, kpt.astype(int)[:2], 3, color, -1) | |
# Draw bboxes | |
if bboxes_xyxy is not None and not mask_out: | |
bboxes_xyxy = np.array(bboxes_xyxy) | |
dt_bboxes = np.array(dt_bboxes) | |
dt_bboxes[:, 2:] += dt_bboxes[:, :2] | |
for gt_bbox, dt_bbox, color, biou in zip(bboxes_xyxy, dt_bboxes, colors, bbox_ious): | |
color = tuple(color.astype(int).tolist()) | |
gbox = gt_bbox.astype(int) | |
dbox = dt_bbox.astype(int) | |
cv2.rectangle(dt_mask_image, (dbox[0], dbox[1]), (dbox[2], dbox[3]), color, 2) | |
cv2.rectangle(gt_mask_image, (gbox[0], gbox[1]), (gbox[2], gbox[3]), color, 2) | |
# Write IOU on th etop-left corner of the bbox | |
# cv2.putText(dt_mask_image, "{:.2f}".format(biou), (dbox[0], dbox[1]-2), cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 1) | |
# cv2.putText(gt_mask_image, "{:.2f}".format(biou), (gbox[0], gbox[1]-2), cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 1) | |
# Save the image | |
bbox_ious = np.array(bbox_ious) | |
mask_ious = np.array(mask_ious) | |
if image_path is not None: | |
save_name = os.path.basename(image_path) | |
else: | |
save_name = "batch_bbox_{:06.2f}_mask_{:06.2f}_{:02d}kpts_{:06d}.jpg".format( | |
bbox_ious.mean(), mask_ious.mean(), args.num_pos_keypoints, np.random.randint(1000000), | |
) | |
if 'debug_folder' not in args: | |
args.debug_folder = "debug" | |
if mask_out: | |
cv2.imwrite(os.path.join(args.debug_folder, save_name), dt_mask_image) | |
else: | |
cv2.imwrite(os.path.join(args.debug_folder, save_name), np.hstack([gt_mask_image, dt_mask_image])) | |