def rag_solidity(labels, connectivity=2): graph = RAG() # The footprint is constructed in such a way that the first # element in the array being passed to _add_edge_filter is # the central value. fp = ndi.generate_binary_structure(labels.ndim, connectivity) for d in range(fp.ndim): fp = fp.swapaxes(0, d) fp[0, ...] = 0 fp = fp.swapaxes(0, d) # For example # if labels.ndim = 2 and connectivity = 1 # fp = [[0,0,0], # [0,1,1], # [0,1,0]] # # if labels.ndim = 2 and connectivity = 2 # fp = [[0,0,0], # [0,1,1], # [0,1,1]] ndi.generic_filter(labels, function=_add_edge_filter, footprint=fp, mode='nearest', output=np.zeros(labels.shape, dtype=np.uint8), extra_arguments=(graph, )) # remove bg_label # graph.remove_node(-1) graph.remove_node(0) for n in graph: mask = (labels == n) solidity = 1. * mask.sum() / convex_hull_image(mask).sum() graph.node[n].update({ 'labels': [n], 'solidity': solidity, 'mask': mask }) if LooseVersion(networkx.__version__) >= '2': edges_iter = graph.edges(data=True) else: edges_iter = graph.edges_iter(data=True) for x, y, d in edges_iter: new_mask = np.logical_or(graph.node[x]['mask'], graph.node[y]['mask']) new_solidity = 1. * new_mask.sum() / convex_hull_image(new_mask).sum() org_solidity = np.mean( [graph.node[x]['solidity'], graph.node[y]['solidity']]) d['weight'] = org_solidity / new_solidity return graph
def _solidity_weight_func(graph, src, dst, n): """Callback to handle merging nodes by recomputing solidity.""" org_solidity = np.mean([graph.node[src]['solidity'], graph.node[dst]['solidity']]) new_mask1 = np.logical_or(graph.node[src]['mask'], graph.node[n]['mask']) new_mask2 = np.logical_or(graph.node[dst]['mask'], graph.node[n]['mask']) new_solidity1 = 1. * new_mask1.sum() / convex_hull_image(new_mask1).sum() new_solidity2 = 1. * new_mask2.sum() / convex_hull_image(new_mask2).sum() weight1 = org_solidity / new_solidity1 weight2 = org_solidity / new_solidity2 return min([weight1, weight2])
def _solidity_weight_func(graph, src, dst, n): """Callback to handle merging nodes by recomputing solidity.""" org_solidity = np.mean( [graph.node[src]['solidity'], graph.node[dst]['solidity']]) new_mask1 = np.logical_or(graph.node[src]['mask'], graph.node[n]['mask']) new_mask2 = np.logical_or(graph.node[dst]['mask'], graph.node[n]['mask']) new_solidity1 = 1. * new_mask1.sum() / convex_hull_image(new_mask1).sum() new_solidity2 = 1. * new_mask2.sum() / convex_hull_image(new_mask2).sum() weight1 = org_solidity / new_solidity1 weight2 = org_solidity / new_solidity2 return {'weight': min([weight1, weight2])}
def rag_solidity(labels, connectivity=2): graph = RAG() # The footprint is constructed in such a way that the first # element in the array being passed to _add_edge_filter is # the central value. fp = ndi.generate_binary_structure(labels.ndim, connectivity) for d in range(fp.ndim): fp = fp.swapaxes(0, d) fp[0, ...] = 0 fp = fp.swapaxes(0, d) # For example # if labels.ndim = 2 and connectivity = 1 # fp = [[0,0,0], # [0,1,1], # [0,1,0]] # # if labels.ndim = 2 and connectivity = 2 # fp = [[0,0,0], # [0,1,1], # [0,1,1]] ndi.generic_filter( labels, function=_add_edge_filter, footprint=fp, mode='nearest', output=np.zeros(labels.shape, dtype=np.uint8), extra_arguments=(graph,)) # remove bg_label # graph.remove_node(-1) graph.remove_node(0) for n in graph: mask = (labels == n) solidity = 1. * mask.sum() / convex_hull_image(mask).sum() graph.node[n].update({'labels': [n], 'solidity': solidity, 'mask': mask}) for x, y, d in graph.edges_iter(data=True): new_mask = np.logical_or(graph.node[x]['mask'], graph.node[y]['mask']) new_solidity = 1. * new_mask.sum() / convex_hull_image(new_mask).sum() org_solidity = np.mean([graph.node[x]['solidity'], graph.node[y]['solidity']]) d['weight'] = org_solidity / new_solidity return graph
def convex_image(self): # TODO: grlee77: avoid host/device transfers # from ..morphology.convex_hull import convex_hull_image from skimage.morphology.convex_hull import convex_hull_image # CuPy Backend: copy required here to avoid unexpected behavior # reported in https://github.com/cupy/cupy/issues/4354 return cp.asarray(convex_hull_image(cp.asnumpy(self.image))).copy()
def infer_order_hull(inmodal): num = inmodal.shape[0] order_matrix = np.zeros((num, num), dtype=np.int) occ_value_matrix = np.zeros((num, num), dtype=np.float32) for i in range(num): for j in range(i + 1, num): if bordering(inmodal[i], inmodal[j]): amodal_i = convex_hull.convex_hull_image(inmodal[i]) amodal_j = convex_hull.convex_hull_image(inmodal[j]) occ_value_matrix[i, j] = ((amodal_i > inmodal[i]) & (inmodal[j] == 1)).sum() occ_value_matrix[j, i] = ((amodal_j > inmodal[j]) & (inmodal[i] == 1)).sum() order_matrix[occ_value_matrix > occ_value_matrix.transpose()] = -1 order_matrix[occ_value_matrix < occ_value_matrix.transpose()] = 1 order_matrix[(occ_value_matrix == 0) & (occ_value_matrix == 0).transpose()] = 0 return order_matrix
def infer_amodal_hull(inmodal, bboxes, order_matrix, order_grounded=True): amodal = [] num = inmodal.shape[0] for i in range(num): m = inmodal[i] hull = convex_hull.convex_hull_image(m).astype(np.uint8) if order_grounded: assert order_matrix is not None ancestors = get_ancestors(order_matrix, i) eraser = (inmodal[ancestors, ...].sum(axis=0) > 0).astype( np.uint8) # union hull[(eraser == 0) & (m == 0)] = 0 amodal.append(hull) return amodal
def _rotate_tooth_image(image, mt_masks): """ Rotate the tooth image by using the gravity centers of mineralized tissues. Parameters ---------- image: PIL.Image The initial tooth image mt_masks: [np.array] List of masks of mineralized tissues Returns ------- (angle, angle deg, rotated image) angle: float The rotation angle in radiangs angle deg: float The rotation angle in degrees rotated image: PIL.Image The tooth image, rotated rotated mt masks: [np.array] A list of rotated masks """ from skimage.morphology.convex_hull import convex_hull_image mt_merged_mask = np.zeros(mt_masks[0].shape) for mask in mt_masks: mt_merged_mask[mask > 0] = 1 hull_mask = convex_hull_image(mt_merged_mask) hull_gc = _mask_gravity_center(hull_mask) hull_gc = (int(hull_gc[1]), int(hull_gc[0])) mt_merged_gc = _mask_gravity_center(mt_merged_mask) mt_merged_gc = (int(mt_merged_gc[1]), int(mt_merged_gc[0])) angle = math.atan2(mt_merged_gc[1] - hull_gc[1], mt_merged_gc[0] - hull_gc[0]) + math.pi / 2 angle_deg = angle * 180 / math.pi rotated_image = image.rotate(angle_deg, expand=True) rotated_mt_masks = [ _pillow_image_to_np_binary(_np_binary_to_pillow_image(mt_mask).rotate(angle_deg, expand=True)) for mt_mask in mt_masks] return (angle, angle_deg, rotated_image, rotated_mt_masks)
def star(a, dtype=np.uint8): """Generates a star shaped structuring element. Much faster than skimage.morphology version """ if a == 1: bfilter = np.zeros((3, 3), dtype) bfilter[:] = 1 return bfilter m = 2 * a + 1 n = a // 2 selem_square = np.zeros((m + 2 * n, m + 2 * n), dtype=np.uint8) selem_square[n:m + n, n:m + n] = 1 c = (m + 2 * n - 1) // 2 if True: # We can do this much faster with opencv b = (m + 2 * n) - 1 vertices = np.array([ [0, c], [c, 0], [b, c], [c, b], [0, c], ]) pts = vertices.astype(int)[:, None, :] mask = np.zeros_like(selem_square) mask = cv2.fillConvexPoly(mask, pts, color=1) selem_rotated = mask else: from skimage.morphology.convex_hull import convex_hull_image selem_rotated = np.zeros((m + 2 * n, m + 2 * n), dtype=np.float32) selem_rotated[0, c] = selem_rotated[-1, c] = 1 selem_rotated[c, 0] = selem_rotated[c, -1] = 1 selem_rotated = convex_hull_image(selem_rotated).astype(int) selem = np.add(selem_square, selem_rotated, out=selem_square) selem[selem > 0] = 1 return selem.astype(dtype)
def _solidity_merge_func(graph, src, dst): """Callback called before merging two nodes of a solidity graph.""" new_mask = np.logical_or(graph.node[src]['mask'], graph.node[dst]['mask']) graph.node[dst]['mask'] = new_mask graph.node[dst]['solidity'] = \ 1. * np.sum(new_mask) / np.sum(convex_hull_image(new_mask))
def calculate_df(event_path,oi_stage): # initialize lists to hold data across events mask_array = [] time_array = [] perimeter_array = [] area_array = [] circ_array = [] deform_array = [] r_um_array = [] xcm_pix_array, ycm_pix_array = [],[] xcm_um_array, ycm_um_array = [],[] tf_array = [] event = [] perimeter_array_cx = [] area_array_cx = [] circ_array_cx = [] deform_array_cx = [] r_um_array_cx = [] ellipse_xc_um_array = [] ellipse_yc_um_array = [] ellipse_a_array, ellipse_b_array = [],[] aspect_array = [] r_um_elps_array = [] df_raw = pd.read_pickle(event_path) for j in df_raw.keys(): num = len(df_raw[j]['mask']) xcm_pix = np.empty(num) ycm_pix = np.empty(num) xcm_um = np.empty(num) ycm_um = np.empty(num) area = np.empty(num) per = np.empty(num) circ = np.empty(num) deform = np.empty(num) r_um = np.empty(num) tf = np.empty(num) masks = [] area_cx = np.empty(num) per_cx = np.empty(num) circ_cx = np.empty(num) deform_cx = np.empty(num) r_um_cx = np.empty(num) ellipse_xc_um = np.empty(num) ellipse_yc_um = np.empty(num) ellipse_a = np.empty(num) ellipse_b = np.empty(num) aspect = np.empty(num) r_um_elps = np.empty(num) for i in range(num): frame = np.reshape(df_raw[j]['mask'][i],(140,880)) masks.append(frame) hull = convex_hull.convex_hull_image(frame) xpix = np.where(frame==1)[1] ypix = np.where(frame==1)[0] xc_pix ,yc_pix = oi_stage.get_channel_coordinates(xpix, ypix) xc_um = oi_stage.pixels_to_meters(xc_pix) yc_um = oi_stage.pixels_to_meters(yc_pix) xcm_pix = np.mean(xc_pix) ycm_pix = np.mean(yc_pix) xcm_um[i] = np.mean(xc_um) ycm_um[i] = np.mean(yc_um) area[i] = np.sum(frame) per[i] = measure.perimeter(frame) circ[i] = 2*np.sqrt(np.pi)*np.sqrt(area[i])/per[i] deform[i] = 1 - circ[i] r_um[i] = (oi_stage.pixels_to_meters(np.sqrt(area[i]/np.pi))+oi_stage.pixels_to_meters(per[i]/(2*np.pi)))/2 tf[i] = df_raw[j]['time'][i] area_cx[i] = np.sum(hull) per_cx[i] = measure.perimeter(hull) circ_cx[i] = 2*np.sqrt(np.pi)*np.sqrt(area[i])/per[i] deform_cx[i] = 1 - circ[i] r_um_cx[i] = (oi_stage.pixels_to_meters(np.sqrt(area[i]/np.pi))+oi_stage.pixels_to_meters(per[i]/(2*np.pi)))/2 #ellipse_pixels = np.where(processed_frame == 1) ellipse = oi.fit_ellipse_image_aligned(xpix, ypix) ellipse_x, ellipse_y = oi.get_ellipse_center(ellipse) ellipse_xc,ellipse_yc = oi_stage.get_channel_coordinates(ellipse_x,ellipse_y) ellipse_xc_um[i] = oi_stage.pixels_to_meters(ellipse_xc) ellipse_yc_um[i] = oi_stage.pixels_to_meters(ellipse_yc) ellipse_a[i], ellipse_b[i] = oi.get_ellipse_axes_lengths(ellipse) aspect[i] = ellipse_a[i]/ellipse_b[i] r_um_elps[i] = np.sqrt(ellipse_a[i]*ellipse_b[i]) event.append(j) mask_array.append(masks) time_array.append(tf) perimeter_array.append(per) area_array.append(area) circ_array.append(circ) deform_array.append(deform) r_um_array.append(r_um) xcm_um_array.append(xcm_um) ycm_um_array.append(ycm_um) perimeter_array_cx.append(per_cx) area_array_cx.append(area_cx) circ_array_cx.append(circ_cx) deform_array_cx.append(deform_cx) r_um_array_cx.append(r_um_cx) ellipse_xc_um_array.append(ellipse_xc_um) ellipse_yc_um_array.append(ellipse_yc_um) ellipse_a_array.append(ellipse_a) ellipse_b_array.append(ellipse_b) aspect_array.append(aspect) r_um_elps_array.append(r_um_elps) d = {'event':event,'tf':time_array,'mask':mask_array,'perimeter':perimeter_array,'area':area_array, 'circ':circ_array,'deform':deform_array,'r_um':r_um_array,'xcm_um':xcm_um_array,'yc_um':ycm_um_array, 'perimeter_cx':perimeter_array_cx,'area_cx':area_array_cx,'circ_cx':circ_array_cx,'deform_cx':deform_array_cx, 'r_um_cx':r_um_array_cx,'xc_um_el':ellipse_xc_um_array,'yc_um_el':ellipse_yc_um_array,'a':ellipse_a_array, 'b':ellipse_b_array,'aspect':aspect_array,'r_um_el':r_um_elps_array} df = pd.DataFrame(data=d) df['cell'] = particle_type df['date'] = date df['run'] = file_index #Remove events with empty time series. Artifact of event detection df = df[df.tf.map(lambda a: a.size!=0)] return df
def convex_image(self): # from ..morphology.convex_hull import convex_hull_image # TODO: grlee77: avoid host/device transfers from skimage.morphology.convex_hull import convex_hull_image return cp.asarray(convex_hull_image(cp.asnumpy(self.image)))
def bug_tertiary(): rp = regionprops(SAMPLE)[0] img = rp.image conv_img = convex_hull_image(img) return
def localize_apices_engine(image, mt_masks, debug=False, output_dir='.', image_name=''): # load the masks # check the mask length if len(mt_masks) < 2: raise ValueError('2 MT masks are needed to infer') mt_masks = utils._find_greatest_mt_masks(mt_masks) angle, _, rotated_image, mt_masks = utils._rotate_tooth_image( image, mt_masks) width, height = rotated_image.size apical_mt_mask, coronal_mt_mask = mt_masks mt_merged_mask = apical_mt_mask | coronal_mt_mask # gradient cancel masks coronal_distance = ndi.distance_transform_edt( np.where(coronal_mt_mask > 0, 0, 1)) apical_distance = ndi.distance_transform_edt( np.where(apical_mt_mask > 0, 0, 1)) hull = convex_hull_image(apical_mt_mask | coronal_mt_mask) cancel_mask = np.where( np.abs(coronal_distance - apical_distance) < 2, 1, 0) thin_cancel_mask = skeletonize(cancel_mask) & hull apical_hull = convex_hull_image(apical_mt_mask) utils._apply_mask_to_image(rotated_image, cancel_mask, (0, 255, 0)) utils._apply_mask_to_image(rotated_image, thin_cancel_mask, (255, 255, 0), alpha=1) utils._apply_mask_to_image(rotated_image, coronal_mt_mask, (255, 0, 0), alpha=0.2) utils._apply_mask_to_image(rotated_image, apical_hull, (0, 0, 255), alpha=0.2) # display outlines coronal_outline, apical_outline, coronal_outline_mask, apical_outline_mask = display_outlines( rotated_image, coronal_mt_mask, apical_mt_mask) # display hull utils._apply_mask_to_image(rotated_image, hull, (255, 0, 255), alpha=0.05) # temporary endpoints temporary_endpoints = get_temporary_endpoints(rotated_image, thin_cancel_mask, hull) if len(temporary_endpoints) < 2: _logger.error( 'can not find endpoints if less than 2 potential endpoints') return coronal_dp_points, apical_dp_points = get_dp_points( width, height, rotated_image, thin_cancel_mask, apical_outline_mask, apical_mt_mask, coronal_outline_mask, coronal_mt_mask) # get the split points apical_split_point, coronal_split_point = get_dentin_pulp_split_points( rotated_image, coronal_mt_mask, apical_mt_mask, coronal_outline, apical_outline, coronal_outline_mask, apical_outline_mask) utils._add_mark(rotated_image, apical_split_point, (255, 128, 0)) utils._add_mark(rotated_image, coronal_split_point, (255, 128, 0)) apical_dp_points.append(apical_split_point) coronal_dp_points.append(coronal_split_point) # reorder the points ordered_apical_dp_points = reorder_dentin_pulp_points( apical_dp_points, apical_outline) ordered_coronal_dp_points = reorder_dentin_pulp_points( coronal_dp_points, coronal_outline) for point in ordered_apical_dp_points + ordered_coronal_dp_points: rotated_image.putpixel(point, (255, 128, 0)) # clean the dp points left_middle_endpoint, right_middle_endpoint = temporary_endpoints[ 0], temporary_endpoints[1] if left_middle_endpoint[0] > right_middle_endpoint[0]: left_middle_endpoint, right_middle_endpoint = right_middle_endpoint, left_middle_endpoint left_coronal_points, left_apical_points, right_apical_points, right_coronal_points = clean_dp_points( rotated_image, temporary_endpoints, apical_split_point, coronal_split_point, ordered_apical_dp_points, ordered_coronal_dp_points, mt_merged_mask) # find the new endpoints draw = ImageDraw.Draw(rotated_image) endpoint_pairs = select_endpoint_pairs( left_middle_endpoint, right_middle_endpoint, left_coronal_points, left_apical_points, right_apical_points, right_coronal_points) for endpoint_pair in endpoint_pairs: for point in endpoint_pair: utils._add_mark(rotated_image, point, (255, 0, 0)) draw.line(endpoint_pair, (255, 0, 0)) (tooth_height, min_y, max_y) = utils._get_tooth_height(apical_mt_mask | coronal_mt_mask) draw.line((width // 2, min_y, width // 2, max_y), (0, 0, 255)) (i3m, min_apex_opening, max_apex_opening) = utils._compute_i3m(endpoint_pairs, tooth_height) result = { 'output_image': rotated_image, 'I3M': i3m, 'min_apex_opening': min_apex_opening, 'max_apex_opening': max_apex_opening, 'height': tooth_height } # draw the rotated image if debug if debug: image_path = os.path.join(output_dir, f'{image_name}-debug.png') rotated_image.save(image_path) return result
def segment_lesion(image, mode="KMeans"): ## Unsupervised Segmentation # K-Means Clustering if (mode == "KMeans"): # K-Means Clustering deim = denoise(cv2.cvtColor(image, cv2.COLOR_RGB2GRAY), weight=150) kmeans = KMeans(n_clusters=2, random_state=0, n_jobs=-1).fit(deim.reshape(-1, 1)) mask = (kmeans.labels_).reshape(deim.shape[0], deim.shape[1]).astype('uint8') # Expectation-Maximization Gaussian Mixture Model elif (mode == "EM"): # K-Means Clustering feature_vector = (denoise(cv2.cvtColor(image, cv2.COLOR_RGB2GRAY), weight=150)).reshape(-1, 1) kmeans = KMeans(n_clusters=2, random_state=0, n_jobs=-1).fit(feature_vector) KMpredict = kmeans.predict(feature_vector) # Expectation Step: Initialization with K-Means KM_BG = feature_vector[KMpredict == 0] KM_FG = feature_vector[KMpredict == 1] # Expectation Step: Mean and Covariance mean_BG = np.mean(KM_BG, axis=0) mean_FG = np.mean(KM_FG, axis=0) covar_BG = np.cov(KM_BG, rowvar=False) covar_FG = np.cov(KM_FG, rowvar=False) # Expectation Step: Prior Probabilities prob_BG = KM_BG.shape[0] / feature_vector.shape[0] prob_FG = KM_FG.shape[0] / feature_vector.shape[0] # Iterative Update min_change = 0.01 max_steps = 5 for i in range(max_steps): # Expectation Step: Probability Density Function PDF_BG = multivariate_normal.pdf(feature_vector, mean=mean_BG, cov=covar_BG) PDF_FG = multivariate_normal.pdf(feature_vector, mean=mean_FG, cov=covar_FG) weights_BG = (prob_BG * PDF_BG) / ((prob_FG * PDF_FG) + (prob_BG * PDF_BG)) weights_FG = (prob_FG * PDF_FG) / ((prob_FG * PDF_FG) + (prob_BG * PDF_BG)) weights = np.concatenate( (weights_BG.reshape(-1, 1), weights_FG.reshape(-1, 1)), axis=1) log_B = sum((np.log(sum(weights)))) # Maximization Step: New Probabilities _, counts = np.unique(np.argmax(weights, axis=1), return_counts=True) prob_BG = counts[0] / feature_vector.shape[0] prob_FG = counts[1] / feature_vector.shape[0] # Maximization Step: New Mean and Covariance mean_BG = (1 / counts[0]) * (weights[:, 0] @ feature_vector) mean_FG = (1 / counts[1]) * (weights[:, 1] @ feature_vector) covar_BG = (1 / counts[0]) * ( weights[:, 0] * np.transpose(feature_vector - mean_BG)) @ ( feature_vector - mean_BG) covar_FG = (1 / counts[1]) * ( weights[:, 1] * np.transpose(feature_vector - mean_FG)) @ ( feature_vector - mean_FG) # Maximization Step: Probability Density Function PDF_BG = multivariate_normal.pdf(feature_vector, mean=mean_BG, cov=covar_BG) PDF_FG = multivariate_normal.pdf(feature_vector, mean=mean_FG, cov=covar_FG) weights_BG = (prob_BG * PDF_BG) / ((prob_FG * PDF_FG) + (prob_BG * PDF_BG)) weights_FG = (prob_FG * PDF_FG) / ((prob_FG * PDF_FG) + (prob_BG * PDF_BG)) weights = np.concatenate( (weights_BG.reshape(-1, 1), weights_FG.reshape(-1, 1)), axis=1) log_N = sum((np.log(sum(weights)))) # Update Trackers, Verify Conditions change_log = np.linalg.norm(log_N - log_B) if (change_log <= min_change): continue else: break # Output Image Reconstruction mask = (np.argmax(weights, axis=1)).reshape(-1, 1) mask = np.reshape(mask, (image.shape[0], image.shape[1])).astype('uint8') # Chan-Vese Active Contours elif (mode == "active_contours"): # Morphological ACWE image = img_as_float(cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)) # Initial level Set init_ls = checkerboard_level_set(image.shape, 6) # List with Intermediate Results for Plotting the Evolution evolution = [] callback = store_evolution_in(evolution) mask = morphological_chan_vese(image, 5, init_level_set=init_ls, smoothing=10, iter_callback=callback).astype(np.uint8) # Watershed elif (mode == "mod_watershed"): ret, thresh = cv2.threshold(cv2.cvtColor(image, cv2.COLOR_RGB2GRAY), 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU) kernel = np.ones((3, 3), np.uint8) opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=2) sure_bg = cv2.dilate(opening, kernel, iterations=3) dist_transform = cv2.distanceTransform(opening, cv2.DIST_L2, 5) ret, sure_fg = cv2.threshold(dist_transform, 0.01 * dist_transform.max(), 255, 0) ls = np.uint8(sure_fg) / 255 circle_mask = create_circular_mask(image.shape[0], image.shape[1], radius=220) ls = ls * circle_mask # Discard Edge-to-Edge Connected Component large = getLargestCC(ls).astype(np.uint8) if (corner_mean(large) > 1): large = getLargestCC(ls - large).astype(np.uint8) # Post-Process Masks post = ndimage.binary_fill_holes(large, structure=np.ones( (5, 5))).astype(bool) else: print("ERROR: Undefined Segmentation Mode") ## Segmentation Label Selection # Define Target Scope candidate_mask_1 = mask.copy() * create_circular_mask( image.shape[0], image.shape[1], radius=230) candidate_mask_2 = (np.invert(mask.copy()) + 2) * create_circular_mask( image.shape[0], image.shape[1], radius=230) # Compute Area of Convex Hulls convex_hull_1 = convex_hull_image(candidate_mask_1) convex_hull_2 = convex_hull_image(candidate_mask_2) # Set Segmentation Component Labels kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (10, 10)) if (np.sum(convex_hull_1) < np.sum(convex_hull_2)): dilation = cv2.dilate(candidate_mask_1, kernel, iterations=1) mask = ndimage.binary_fill_holes(dilation, structure=np.ones((5, 5))) else: dilation = cv2.dilate(candidate_mask_2, kernel, iterations=1) mask = ndimage.binary_fill_holes(dilation, structure=np.ones((5, 5))) if (np.sum(mask) < 5000): mask = create_circular_mask(image.shape[0], image.shape[1], radius=230) return mask
def bug_quaternary(): img = SAMPLE.astype(np.bool) conv_img = convex_hull_image(img) return