def mergeSuperpixels( superpixels, rgb_frame, sat_frame, depth_frame, rgb_thresh=55, sat_thresh=0.20, depth_thresh=25): if rgb_thresh >= 0: rgb_rag = graph.rag_mean_color(rgb_frame, superpixels) sp_merged_rgb = graph.cut_threshold(superpixels, rgb_rag, rgb_thresh) sp_joined = sp_merged_rgb if sat_thresh >= 0: sat_rag = graph.rag_mean_color(sat_frame, superpixels) sp_merged_sat = graph.cut_threshold(superpixels, sat_rag, sat_thresh) if rgb_thresh >= 0: sp_joined = segmentation.join_segmentations( sp_joined, sp_merged_sat) if depth_thresh >= 0: depth_rag = graph.rag_mean_color(depth_frame, superpixels) sp_merged_depth = graph.cut_threshold( superpixels, depth_rag, depth_thresh) if sat_thresh >= 0: sp_joined = segmentation.join_segmentations( sp_joined, sp_merged_depth) return sp_joined
def mejorar_pluma(array, n_segments=2000): """Function to improve the ash footprint shape with RAG filtering. Parameters -------------------------------------------------- array : 2D array image with nonzero values for all the pixels above 0. n_segments : Number of pixels for the RAG filtering. The value of 2000 is selected by empiricaly observation. More pixels during the rearrange values output -------------------------------------------------- filtered array with the dilate-closed object. """ # equalizar histograma para unicamente negativos arreq = muestra_banda(array).reshape(array.shape) arreq = arreq.astype(int) labels1 = segmentation.slic(arreq, compactness=30, n_segments=n_segments) out1 = color.label2rgb(labels1, arreq, kind='avg') gra = graph.rag_mean_color(arreq, labels1) labels2 = graph.cut_threshold(labels1, gra, 29) out2 = color.label2rgb(labels2, arreq, kind='avg') fig, axe = plt.subplots(nrows=2, sharex=True, sharey=True, figsize=(6, 8)) axe[0].imshow(out1) ma = axe[1].imshow(out2) fig.colorbar(ma) for a in axe: a.axis('off') plt.tight_layout() fig.show() return fig, out1, out2
def merge_clusters(self, segmented_image, threshold=5): """Merge tiny superpixel clusters. Superpixel segmentations result in oversegmented images. Based on graph theoretic tools, similar clusters are merged. Parameters ---------- segmented_image : ndarray Label image, output of a segmentation. threshold : float, optional Regions connected by edges with smaller weights are combined. Returns ------- merged_superpixels : ndarray The new labelled array. """ if self.__stored_graph is None: # Region Adjacency Graph (RAG) not yet determined -> compute it g = graph.rag_mean_color(self.original_image, segmented_image) self.__stored_graph = g else: g = self.__stored_graph merged_superpixels = graph.cut_threshold(segmented_image, g, threshold, in_place=False) if self.__interactive_mode: io.imshow(color.label2rgb(merged_superpixels, self.original_image, kind='avg')) io.show() print('Tiny clusters merged. ' 'Number of segments: {0}'.format(np.amax(merged_superpixels))) return merged_superpixels
def preview(self, ips, para): lab = self.app.get_img(para['lab']).img connect = ['4-connected', '8-connected'].index(para['connect']) + 1 g = graph.rag_mean_color(ips.snap, lab, connect, para['mode'], para['sigma']) lab = graph.cut_threshold(lab, g, para['thresh']) ips.img[:] = color.label2rgb(lab, ips.snap, kind='avg')
def test_rag_hierarchical(): img = np.zeros((8, 8, 3), dtype='uint8') labels = np.zeros((8, 8), dtype='uint8') img[:, :, :] = 31 labels[:, :] = 1 img[0:4, 0:4, :] = 10, 10, 10 labels[0:4, 0:4] = 2 img[4:, 0:4, :] = 20, 20, 20 labels[4:, 0:4] = 3 g = graph.rag_mean_color(img, labels) g2 = g.copy() thresh = 20 # more than 11*sqrt(3) but less than result = merge_hierarchical_mean_color(labels, g, thresh) assert (np.all(result[:, :4] == result[0, 0])) assert (np.all(result[:, 4:] == result[-1, -1])) result = merge_hierarchical_mean_color(labels, g2, thresh, in_place_merge=True) assert (np.all(result[:, :4] == result[0, 0])) assert (np.all(result[:, 4:] == result[-1, -1])) result = graph.cut_threshold(labels, g, thresh) assert np.all(result == result[0, 0])
def create_annotation_by_changing_colors(path_to_image: str) -> str: """ Creates an annotation by replacing each color of original image with closest (by euclidean distance) color from a list of annotation colors :param path_to_image: Path to original image :return: Path to created annotation """ # Read image image = cv2.imread(path_to_image) # Perform image segmentation labels = sgm.slic(image, n_segments=400, compactness=30) # Use average color for segments segmented_image = clr.label2rgb(labels, image, kind="avg") # Now let's make difference even more smoother with cuttting by threshold labels = grh.cut_threshold(labels, grh.rag_mean_color(segmented_image, labels), thresh=29) # And apply new labels segmented_image = clr.label2rgb(labels, segmented_image, kind="avg") # Prepare K-means cluster (use 4 clusters since annotation should have 4 colors) model = cls.KMeans(n_clusters=4) pixels = segmented_image.reshape(image.shape[0] * image.shape[1], 3) # Cluster pixels of segmented image model.fit(pixels) # Create an annotation annotation = np.ravel(ANNOTATION_COLORS[model.labels_]).reshape( image.shape).astype(np.uint8) image_file_name = os.path.splitext(os.path.basename(path_to_image))[-2] path_to_annotation = "%s%s" % (os.path.join(os.path.dirname(path_to_image), "%s_sem" % image_file_name), os.path.splitext( os.path.basename(path_to_image))[-1]) # Save annotation cv2.imwrite(path_to_annotation, annotation) # Return a path to an annotation file return path_to_annotation
def test_rag_hierarchical(): img = np.zeros((8, 8, 3), dtype='uint8') labels = np.zeros((8, 8), dtype='uint8') img[:, :, :] = 31 labels[:, :] = 1 img[0:4, 0:4, :] = 10, 10, 10 labels[0:4, 0:4] = 2 img[4:, 0:4, :] = 20, 20, 20 labels[4:, 0:4] = 3 g = graph.rag_mean_color(img, labels) g2 = g.copy() thresh = 20 # more than 11*sqrt(3) but less than result = merge_hierarchical_mean_color(labels, g, thresh) assert(np.all(result[:, :4] == result[0, 0])) assert(np.all(result[:, 4:] == result[-1, -1])) result = merge_hierarchical_mean_color(labels, g2, thresh, in_place_merge=True) assert(np.all(result[:, :4] == result[0, 0])) assert(np.all(result[:, 4:] == result[-1, -1])) result = graph.cut_threshold(labels, g, thresh) assert np.all(result == result[0, 0])
def superpixel_extraction(image_i): """ Extracts regions from image and refines segmentation with graph cut :param image_i: input image of shape (N, M, 3) :return: label matrix of shape (N, M, 1) """ image = image_i.copy() image = image[:, :, ::-1] edges, top_left, bottom_right = perform_canny_edge_detection(image=image) grabbed_object = perform_grabcut_segmentation(image=image, top_left_point=top_left, bottom_right_point=bottom_right) frontal_face, frontal_face_bbox = find_frontal_face(image=image, classifier_path='data/face.xml') if frontal_face is None: frontal_face, frontal_face_bbox = find_frontal_face(image=image, classifier_path='data/profile.xml') if frontal_face is not None: skin_mask, hair_mask = get_subtraction_masks_for_skin_and_hair(image=image, face=frontal_face) result = grabbed_object.copy() result[skin_mask == 255] = [255, 255, 255] result[hair_mask == 255] = [255, 255, 255] x, y, w, h = frontal_face_bbox top_left = list(top_left) top_left[1] += h result = perform_grabcut_segmentation(image=result.copy(), top_left_point=top_left, bottom_right_point=bottom_right, iterations=1) else: result = grabbed_object.copy() result = result[:, :, ::-1] labels = segmentation.slic(image=result, n_segments=200, convert2lab=True, max_iter=100, min_size_factor=0.01, max_size_factor=3, compactness=100) # labels = segmentation.quickshift(image, ratio=1, sigma=0.8, max_dist=20, convert2lab=True, kernel_size=10) rag = graph.rag_mean_color(image=color.rgb2lab(result), labels=labels) return graph.cut_threshold(labels=labels, rag=rag, thresh=3.5)
def segFelzenszwalb(sub_templateg, ragthreshold=35, scale=100, sigma=0, min_size=3): #print('Segmenting...') #sub_templateg = border_remove(sub_templateg) #s = timer() segmentos = felzenszwalb(sub_templateg, scale=scale, sigma=sigma, min_size=min_size) n_zeros = np.count_nonzero(segmentos) if n_zeros > 0: #print('Computing RAG...') rag = graph.rag_mean_color(sub_templateg, segmentos, mode='distance') new_labels = graph.cut_threshold(segmentos, rag, ragthreshold) segmentos = clear_border(new_labels) #e = timer() #print('Segmentation Done! ', round((e - s) / 60, 3), ' min') # print('tempo Felzenszwalb', len(np.unique(segmentos))) print('Felzemwalb Segmentation for giants') plt.figure('Felzemwalb Segmentation for giants', figsize=(10, 8)) plt.imshow(mark_boundaries(sub_templateg, segmentos, color=(1, 0, 0))) plt.axis('off') plt.show() return segmentos
def get_rag_labels_signal(self): """Main working horse. Calculates the RAG, its corresponding labels and graph signal. """ # first we create an initial RAG based on the k-means # segmentation rag = graph.rag_mean_color(self.image_tensor, self.segmentation_labels) labels = graph.cut_threshold(self.segmentation_labels, rag, thresh=20) # create rag from these new labels rag = graph.rag_mean_color(self.image_tensor, labels) # add 1 so labels start at 1 labels = labels + 1 # We will add a few more node attributes properties = measure.regionprops(labels) # we will create the graph signal now as well # so we only have to iterate through all the regions once. X = [] # properties now contains a dict of various things that # we can calculate for each region. It is indexed by label. for region in rag.nodes: idx = region # get corresponding properties props = properties[idx] # get centeroid and normalise it centroid_x, centroid_y = props.centroid centroid_x = centroid_x / self.width centroid_y = centroid_y / self.height # get orientation of region orientation = props.orientation # update node rag.nodes[idx]["centroid"] = [centroid_x, centroid_y] rag.nodes[idx]["orientation"] = orientation # turn all the node attributes into an ordered array # and append it as a row to the graph signal X.append(attributes2array(rag.nodes[idx])) # stack X rows to create one array X = np.stack(X) return (rag, labels, X)
def clustering_RAG(img, op="disc", test=False): to_plot = [] img_red = img[:, :, 0] if test: to_plot.append(("red_chan", img)) (ancho, alto) = img_red.shape rr, cc = ellipse(ancho / 2, alto / 2, (ancho / 2), (alto / 2)) mask_background = np.zeros((ancho, alto)) > 0 mask_background[rr, cc] = 1 """ Clustering k-means type """ if op == "disc": labels1 = segmentation.slic(img, mask=mask_background, n_segments=250, compactness=15, sigma=1, start_label=1) out1 = color.label2rgb(labels1, img) if test: to_plot.append(("Cluster1", out1)) g = graph.rag_mean_color(img, labels1, mode='similarity') labels2 = graph.cut_normalized(labels1, g) if op == "cup": labels1 = segmentation.slic(img, mask=mask_background, n_segments=100, compactness=10, sigma=1, start_label=1) out1 = color.label2rgb(labels1, img) if test: to_plot.append(("Cluster2", out1)) g = graph.rag_mean_color(img, labels1) g = graph.rag_mean_color(img, labels1, mode='similarity') labels2 = graph.cut_threshold(labels1, g, 500) out2 = color.label2rgb(labels2, img) if test: to_plot.append(("RAGs", out2)) if test: vi.plot_multy(to_plot, 1, 3, 'K-means + RAGs')
def test_threshold_cut(): img = np.zeros((100, 100, 3), dtype='uint8') img[:50, :50] = 255, 255, 255 img[:50, 50:] = 254, 254, 254 img[50:, :50] = 2, 2, 2 img[50:, 50:] = 1, 1, 1 labels = np.zeros((100, 100), dtype='uint8') labels[:50, :50] = 0 labels[:50, 50:] = 1 labels[50:, :50] = 2 labels[50:, 50:] = 3 rag = graph.rag_mean_color(img, labels) new_labels = graph.cut_threshold(labels, rag, 10, in_place=False) # Two labels assert new_labels.max() == 1 new_labels = graph.cut_threshold(labels, rag, 10) # Two labels assert new_labels.max() == 1
def create_RAG(image_path, compactness, num_segments, threshold): img_org = Image.open(image_path) img = np.array(img_org, dtype=np.float32) labels1 = segmentation.slic(img_org, compactness=compactness, n_segments=num_segments) out1 = color.label2rgb(labels1, img, kind='avg') g = graph.rag_mean_color(img, labels1) labels2 = graph.cut_threshold(labels1, g, threshold) out2 = color.label2rgb(labels2, img, kind='avg') #misc.imsave('./RAG_other/'+name, out2) return out2
def run(self, ips, imgs, para=None): if not para['stack']: imgs, labs = [ips.img], [self.app.get_img(para['lab']).img] else: labs = self.app.get_img(para['lab']).imgs if len(imgs) != len(labs): labs = [self.app.get_img(para['lab']).img] * len(imgs) for i in range(len(imgs)): img, lab = imgs[i], labs[i] connect = ['4-connected', '8-connected'].index(para['connect']) + 1 g = graph.rag_mean_color(img, lab, connect, para['mode'], para['sigma']) lab = graph.cut_threshold(lab, g, para['thresh']) img[:] = color.label2rgb(lab, img, kind='avg') self.progress(i, len(imgs))
def smartDownSample(vol, nsegs, compactness, threshold): label_vol = np.empty(vol.shape) for i in range(len(vol)): # Segment using SLIC labels = segmentation.slic(vol[i], nsegs, compactness, multichannel = False, enforce_connectivity = True) # Make a Region Adjacency Graph of the segmentation rag = graph_custom.rag_mean_int(vol[i], labels) # Cut this RAG based on threshold new_labels = graph.cut_threshold(labels, rag, threshold) # Make a new graph based on the new segmentation (post cut) # not using right now... rag = graph_custom.rag_mean_int(img, new_labels) new_labels = np.add(new_labels, np.ones(new_labels.shape, dtype=np.int8)) label_vol[i] = new_labels return label_vol.astype('uint8')
def grafo(): ''' Responsavel pelas operacoes com grafos ''' print "\n--- Contagem e união dos segmentos ---\n" global rag, image, segments labels = segments + 1 rag = graph.rag_mean_color(img_as_float(image), labels, sigma=p_sigma) labels2 = graph.cut_threshold(labels, rag, 1) new_rag = graph.rag_mean_color(img_as_float(image), labels2, sigma=p_sigma) new_cel = percorrer_rag_adj_nodos(new_rag) segments = labels2 print "Total de celulas: %d" % len(new_cel) rag = new_rag print "\n--- Fim da uniao dos segmentos ---\n" return len(new_cel)
def rag_main_colors(self, image): img = image[:, :, ::-1] labels = segmentation.slic(img, compactness=30, n_segments=400) out1 = color.label2rgb(labels, img, kind='avg', bg_label=0) #show(out1[:, :, ::-1].copy()) g = graph.rag_mean_color(img, labels) labels2 = graph.cut_threshold(labels, g, 29) out2 = color.label2rgb(labels2, img, kind='avg', bg_label=1) #show(out2[:, :, ::-1].copy()) g = graph.rag_mean_color(out2, labels2) colors_list = g.nodes._nodes.values() main_colors = [[x["pixel count"], x["mean color"]] for x in colors_list] summ = sum([x[0] for x in main_colors ]) for i in range(len(main_colors)): main_colors[i][0] /= summ return union_same_colors(main_colors)
def binary_by_colors(img, target_colors, thresh=0.1): "Segmentacion por color" segments_slic = segmentation.slic(img, n_segments=300, compactness=10, sigma=1) g = graph.rag_mean_color(img, segments_slic) graphcut = graph.cut_threshold(segments_slic, g, 0.1) g = graph.rag_mean_color(img, graphcut) good_nodes = [] for nid in g.nodes(): color = g.node[nid]['mean color'] color = rgb2hsv(color[None, None, :]) minimo = np.min(pairwise_distances(color[0, :, :], target_colors)) if minimo < thresh: good_nodes.append(nid) binary_mask = np.zeros(graphcut.shape, dtype=bool) for gn in good_nodes: binary_mask = binary_mask + (graphcut == gn) return binary_mask
def test_rag_code(): img_org = Image.open("2008_000008.jpg") img = np.array(img_org, dtype=np.float32) labels1 = segmentation.slic(img_org, compactness=40, n_segments=600) out1 = color.label2rgb(labels1, img, kind='avg') g = graph.rag_mean_color(img, labels1) labels2 = graph.cut_threshold(labels1, g, 10) out2 = color.label2rgb(labels2, img, kind='avg') print(out2) misc.imsave('outfile.jpg', out2) fig, ax = plt.subplots(nrows=2, sharex=True, sharey=True, figsize=(6, 8)) ax[0].imshow(out1) ax[1].imshow(out2) for a in ax: a.axis('off') plt.tight_layout()
def segm_rag(input_image, compactness=10, n_segments=275, sigma=1, start_label=1): """Función para generar la segmentación mediante la técnica de RAG. Args: input_image ([Numpy Array]): Imagen de entrada sobre la que obtener la segmentación. compactness (int, optional): Equilibra proximidad de color y espacio. Defaults to 10. n_segments (int, optional): El número aproximado de etiquetas en la imagen de salida. Defaults to 275. sigma (int, optional): Anchura del núcleo de suavizado Gaussiano. Defaults to 1. start_label (int, optional): Índice inicial de etiquetado 0/1. Defaults to 1. Returns: Tuple (output image, labels, number classes): Tupla con la imagen segmentada, las etiquetas y el número total de segmentos encontrados. """ labels = segmentation.slic(input_image, compactness=compactness, n_segments=n_segments, sigma=sigma, start_label=start_label) g = graph.rag_mean_color(input_image, labels) segments_rag = graph.cut_threshold(labels, g, 29) output_image = mark_boundaries(input_image, segments_rag) # labeled_rag = color.label2rgb(segments_rag, input_image, kind='avg', bg_label=0) return (output_image, labeled_rag, len(np.unique(segments_rag)))
def _process(self, image, steps=None): from skimage import segmentation, color from skimage.future import graph resized = self._common_scale(image, downscale=5) labeled = segmentation.slic(resized, compactness=30, n_segments=1000) superpixels = color.label2rgb(labeled, resized, kind='avg') g = graph.rag_mean_color(resized, labeled) merged_labels = graph.cut_threshold(labeled, g, 30) merged_superpixels = color.label2rgb(merged_labels, resized, kind='avg') if steps is not None: steps['superpixels'] = superpixels steps['merged superpixels'] = merged_superpixels center = merged_labels[int(merged_labels.shape[0] / 2), int(merged_labels.shape[1] / 2)] binary = np.zeros(merged_labels.shape[:2]) binary[merged_labels == center] = 1 binary = cv2.resize(binary, (image.shape[1], image.shape[0])) return binary
def pill_mask(img_root, mask_root): ''' Mask Pill Mask -Reference Paper- http://www.scitepress.org/Papers/2017/61358/61358.pdf ''' img_list = os.listdir(img_root) img_list = sorted(img_list, key=lambda x: int(os.path.splitext(x)[0])) for i, img_name in enumerate(img_list): print(i) img = cv2.imread(os.path.join(img_root, img_name)) shear = int(img.shape[0] * 0.12) pad_img = np.zeros((shear, img.shape[1])) img = img[:(img.shape[0] - shear), :, :] # Gaussian Smoothing Filter img = (gaussian(img, sigma=2, multichannel=True) * 255).astype( np.uint8) # SLIC (Simple Linear Iterative Clustering) labels = slic(img, n_segments=150, compactness=12, max_iter=10) labels = labels + 1 regions = regionprops(labels) # Create RAG(Region Adjacency Graph) rag = graph.rag_mean_color(img, labels) for region in regions: rag.node[region['label']]['centroid'] = region['centroid'] # Post-processing labels = graph.cut_threshold(labels, rag, 29) background = np.argmax(np.bincount(labels.flatten())) labels[labels != background] = 255 labels[labels == background] = 0 labels = np.concatenate((labels, pad_img), axis=0) cv2.imwrite(os.path.join(mask_root, img_name), labels)
def main(): img = misc.imread("wheat.png") # labels1 = segmentation.slic(img, compactness=100, n_segments=9) labels1 = segmentation.slic(img, compactness=50, n_segments=4) out1 = color.label2rgb(labels1, img, kind='overlay') print(labels1.shape) g = graph.rag_mean_color(img, labels1) labels2 = graph.cut_threshold(labels1, g, 29) out2 = color.label2rgb(labels2, img, kind='overlay') # get roi # logicalIndex = (labels2 != 1) # gray = rgb2gray(img); # gray[logicalIndex] = 0; plt.figure() io.imshow(out1) plt.figure() io.imshow(out2) io.show()
def grafo(event): global classificacao ''' Responsavel pelas operacoes com grafos ''' if classificacao == 0: print"Executar classificação para a reunião e contagem" classify(1) print "\n--- Contagem e união dos segmentos ---\n" global rag, image, segments labels = segments+1 rag = graph.rag_mean_color(img_as_float(image), labels,sigma=p_sigma) labels2 = graph.cut_threshold(labels, rag, 1) new_rag = graph.rag_mean_color(img_as_float(image), labels2,sigma=p_sigma) desenho_rag(rag, labels) new_cel = percorrer_rag_adj_nodos(new_rag) segments = labels2 desenho_rag(new_rag, labels2) print "Total de celulas: %d" % len(new_cel) rag = new_rag print "\n--- Fim da uniao dos segmentos ---\n"
def apply_watershed(field, markers=None, mask_threshold=0., merge_threshold=0.2, verbose=True): """ Apply a watershed algorithm to find voids in a given field. Candidate void regions are found using the `skimage.segmentation.watershed` method. They are then merged together into a reduced set of voids using a graph-based region merging methods, `skimage.future.graph.rag_mean_color` and `cut_threshold`. Parameters: field (array_like): 3D field to apply the watershed algorithm to. This will be normalised to produce a density contrast, so that `f = field / mean(field) - 1`. markers (int, optional): Number of initial seeds of regions to place before running the watershed algorithm. The seeds are placed in local minima of the field. The final number of regions will be less than this number. mask_threshold (float, optional): Mask (exclude) all regions with density contrast `f` above this value. This is intended to exclude higher-density regions that are not allowed to form part of a void. merge_threshold (float, optional): Similarity threshold (in terms of mean density) to use to decide whether to merge neighbouring regions. Larger values allow less similar regions to merge. Returns: region_lbls (array_like): Array with same shape as `field` with integer label for each voxel. A value of 0 denotes a voxel that is not part of any void. """ # Normalise field to get density contrast if np.mean(field) == 0.: f = field / np.mean(field) - 1. else: f = field # Mask-out high-density regions mask = np.ones_like(f, dtype=np.bool) mask[np.where(f > mask_threshold)] = False # Apply watershed algorithm if verbose: print("Running watershed algorithm") t0 = time.time() region_lbls = watershed(f, markers=markers, mask=mask) if verbose: print("Watershed took %2.2f sec" % (time.time() - t0)) print("No. regions:", np.unique(region_lbls).size) # Use a graph-based region merging algorithm t0 = time.time() if verbose: print("Running merging algorithm") g = graph.rag_mean_color(f, region_lbls, connectivity=1, sigma=2) region_lbls_new = graph.cut_threshold(region_lbls, g, merge_threshold) if verbose: print("Merging took %2.2f sec" % (time.time() - t0)) print("No. regions after merging:", np.unique(region_lbls_new).size) return region_lbls_new
from skimage import io, segmentation, color from skimage.future import graph from matplotlib import pyplot as plt img = io.imread("images/sample.jpg") labels1 = segmentation.slic(img, compactness=30, n_segments=400, start_label=1) out1 = color.label2rgb(labels1, img, kind='avg', bg_label=0) g = graph.rag_mean_color(img, labels1) labels2 = graph.cut_threshold(labels1, g, 29) out2 = color.label2rgb(labels2, img, kind='avg', bg_label=0) fig, ax = plt.subplots(nrows=2, sharex=True, sharey=True, figsize=(6, 8)) ax[0].imshow(out1) ax[1].imshow(out2) for a in ax: a.axis('off') plt.tight_layout() plt.show()
def watershed_transformation(image_data, sobel_threshold, amplification_factor): ''' Runs a watershed transform on the main dataset 1. Create a gradient image using the sobel algorithm 2. Adjust the gradient image based on given threshold and amplification. 3. Find the local minimum gradient values and place a marker 4. Construct watersheds on top of the gradient image starting at the markers. 5. Recombine neighboring image segments using a region adjacency graph. ''' # If this block has no data, return a placeholder watershed. if np.amax(image_data[0]) <= 1: return np.zeros(np.shape(image_data)) # Create a gradient image using a sobel filter sobel_image = filters.sobel(image_data[2]) # Adjust the sobel image based on the given threshold and amp factor. upper_threshold = np.amax(sobel_image) / amplification_factor if upper_threshold < 0.20: upper_threshold = 0.20 sobel_image = exposure.rescale_intensity(sobel_image, in_range=(0, upper_threshold), out_range=(0, 1)) # Prevent the watersheds from 'leaking' along the sides of the image sobel_image[:, 0] = 1 sobel_image[:, -1] = 1 sobel_image[0, :] = 1 sobel_image[-1, :] = 1 # Set all values in the sobel image that are lower than the # given threshold to zero. sobel_image[sobel_image <= sobel_threshold] = 0 #sobel_copy = np.copy(sobel_image) # Find local minimum values in the sobel image by inverting # sobel_image and finding the local maximum values inv_sobel = 1 - sobel_image local_min = feature.peak_local_max(inv_sobel, min_distance=2, indices=False, num_peaks_per_label=1) markers = ndimage.label(local_min)[0] # Build a watershed from the markers on top of the edge image im_watersheds = morphology.watershed(sobel_image, markers) im_watersheds = np.array(im_watersheds, dtype='uint16') # Clear gradient image data sobel_image = None # Find the locations that contain no spectral data empty_pixels = np.zeros(np.shape(image_data[0]), dtype='bool') empty_pixels[image_data[2] == 0] = True # Set all values outside of the image area (empty pixels, usually caused by # orthorectification) to one value, at the end of the watershed list. im_watersheds[empty_pixels] = np.amax(im_watersheds) + 1 # Recombine segments that are adjacent and similar to each other. # Created a region adjacency graph. Create_composite() takes a single list # of bands color_im = utils.create_composite( [image_data[0], image_data[1], image_data[2]]) # Clear image data image_data = None # Create the region adjacency graph based on the color image try: im_graph = graph.rag_mean_color(color_im, im_watersheds) except KeyError: pass else: # Clear color image data color_im = None # Combine segments that are adjacent and whose pixel intensity # difference is less than 10. im_watersheds = graph.cut_threshold(im_watersheds, im_graph, 5.0) return im_watersheds
ruta1 = directorio / imagen2 prueba1 = ji.read_tiff(ruta1) numSegments = 2200000 ## 1/30 #19000 prueba2d #100000 slic100 peque #superp = slic(prueba1, n_segments = numSegments,compactness= 0.1, multichannel= False, convert2lab= False) superp += 1 print('Number of SV: ', len(np.unique(superp))) prueba1 = prueba1.astype('int64') # Precision mag = ndi.generic_gradient_magnitude(prueba1, ndi.sobel, float) # Float for rag_boundary #mag *= 255.0 / np.max(mag) # normalize (Q&D) ragb = graph.rag_boundary(superp, mag, connectivity=1) # CLUST "CORTAR" umbralc = 1000 superp_co = graph.cut_threshold(superp, ragb, umbralc) print('Intermediate Number of SV: ', len(np.unique(superp_co))) superp_co += 1 # CLUST "UNIR" umbralb = 3500 ragb2 = graph.rag_boundary(superp_co, mag, connectivity=1) superp_un = graph.merge_hierarchical(superp_co, ragb2, umbralb, in_place_merge=True, rag_copy=False, merge_func=ji.merge_boundary, weight_func=ji.weight_boundary) superp_un += 1 directorio = Path( "C:/Users/Juan Ignacio/Documents/Movistar Cloud/TFM/Prueba_Feima_multiframe/"
Load() # Load the image for J in range(len(Img)): Data1 =Img[J] # Make a temporary mask Mask=cv2.cvtColor(Data1,cv2.COLOR_BGR2GRAY) # Convert the image in gray-scale ret,Mask=cv2.threshold(Mask,10,255,cv2.THRESH_BINARY) # Thresholding to binarize the image Mask[:]=0 # reset the Mask # SLIC Segmentation with number of segment: 250 , Sigma =3, Compactness : 30 segment_slic = slic(Data1,n_segments=250,sigma=3,compactness=30) # SLIC Segmentation # Calculate the mean-color, corresponding to the original image and result of the SLIC Segmentation. g = graph.rag_mean_color(Data1,segment_slic) # Use the pre-defined threshold to cut off the connection of the region and group the regions, having the value less than 17 label2=graph.cut_threshold(segment_slic,g,17) # Convert the Label(contains the pixel-info) into the RGB Color space rgb=label2rgb(label2,Data1,kind='avg') # Extract RGB and HSV channels for explicitly defined skin boundary model [x,y]=segment_slic.shape seg=np.zeros((x,y,3),np.float32) r=rgb[:,:,0] #Red channel g=rgb[:,:,1] #Green channel b=rgb[:,:,2] #Blue channel HSV=cv2.cvtColor(rgb,cv2.COLOR_BGR2HSV) summ=b+g+r #Summation of red, bule, and green channel seg[:,:,1]=g/summ #Normalised green channel seg[:,:,0]=b/summ #Normalised blue channel #Additional Variable to save the result of the Loop
def find_largest(img, threshold='opening'): """Function to find largest bright object in an image. Workflow: - Convert to binary - Find and retain only largest object in binary image - Fill holes - Apply opening and dilation to remove minutiae Current options to convert to binary: - 'opening': applies global Otsu thresholding after a minor morphological opening (default) - 'global': applies global Otsu thresholding - 'adaptive': applies adaptive threshold after gaussian smoothing - 'tips': eliminates both ~black and ~nearly white backgrounds - 'rag': applies RAG thresholding, followed by global Otsu. Slowest method. Coming soon: - 'textural': eliminates backgrounds of (any) constant colour based on GLCM or binary patterns - 'bilateral': applies adaptive threshold, but after bilateral smoothing""" # Gray scale conversion and contrast stretching gry = color.rgb2gray(img) p2, p95 = np.percentile(gry, (2, 95)) if threshold == 'rag': labels1 = segmentation.slic(img, compactness=50, n_segments=500) out1 = color.label2rgb(labels1, img, kind='avg') thresh = min( np.shape(out1) [:1]) / 10 # threshold = 1/10th of the smallest side of the image # with a large value we get few colours g = graph.rag_mean_color(img, labels1) labels2 = graph.cut_threshold(labels1, g, thresh) out2 = color.label2rgb(labels2, img, kind='avg') out2 = color.rgb2gray(out2) global_thresh = threshold_otsu(out2) binary = out2 < global_thresh elif threshold == 'tips': rescale = exposure.rescale_intensity(gry, in_range=(p2, p95)) binary = np.logical_and( color.rgb2gray(rescale) > 0.05, color.rgb2gray(rescale) < 0.95) elif threshold == 'adaptive': gry = sp.ndimage.filters.gaussian_filter(color.rgb2gray(gry), 7) rescale = exposure.rescale_intensity(gry, in_range=(p2, p95)) thresh_sauvola = threshold_sauvola(rescale, window_size=99) binary = rescale < thresh_sauvola elif threshold == 'global': rescale = exposure.rescale_intensity(gry, in_range=(p2, p95)) global_thresh = threshold_otsu(rescale) binary = rescale < global_thresh else: rescale = 1 - opening( 1 - (exposure.rescale_intensity(gry, in_range=(p2, p95))), disk(2)) global_thresh = threshold_otsu(rescale) binary = rescale < global_thresh # Detect largest bright element in the binary image. Making the assumption it would be the map. # Eliminate everything else (text, colorbar, holes, ...). # Label all white objects (made up of ones) label_objects, nb_labels = ndi.label( binary) # ndimage.label actually labels 0 (background) as 0 and then # labels every nonzero object as 1, 2, ... n. # Calculate every labeled object's size. # np.bincount ignores whether input is an image or another type of array. # It just calculates the binary sizes, including for the 0 (background). sizes = np.bincount(label_objects.ravel()) sizes[ 0] = 0 # This sets the size of the background to 0 so that if it happened to be larger than # the largest white object it would not matter # Keep only largest object binary_objects = remove_small_objects(binary, max(sizes)) # Remove holes from it (black regions inside white object) binary_holes = ndi.morphology.binary_fill_holes(binary_objects) # This may help remove minutiae on the outside (tick marks and tick labels) binary_mask = opening(binary_holes, disk(7)) return binary_mask
def performPaste(img, img_to_paste, approach, segment_algorithm): mask_of_image_to_paste = img_to_paste.to_mask().to_array() out2 = None if approach == 'texture': denoise_img = denoise_tv_bregman(np.asarray(img), weight=0.4) denoise_img = (denoise_img * 255).astype('uint8') gray = cv2.cvtColor(denoise_img, cv2.COLOR_BGR2GRAY) gray = cv2.equalizeHist(gray) mask_of_image_to_paste_ellipse = minimum_bounding_ellipse( mask_of_image_to_paste) if mask_of_image_to_paste_ellipse is not None: img_to_paste = img_to_paste.apply_mask_rgba(mask_of_image_to_paste) dims = (math.ceil(denoise_img.shape[0] / 500.0) * 500.0, math.ceil(denoise_img.shape[1] / 500.0) * 500.0) sigma = max(1.0, math.log10(dims[0] * dims[1] / 10000.0) - 0.5) min_size = max(100.0, math.ceil(sigma * 10.0) * 10) while out2 is None and sigma < 5: if segment_algorithm == 'slic': masksize = float(sum(sum(mask_of_image_to_paste)) / 255) imgsize = float(img.size[0] * img.size[1]) labels1 = segmentation.slic( gray, compactness=5, n_segments=min(500, int(imgsize / (sigma * 2 * masksize)))) else: labels1 = segmentation.felzenszwalb(gray, scale=min_size, sigma=sigma, min_size=int(min_size)) # Compute the Region Adjacency Graph using mean colors. # # Given an image and its initial segmentation, this method constructs the corresponding RAG. # Each node represents a set of pixels within image with the same label in labels. # The weight between two adjacent regions represents how similar or dissimilar two # regions are depending on the mode parameter. cutThresh = 0.00000001 labelset = np.unique(labels1) sizeOfLabelSet = len(labelset) increment = 0.0000005 while increment < 0.01 and (len(labels1) > 100000 or sizeOfLabelSet > 1000): g = graph.rag_mean_color(denoise_img, labels1, mode='similarity') labels1 = graph.cut_threshold(labels1, g, cutThresh) labelset = np.unique(labels1) # too slow of a change if sizeOfLabelSet - len(labelset) < 5: increment *= 10 sizeOfLabelSet = len(labelset) cutThresh += increment labelset = np.unique(labels1) for label in labelset: if label == 0: continue mask = np.zeros(labels1.shape) mask[labels1 == label] = 255 mask = mask.astype('uint8') ret, thresh = cv2.threshold(mask, 127, 255, 0) (contours, _) = cv2api.findContours(thresh, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE) areas = [(cnt, cv2.contourArea(cnt)) for cnt in contours if cv2.moments(cnt)['m00'] > 2.0] contours = sorted(areas, key=lambda cnt: cnt[1], reverse=True) contours = contours[0:min(20, len(contours))] if len(contours) > 0: for contour in contours: try: placement_ellipse = minimum_bounding_ellipse_of_points( contour[0]) if placement_ellipse is not None: transform_matrix = build_transform_matrix( placement_ellipse, mask_of_image_to_paste_ellipse) if transform_matrix is None: continue transformed_image = transform_image( img_to_paste.to_array(), transform_matrix) else: transformed_image = img_to_paste.to_array() out2 = tool_set.place_in_image( ImageWrapper(transformed_image).to_mask(). to_array(), transformed_image, np.asarray(img), (placement_ellipse[0], placement_ellipse[1])) if out2 is not None: break except Exception as e: continue if out2 is not None: break sigma += 0.5 if out2 is None: transform_matrix, out2 = pasteAnywhere(img, img_to_paste.to_array(), mask_of_image_to_paste, approach == 'simple') return transform_matrix, out2
This example constructs a Region Adjacency Graph (RAG) and merges regions which are similar in color. We construct a RAG and define edges as the difference in mean color. We then join regions with similar mean color. """ from skimage import data, io, segmentation, color from skimage.future import graph from matplotlib import pyplot as plt img = data.coffee() labels1 = segmentation.slic(img, compactness=30, n_segments=400) out1 = color.label2rgb(labels1, img, kind='avg') g = graph.rag_mean_color(img, labels1) labels2 = graph.cut_threshold(labels1, g, 29) out2 = color.label2rgb(labels2, img, kind='avg') fig, ax = plt.subplots(nrows=2, sharex=True, sharey=True, figsize=(6, 8)) ax[0].imshow(out1) ax[1].imshow(out2) for a in ax: a.axis('off') plt.tight_layout()
g, thresh=0.08, rag_copy=True, in_place_merge=True, merge_func=merge_boundary, weight_func=weight_boundary) elif ALGO == "ncut": g = graph.rag_mean_color(img, segments, mode='similarity') labels = graph.cut_normalized(segments, g, thresh=0.0002, num_cuts=20, in_place=False) elif ALGO == "thresh": g = graph.rag_mean_color(img, segments, mode='distance') labels = graph.cut_threshold(segments, g, 30, in_place=False) elif ALGO == "GNN": g = graph.rag_mean_color(img, segments, mode='similarity') A = nx.to_scipy_sparse_matrix(g) X_m = np.empty((A.shape[0], 3)) X_t = np.empty((A.shape[0], 3)) y = np.empty((A.shape[0], )) for n, d in g.nodes(data=True): X_m[n] = d['mean color'] X_t[n] = d['total color'] y[n] = d['labels'][0] X_m = (X_m / np.max(X_m)).astype(np.float32) X_t = (X_t / np.max(X_t)).astype(np.float32) X = np.concatenate((X_m, X_t), axis=-1) n_feat = X.shape[1]