def get_slic_points_labels(segm, img=None, slic_size=20, slic_regul=0.1): """ run SLIC on image or supepixels and return superpixels, their centers and also lebels (label from segmentation in position of superpixel centre) :param ndarray segm: :param ndarray img: :param int slic_size: superpixel size :param float slic_regul: regularisation in range (0, 1) :return: """ if img is None: img = segm / float(segm.max()) slic = seg_spx.segment_slic_img2d(img, sp_size=slic_size, rltv_compact=slic_regul) slic_centers = np.array(seg_spx.superpixel_centers(slic)).astype(int) labels = segm[slic_centers[:, 0], slic_centers[:, 1]] return slic, slic_centers, labels
def insert_gc_debug_images(dict_debug_imgs, segments, graph_labels, unary_cost, edges, edge_weights): """ wrapper for placing intermediate variable to a dictionary """ if dict_debug_imgs is None: return dict_debug_imgs['segments'] = segments dict_debug_imgs['edges'] = edges dict_debug_imgs['edge_weights'] = edge_weights dict_debug_imgs['imgs_unary_cost'] = \ tl_visu.draw_graphcut_unary_cost_segments(segments, unary_cost) img = dict_debug_imgs.get('slic_mean', None) list_centres = seg_spx.superpixel_centers(segments) dict_debug_imgs['img_graph_edges'] = \ tl_visu.draw_graphcut_weighted_edges(segments, list_centres, edges, edge_weights, img_bg=img) dict_debug_imgs['img_graph_segm'] = \ tl_visu.draw_color_labeling(segments, graph_labels)
def estim_points_compute_features(name, img, segm, params): """ determine points (center candidates) using slic and for each compute feature vector with their names :param str name: :param ndarray img: :param ndarray segm: :param {str: any} params: :return str, np.array, [(int, int)], [[float]], [str]: """ # superpixels on image assert img.shape[:2] == segm.shape[:2], \ 'shapes: %s : %s' % (repr(img.shape), repr(segm.shape)) slic = seg_spx.segment_slic_img2d(img, params['slic_size'], params['slic_regul']) slic_centers = seg_spx.superpixel_centers(slic) # slic_edges = seg_spx.make_graph_segm_connect2d_conn4(slic) features, feature_names = compute_points_features(segm, slic_centers, params) return name, slic, slic_centers, features, feature_names
def filter_boundary_points(segm, slic): slic_centers = np.array(seg_spx.superpixel_centers(slic)).astype(int) labels = segm[slic_centers[:, 0], slic_centers[:, 1]] vertices, edges = seg_spx.make_graph_segm_connect2d_conn4(slic) nb_labels = labels.max() + 1 neighbour_labels = np.zeros((len(vertices), nb_labels)) for e1, e2 in edges: # print e1, labels[e2], e2, labels[e1] neighbour_labels[e1, labels[e2]] += 1 neighbour_labels[e2, labels[e1]] += 1 neighbour_labels = neighbour_labels \ / np.tile(np.sum(neighbour_labels, axis=1), (nb_labels, 1)).T # border point nex to foreground filter_bg = np.logical_and(labels == 0, neighbour_labels[:, 0] < 1) # fulucul cels next to backround filter_fc = np.logical_and(labels == 1, neighbour_labels[:, 0] > 0) points = slic_centers[np.logical_or(filter_bg, filter_fc)] return points
def compute_edge_weights(segments, image=None, features=None, proba=None, edge_type=''): """ pp 32, http://www.coe.utah.edu/~cs7640/readings/graph_cuts_intro.pdf exp(- norm value diff) * (geom dist vertex)**-1 :param ndarry segments: superpixels :param ndarry image: input image :param ndarry features: features for each segment (superpixel) :param ndarry proba: probability of each superpixel and class :param str edge_type: contains edge type, if 'model', after '_' you can specify the metric, eg. 'model_l2' :return [[int, int]], [float]: >>> segments = np.array([[0] * 3 + [1] * 5 + [2] * 4, ... [4] * 4 + [5] * 5 + [6] * 3]) >>> np.random.seed(0) >>> img = np.random.random(segments.shape + (3,)) * 255 >>> features = np.random.random((segments.max() + 1, 15)) * 10 >>> proba = np.random.random((segments.max() + 1, 2)) >>> edges, weights = compute_edge_weights(segments) >>> edges.tolist() [[0, 1], [1, 2], [0, 4], [1, 4], [1, 5], [2, 5], [4, 5], [2, 6], [5, 6]] >>> np.round(weights, 2).tolist() [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0] >>> edges, weights = compute_edge_weights(segments, image=img, ... edge_type='spatial') >>> np.round(weights, 3).tolist() [0.776, 0.69, 2.776, 0.853, 2.194, 0.853, 0.69, 2.776, 0.776] >>> edges, weights = compute_edge_weights(segments, image=img, ... edge_type='color') >>> np.round(weights, 3).tolist() [0.06, 0.002, 0.0, 0.0, 0.0, 0.009, 0.0, 0.019, 0.044] >>> edges, weights = compute_edge_weights(segments, features=features, ... edge_type='features') >>> np.round(weights, 3).tolist() [0.031, 0.005, 0.051, 0.032, 0.096, 0.013, 0.018, 0.033, 0.013] >>> edges, weights = compute_edge_weights(segments, proba=proba, ... edge_type='model') >>> np.round(weights, 3).tolist() [0.0, 0.028, 1.122, 0.038, 0.117, 0.688, 0.487, 1.152, 0.282] """ logging.debug('extraction segment connectivity...') _, edges = get_vertexes_edges(segments) # convert variables edges = np.array(edges, dtype=np.int32) logging.debug('graph edges %s', repr(edges.shape)) if edge_type.startswith('model'): assert proba is not None metric = edge_type.split('_')[-1] if '_' in edge_type else 'lT' edge_weights = compute_edge_model(edges, proba, metric) elif edge_type == 'color': assert image is not None # {'color': ['mean', 'median']} image_float = np.array(image, dtype=float) if np.max(image) > 1: image_float /= 255. color, _ = seg_fts.compute_selected_features_img2d( image_float, segments, {'color': ['mean']}) vertex_1 = color[edges[:, 0]] vertex_2 = color[edges[:, 1]] dist = metrics.pairwise.paired_manhattan_distances(vertex_1, vertex_2) weights = dist.astype(float) / (2 * np.std(dist)**2) edge_weights = np.exp(-weights) elif edge_type == 'features': assert features is not None features_norm = preprocessing.StandardScaler().fit_transform(features) vertex_1 = features_norm[edges[:, 0]] vertex_2 = features_norm[edges[:, 1]] dist = metrics.pairwise.paired_euclidean_distances(vertex_1, vertex_2) weights = dist.astype(float) / (2 * np.std(dist)**2) edge_weights = np.exp(-weights) else: edge_weights = np.ones(len(edges)) edge_weights = np.array(edge_weights, dtype=float) if edge_type in ['model', 'features', 'color', 'spatial']: centres = seg_spx.superpixel_centers(segments) spatial = compute_spatial_dist(centres, edges, relative=True) edge_weights /= spatial return edges, edge_weights