def visualize_image_with_pts_bbox(input_image, input_pts, window_size, linewidth=0.5, edge_color_index=20, pts_color_index=0, pts_size=20, vis_threshold=0.3, label=False, label_list=None, label_size=20, bgr2rgb=False, save_path=None, vis=False, warning=True, debug=True, closefig=True): ''' plot a set of points on top of an image with bbox around all points parameters input_image: a pil or numpy image input_pts: 2(3) x num_pts numpy array or a dictionary of 2(3) x num_pts array when there are 3 channels in pts, the third one denotes the occlusion/confidence flag occlusion: 0 -> invisible and not annotated, 1 -> visible and annotated, -1 -> visible but not annotated window_size: the height and width of the bbox linewidth: width of the edges of bounding boxes egde_color_index: a scalar or a list of color indexes for the edges of bounding boxes pts_color_index: a scalar or a list of color indexes for points pts_size: size of points label_size: font of labels vis_threshold: the points with confidence above the threshold will be drawn label: determine to add text label for each point, if label list is None, then an automatic list is created label_list: label string for all points, if label list is not None, the label is True automatically if the input points is a dictionary, then every point array in the dict follow the same label list bgr2rgb: true if the image needs to be converted from bgr to rgb outputs: fig, ax: figure handle for future use ''' try: safe_pts = safe_2dptsarray(input_pts, homogeneous=True, warning=warning, debug=debug) except AssertionError: safe_pts = safe_2dptsarray(input_pts, homogeneous=False, warning=warning, debug=debug) pts_visible_index = np.where(safe_pts[2, :] > vis_threshold)[0].tolist() safe_pts = safe_pts[0:2, pts_visible_index].transpose() # N x 2, N is the number of valid points to draw fig, ax = visualize_image_with_pts(input_image, input_pts, pts_size=pts_size, label=label, label_list=label_list, color_index=pts_color_index, bgr2rgb=bgr2rgb, debug=debug, vis=False, save_path=None, warning=warning, closefig=False) # construct the center bbox by input pts and window size center_bbox = np.zeros((safe_pts.shape[0], 4), dtype='float32') center_bbox[:, 0:2] = safe_pts center_bbox[:, 2:] = window_size input_bbox = get_center_crop_bbox(center_bbox, window_size, window_size, warning=warning, debug=debug) good_bbox = bbox_TLWH2TLBR(input_bbox, warning=warning, debug=debug) fig, ax = visualize_bbox(good_bbox, linewidth=linewidth, edge_color_index=edge_color_index, fig=fig, ax=ax, debug=debug, vis=False, save_path=None, warning=warning, closefig=False) return save_vis_close_helper(fig=fig, ax=ax, vis=vis, save_path=save_path, debug=debug, warning=warning, closefig=closefig)
def image_crop_center(input_image, center_rect, pad_value=0, warning=True, debug=True): ''' crop the image around a specific center with padded value around the empty area when the crop width/height are even, the cropped image has 1 additional pixel towards left/up parameters: center_rect: a list contains [center_x, center_y, (crop_width, crop_height)] pad_value: scalar within [0, 255] outputs: img_cropped: an uint8 numpy image crop_bbox: numpy array with shape of (1, 4), user-attempted cropping bbox, might out of boundary crop_bbox_clipped: numpy array with shape of (1, 4), clipped bbox within the boundary ''' np_image, _ = safe_image(input_image, warning=warning, debug=debug) if isfloatimage(np_image): np_image = (np_image * 255.).astype('uint8') if len(np_image.shape) == 2: np_image = np.expand_dims(np_image, axis=2) # extend the third channel if the image is grayscale # center_rect and pad_value are checked in get_crop_bbox and pad_around functions if debug: assert isuintimage(np_image), 'the input image is not an uint8 image' im_height, im_width = np_image.shape[0], np_image.shape[1] # calculate crop rectangles crop_bbox = get_center_crop_bbox(center_rect, im_width, im_height, debug=debug) crop_bbox_clipped = clip_bboxes_TLWH(crop_bbox, im_width, im_height, debug=debug) x1, y1, x2, y2 = crop_bbox_clipped[0, 0], crop_bbox_clipped[0, 1], crop_bbox_clipped[0, 0] + crop_bbox_clipped[0, 2], crop_bbox_clipped[0, 1] + crop_bbox_clipped[0, 3] img_cropped = np_image[y1 : y2, x1 : x2, :] # if original image is not enough to cover the crop area, we pad value around outside after cropping xmin, ymin, xmax, ymax = crop_bbox[0, 0], crop_bbox[0, 1], crop_bbox[0, 0] + crop_bbox[0, 2], crop_bbox[0, 1] + crop_bbox[0, 3] if (xmin < 0 or ymin < 0 or xmax > im_width or ymax > im_height): pad_left = max(0 - xmin, 0) pad_top = max(0 - ymin, 0) pad_right = max(xmax - im_width, 0) pad_bottom = max(ymax - im_height, 0) pad_rect = [pad_left, pad_top, pad_right, pad_bottom] img_cropped = image_pad_around(img_cropped, pad_rect=pad_rect, pad_value=pad_value, debug=debug) if len(img_cropped.shape) == 3 and img_cropped.shape[2] == 1: img_cropped = img_cropped[:, :, 0] return img_cropped, crop_bbox, crop_bbox_clipped