def cc_locs(mask): ccs = cv2.connectedComponents(mask.astype(np.uint8), connectivity=4)[1] rc_locs = np.where(mask > 0) rc_ids = ccs[rc_locs] rc_arrs = np.ascontiguousarray(np.vstack(rc_locs).T) cc_to_loc = util.group_items(rc_arrs, rc_ids, axis=0) return cc_to_loc
def cc_locs(mask): """ Grouped row/col locations of 4-connected-components """ from clab import util import cv2 ccs = cv2.connectedComponents(mask.astype(np.uint8), connectivity=4)[1] rc_locs = np.where(mask > 0) rc_ids = ccs[rc_locs] rc_arrs = np.ascontiguousarray(np.vstack(rc_locs).T) cc_to_loc = util.group_items(rc_arrs, rc_ids, axis=0) return cc_to_loc
def instance_contours(gti): """ Extracts a contour for each (non-overlapping) instance label in a mask """ # TODO: move to somewhere better import cv2 rc_locs = np.where(gti > 0) grouped_cc_rcs = util.group_items( np.ascontiguousarray(np.vstack(rc_locs).T), gti[rc_locs], axis=0 ) def bounding_box(rcs): rc1 = rcs.min(axis=0) rc2 = rcs.max(axis=0) return rc1, rc2 # slice out a bounding region around each instance, detect the contour and # then offset it back into image coordinates grouped_contours = {} for label, rcs in grouped_cc_rcs.items(): rc1, rc2 = bounding_box(rcs) sl = (slice(rc1[0], rc2[0] + 2), slice(rc1[1], rc2[1] + 2)) submask = (gti[sl] == label).astype(np.uint8) xy_offset = rc1[::-1] offset = xy_offset + [-2, -2] border = cv2.copyMakeBorder(submask, 2, 2, 2, 2, cv2.BORDER_CONSTANT, value=0 ) _, contors, hierarchy = cv2.findContours(border, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE, offset=tuple(offset)) """ offset = [0, 0] BGR_GREEN = (0, 255, 0) x = np.ascontiguousarray(util.ensure_alpha_channel(submask)[:, :, 0:3]).astype(np.uint8) draw_img = cv2.drawContours( image=x, contours=contors, contourIdx=-1, color=BGR_GREEN, thickness=2) """ # note when len(contours > 1, there is a hole in the building) # assert len(contors) == 1 grouped_contours[label] = contors return grouped_contours
def instance_submasks(gti): """ Iterate over a cropped mask for each instance in an instance segmentation Example: >>> gti = np.array([ >>> [0, 0, 5, 5, 5, 2, 2], >>> [0, 0, 5, 5, 5, 2, 2], >>> [0, 0, 0, 0, 0, 0, 0], >>> [0, 0, 0, 1, 9, 0, 0], >>> [3, 0, 0, 1, 1, 0, 0], >>> ], dtype=np.uint8) >>> first, *rest = instance_submasks(gti) >>> (label, submask, rc_off, rc_sl) = first >>> submask array([[1, 0], [1, 1]], dtype=uint8) """ rc_locs = np.where(gti > 0) grouped_cc_rcs = util.group_items( np.ascontiguousarray(np.vstack(rc_locs).T), gti[rc_locs], axis=0 ) def bounding_box(rcs): rc1 = rcs.min(axis=0) rc2 = rcs.max(axis=0) return rc1, rc2 for label, rcs in grouped_cc_rcs.items(): rc1, rc2 = bounding_box(rcs) r_slice = slice(rc1[0], rc2[0] + 1) c_slice = slice(rc1[1], rc2[1] + 1) rc_sl = (r_slice, c_slice) subimg = gti[rc_sl] submask = (subimg == label).astype(np.uint8) rc_off = rc1 yield label, submask, rc_off, rc_sl