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])) | |