def auto_threshold(image,filter_type): if filter_type=='otsu': filt= f.threshold_otsu(image) bw= image>filt bw=bw.astype(int) elif filter_type=='isodata': filt= f.threshold_isodata(image) bw= image>filt bw=bw.astype(int) elif filter_type=='triangle': filt= f.threshold_triangle(image) bw= image>filt bw=bw.astype(int) elif filter_type=='entropy': filt= f.threshold_li(image) bw= image>filt bw=bw.astype(int) elif filter_type=='mixed': snr=np.mean(image)/np.std(image) if snr>2: filt= f.threshold_triangle(image) else: filt= f.threshold_otsu(image) bw= image>filt bw=bw.astype(int) return bw
def auto_threshold(image, filter_type, return_filt=False): blurred = cv2.GaussianBlur(image, (3, 3), 0) if filter_type == 'otsu': filt = f.threshold_otsu(blurred) bw = blurred > filt bw = bw.astype(int) elif filter_type == 'isodata': filt = f.threshold_isodata(blurred) bw = blurred > filt bw = bw.astype(int) elif filter_type == 'triangle': filt = f.threshold_triangle(blurred) bw = blurred > filt bw = bw.astype(int) elif filter_type == 'entropy': filt = f.threshold_li(blurred) bw = blurred > filt bw = bw.astype(int) elif filter_type == 'mixed': snr = np.mean(blurred) / np.std(blurred) if snr > 2: filt = f.threshold_triangle(blurred) else: filt = f.threshold_otsu(blurred) bw = image > filt bw = bw.astype(int) if return_filt: return bw, filt else: return bw
def get_cmap(name, image): """ Takes filename of certain staining and creates the propper colormap for it """ if 'DAPI' in name: cmap = make_colormap([c('black'), c('blue')]) vmin = np.quantile(image, 0.5) vmax = np.quantile(image, 0.95) elif 'HE' in name: cmap = None vmin = None vmax = None elif 'OSP' in name: cmap = make_colormap([c('black'), c('brown')]) vmin = np.quantile(image, 0.4) vmax = np.quantile(image, 0.95) elif 'GFAP' in name: cmap = make_colormap([c('black'), c('green')]) vmin = np.quantile(image, 0.6) vmax = np.quantile(image, 0.98) elif 'Iba1' in name: cmap = 'YlOrBr_r' vmin = np.quantile(image, 0.5) vmax = np.quantile(image, 0.98) elif 'Nestin' in name: cmap = make_colormap([c('black'), c('cyan')]) vmin = np.quantile(image, 0.6) vmax = np.quantile(image, 0.98) elif 'Ki67' in name: cmap = make_colormap([c('black'), c('orange')]) vmin = np.quantile(image, 0.8) vmax = np.quantile(image, 0.999) elif 'NeuN' in name: cmap = 'PuBuGn_r' vmin = np.quantile(image, 0.55) vmax = np.quantile(image, 0.98) elif 'Cas3' in name: cmap = make_colormap([c('black'), c('purple')]) vmin = threshold_triangle(image) vmax = np.quantile(image, 0.98) elif 'CD45' in name: cmap = make_colormap([c('black'), c('magenta')]) vmin = threshold_triangle(image) vmax = np.quantile(image, 0.98) elif 'HIF1a' in name: cmap = make_colormap([c('black'), c('white')]) vmin = np.quantile(image, 0.6) vmax = np.quantile(image, 0.98) elif 'MAP2' in name: cmap = 'inferno' vmin = np.quantile(image, 0.6) vmax = np.quantile(image, 0.98) return cmap, vmin, vmax
def find_furrow(self, use_dapi=False): disc = pd.DataFrame() disc['cx'] = self.nuclei['cx'] disc['cy'] = self.nuclei['cy'] disc['cz'] = self.nuclei['cz'] disc['mCherry'] = self.nuclei['mCherry'] cherry_m = self.disc_matrix(disc, 'mCherry', 'mean') disc['DAPI'] = self.nuclei['DAPI'] dapi_m = self.disc_matrix(disc, 'DAPI', 'mean') mask_thr = threshold_triangle(dapi_m) mask = dapi_m > mask_thr self.thumbnail('mask', mask, title="Disc mask") xhe_min, che_max = self.detect_ridges(cherry_m) if use_dapi: disc['iDAPI'] = 1 / self.nuclei['DAPI'] idapi_m = self.disc_matrix(disc, 'iDAPI', 'mean') dhe_min, dhe_max = self.detect_ridges(idapi_m) he_max = dhe_max * che_max else: he_max = np.absolute(che_max) self.thumbnail('hessian', he_max, title="Max of Hessian Eigenvalue (MHE)") threshold = threshold_triangle(he_max) thresholded = he_max > threshold self.thumbnail('thresholded', thresholded, title="Thresholded MHE (triangle)") skeleton = skeletonize(thresholded) labels = label(skeleton) self.thumbnail('labels', label2rgb(labels, bg_label=0), title="Detected lines") if self.furrow_manual: furrow = self.manual_furrow() else: furrow = self.auto_furrow(labels, mask) mask = ~np.isnan(furrow) indices = np.arange(0, furrow.size) cx = indices[mask] cy = furrow[mask] furrow_img = np.zeros(cherry_m.shape, dtype=bool) if len(cx) < 2: self.logger.warning("Unable to reliably determine furrow position") fn = self.rms_fit(cx, cy) poly = np.poly1d(fn) for x in range(0, furrow.size): if np.isnan(furrow[x]): furrow[x] = round(poly(x)) furrow_img[int(furrow[x]), x] = True self.thumbnail('furrow_line', furrow_img, title="Furrow line") self.furrow = furrow
def getStarCoords(image): """ params: image: first image of the observation return coordinates of the stars detected """ print("Getting stars...") t = threshold_triangle( image) # Selected with skimage.filters.try_all_thresholds print("Threshold:", t) thresh = cv2.threshold(image, t, image.max(), cv2.THRESH_BINARY)[1] contours = cv2.findContours(thresh.astype(np.uint8), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[0] star_coords = [] star_coords_x = [] star_coords_y = [] for star in contours: star = star.reshape((-1, 2)) mean_x = np.round(np.mean(star[:, 0])) mean_y = np.round(np.mean(star[:, 1])) star_coords_x.append(mean_x) star_coords_y.append(mean_y) star_coords.append([mean_x, mean_y]) print("Done!") return star_coords, [star_coords_x, star_coords_y]
def process_image(image_path: str) -> ndarray: img = plt.imread(image_path) img_gray = to_gray(img) pencil_triangle = threshold_triangle(img_gray) binary_img = image_to_binary(img_gray, 0, pencil_triangle) binary_img = morphology.binary_dilation(binary_img, iterations=1) return binary_img
def get_pencils(filename): image = plt.imread(filename) gray = togray(image) thresh = threshold_triangle(gray) binary = binarisation(gray, 0, thresh) binary = morphology.binary_erosion(binary, iterations=10) binary = morphology.binary_dilation(binary, iterations=10) labeled = label(binary) areas = [] for region in regionprops(labeled): areas.append(region.area) for region in regionprops(labeled): if region.area < np.mean(areas): labeled[labeled == region.label] = 0 bbox = region.bbox if bbox[0] == 0 or bbox[1] == 0: labeled[labeled == region.label] = 0 labeled[labeled > 0] = 1 labeled = label(labeled) i, count = 1, 0 for region in regionprops(labeled): isCirc = circularity(region, i) if isCirc > 100 and region.area < 450000 and region.area > 300000: count += 1 i += 1 return count
def autoThresholding(image2d, method='triangle', radius=10, value=50): """Autothreshold an 2D intensity image which is calculated using: binary = image2d >= thresh :param image2d: input image for thresholding :type image2d: NumPy.Array :param method: choice of thresholding method, defaults to 'triangle' :type method: str, optional :param radius: radius of disk when using local Otsu threshold, defaults to 10 :type radius: int, optional :param value: manual threshold value, defaults to 50 :type value: int, optional :return: binary - binary mask from thresholding :rtype: NumPy.Array """ # calculate global Otsu threshold if method == 'global_otsu': thresh = threshold_otsu(image2d) # calculate local Otsu threshold if method == 'local_otsu': thresh = rank.otsu(image2d, disk(radius)) if method == 'value_based': thresh = value if method == 'triangle': thresh = threshold_triangle(image2d) binary = image2d >= thresh return binary
def simple_whale_detector(filename, dilation_iterations=200, num_regions=2): image = load_image(filename) image_array = [] titles = [] image_array.append(image.astype('uint8')) titles.append('Original') # yen threshold = threshold_triangle(image) yen = np.zeros_like(image) yen[image[:, :, 0] > threshold] = image[image[:, :, 0] > threshold] # denoise binary_image = yen[:, :, 0] > 0 structure = build_binary_opening_structure(binary_image) binary_image = binary_opening(binary_image, structure=structure) binary_image = binary_dilation(binary_image, iterations=dilation_iterations) # mask regions, labels = extract_largest_regions(binary_image, num_regions=num_regions) mask = convex_hull_mask(regions > 0) masked = np.zeros_like(image) masked[mask > 0, :] = image[mask > 0, :] titles.append('target') image_array.append(masked.astype('uint8')) # plot subplot_images(image_array, titles=titles, suptitle=filename.split('.')[0])
def central_pixel_without_cells(pixels: np.array): """ Find the location closest to the center that does not have an object (cell) near by :param pixels: Input image as n.array :return: location as a tuple, or False if not found """ s2 = disk(2) s15 = disk(15) binary = pixels > threshold_triangle(pixels) opened = opening(binary, s2) dilated = dilation(opened, s15) location = [pixels.shape[0] // 2, pixels.shape[1] // 2] center = [pixels.shape[0] // 2, pixels.shape[1] // 2] distance = 1 test = dilated[center[0], center[1]] while test and distance < pixels.shape[0] // 2: subarray = dilated[center[0] - distance:center[0] + distance, center[1] - distance:center[1] + distance] if False in subarray: rows, cols = np.where(subarray == False) location = [ rows[0] + center[0] - distance, cols[0] + center[1] - distance ] test = False else: distance += 1 if not test: return location return False
def simple_detector(o_image): image = np.asarray(o_image) dilation_iterations = 40 num_regions = 4 image_array = [] titles = [] image_array.append(image.astype('uint8')) titles.append('Original') threshold = threshold_triangle(image) yen = np.zeros_like(image) yen[image[:, :, 0] > threshold] = image[image[:, :, 0] > threshold] # denoise binary_image = yen[:, :, 0] > 0 structure = build_binary_opening_structure(binary_image) binary_image = binary_opening(binary_image, structure=structure) binary_image = binary_dilation(binary_image, iterations=dilation_iterations) # mask regions, labels = extract_largest_regions(binary_image, num_regions=num_regions) if labels: mask = convex_hull_mask(regions > 0) masked = np.zeros_like(image) masked[mask > 0, :] = image[mask > 0, :] titles.append('Whale') image_array.append(masked.astype('uint8')) myImage = Image.fromarray(np.uint8(image_array[1])) return myImage else: return o_image
def threshold(self, threshold_name): if self.scene.circles: self.scene.reset() if self.current_augments['overlay_applied']: del self.scene.coords self.init_scene() self.read_excel() self.current_augments['overlay_applied'] = False if threshold_name == "origional": self.showimage(self.overview) self.thresholdval = None self.current_augments["threshold"] = False return self.thresholdval = threshold_name im = rgb2gray(self.overview) if threshold_name == "otsu": threshold = threshold_otsu(im) if threshold_name == "li": threshold = threshold_li(im) if threshold_name == "mean": threshold = threshold_mean(im) if threshold_name == "triangle": threshold = threshold_triangle(im) self.current_augments["threshold"] = threshold_name self.current_image = im < threshold self.showimage(self.current_image)
def segment_mask(img_GRAY): ''' Computation of Segmentation Mask for grayscale images mask_pred = segment_mask(img_GRAY) INPUTS: img_GRAY ~ 2D array, dtype=float (N x M) [Grayscale input for which mask will be generated OUTPUTS: mask_pred ~ Boolean array (N x M) [Output segmentation mask in [0,1]] ''' # Increase contrast by adapative histogram equalization # The low contrast in large parts of the image, coupled with the high # intensity for the bottom-right artifacts, motivated selection of a locally # adaptive form of histogram equalization. img_HISTEQ = exposure.equalize_adapthist(img_GRAY) # Use triangle threshold for segmenting objects # Given the skewed and unimodal distribution of pixel values, # the triangle threshold was selected as desirable for isolating the # tail of peak pixel intensities without including brighter segments of the # tissue (as was observed with Otsu) thresh = filters.threshold_triangle(img_HISTEQ) mask_init = img_HISTEQ > thresh # Use white tophat filtering to remove small artifacts # White top-hat filtering inflates objects larger than the structural element, # and then returns the complement. The original mask can be used to crush # small structures in the original image. strel = morphology.disk(2) noise = morphology.white_tophat(mask_init, strel) mask_pred = np.logical_and(mask_init, np.logical_not(noise)) return mask_pred
def process_image(red, green, blue, mask): mask = np.asarray(mask) mask = mask[:, :, 1] red = rescale_intensity(red, in_range=(red.min(), red.max())) green = equalize_adapthist(green) plt.imshow(green, cmap="gray") plt.show() lowpass = ndimage.gaussian_filter(green, 20) green = green - lowpass green = rescale_intensity(green, in_range=(green.min(), green.max())) plt.imshow(green, cmap="gray") plt.show() fran = frangi(green, scale_range=(0, 6), scale_step=1) res1 = np.asarray(fran) # res1 = fran plt.imshow(res1, cmap="gray") plt.show() thresh = threshold_triangle(res1) res2 = res1 >= thresh res2 = remove_small_objects(res2, 30, 20) res2[mask == 0] = 0 result = np.zeros_like(res2) result[res2] = 1 # result[mask == 0] = 0 plt.imshow(res2, cmap="gray") plt.show() return result
def image_binary_global(img_filename, img_filename2): image = io.imread(img_filename) if image.ndim == 3: print("FROM RGB TO GRAY") image = color.rgb2gray(image) elif image.ndim == 4: print("FROM RGBA TO GRAY") image = color.rgba2rgb(image) image = color.rgb2gray(image) thresh = threshold_triangle(image) binary = img_as_ubyte(image > thresh) origin_row, origin_col = image.shape temp1 = max(origin_col, origin_row) temp2 = min(origin_col, origin_row) if (temp1 / temp2) > 1.5: print("not appropriate to be resized") temp1 = int(1.1 * temp1) image2 = np.full((temp1, temp1), 0, dtype='ubyte') image2[int(temp1/2 - origin_row/2): int(temp1/2 - origin_row/2) +origin_row, \ int(temp1/2 - origin_col/2): int(temp1/2 - origin_col/2)+origin_col] = binary image2 = transform.resize(image2, (300, 300), anti_aliasing=True) else: image2 = transform.resize(binary, (300, 300), anti_aliasing=True) io.imsave(img_filename2, img_as_ubyte(image2))
def autocrop(image, scale=0.05, show_plot=False, save_name=None): orig, scaling_factors = resize_with_scaling(image, scale) print "completed resize" struct_elem_size = max(5, int(0.005 * orig.shape[0])) print struct_elem_size elem = disk(struct_elem_size) orig_gr = rgb2lab(orig) orig_gr = (orig_gr + [0, 128, 128]) / [100, 255, 255] im_means = [] threshed_images = [] for lab_channel in range(3): working_copy = orig_gr.copy()[:, :, lab_channel] thresh = threshold_triangle(working_copy) binary = working_copy > thresh threshed_images.append(binary) # quick_fig(binary) print np.mean(binary) im_means.append(np.mean(binary)) print "completed thresholding for channel {}".format(lab_channel) # min_mean_channel = im_means.index(min(im_means)) # binary = threshed_images[min_mean_channel] # label image regions label_image = label(binary) image_label_overlay = label2rgb(label_image, image=label_image) crop_bbox = None overall_area = label_image.shape[:2][0] * label_image.shape[:2][1] for region in regionprops(label_image): # print overall_area, 0.05*overall_area if 0.75 * overall_area > region.area >= 0.07 * overall_area: # draw rectangle around segmented coins minr, minc, maxr, maxc = region.bbox crop_bbox = region.bbox # rect = mpatches.Rectangle((minc, minr), maxc - minc, maxr - minr, fill=False, edgecolor='red', linewidth=2) # ax.add_patch(rect) break quick_fig(np.hstack(threshed_images)) if crop_bbox is not None: minr, minc, maxr, maxc = crop_bbox minr, minc = scale_label((minr, minc), (scale, scale)) maxr, maxc = scale_label((maxr, maxc), (scale, scale)) cropped_region = image[minr:maxr, minc:maxc] quick_fig(cropped_region) print cropped_region.shape if cropped_region.shape[0] > 1000: cropped_region = transform.resize(cropped_region, (1000, 1000)) else: cropped_region = transform.resize(cropped_region, (500, 500)) if save_name is not None: print "saving cropped image as {}".format(save_name) io.imsave(save_name, cropped_region) else: return cropped_region if show_plot: plt.tight_layout() plt.show()
def get_quadrants(inputs, cd45_f: float = 1.0, dapi_f: float = 1.0, cd45_dil: int = 1, dapi_dil: int = 3, cd45_cutoffs: list = [500, 70000], dapi_cutoffs: list = [300, 7000], parallel=True): cd45, dapi = inputs[..., 0], inputs[..., 1] if parallel: N = cd45.shape[0] pool = multiprocessing.Pool(12) gen = (cd45[i, ...][cd45[i, ...] > 0] for i in range(N)) cd45_thresh = np.array(pool.map(threshold_triangle, gen)) cd45_thresh = cd45_thresh[..., None, None] gen = (dapi[i, ...][dapi[i, ...] > 0] for i in range(N)) dapi_thresh = np.array(pool.map(threshold_triangle, gen)) dapi_thresh = dapi_thresh[..., None, None] else: cd45_thresh = threshold_triangle(cd45[cd45 > 0]) dapi_thresh = threshold_triangle(dapi[dapi > 0]) cd45_thresh = cd45_f * cd45_thresh dapi_thresh = dapi_f * dapi_thresh dapi = dapi > dapi_thresh cd45 = cd45 > cd45_thresh if parallel: dapi_pos_gen = ((dapi[i, ...], dapi_dil, i) for i in range(N)) for result in pool.starmap(dapi_processing, dapi_pos_gen): dapi[result[1], ...] = result[0] cd45_pos_gen = ((cd45[i, ...], cd45_dil, i) for i in range(N)) for result in pool.starmap(cd45_processing, cd45_pos_gen): cd45[result[1], ...] = result[0] pool.close() pool.join() else: cd45 = dapi_processing(cd45, cd45_dil, 0, cd45_cutoffs)[0] dapi = dapi_processing(dapi, dapi_dil, 0, dapi_cutoffs)[0] return (np.logical_and(dapi, cd45), np.logical_and(~dapi, cd45), np.logical_and(dapi, ~cd45), np.logical_and(~dapi, ~cd45))
def MO(structure_img_smooth, global_thresh_method, object_minArea, extra_criteria=False, local_adjust=0.98, return_object=False): if global_thresh_method == 'tri' or global_thresh_method == 'triangle': th_low_level = threshold_triangle(structure_img_smooth) elif global_thresh_method == 'med' or global_thresh_method == 'median': th_low_level = np.percentile(structure_img_smooth, 50) elif global_thresh_method == 'ave' or global_thresh_method == 'ave_tri_med': global_tri = threshold_triangle(structure_img_smooth) global_median = np.percentile(structure_img_smooth, 50) th_low_level = (global_tri + global_median) / 2 bw_low_level = structure_img_smooth > th_low_level bw_low_level = remove_small_objects(bw_low_level, min_size=object_minArea, connectivity=1, in_place=True) bw_low_level = dilation(bw_low_level, selem=ball(2)) bw_high_level = np.zeros_like(bw_low_level) lab_low, num_obj = label(bw_low_level, return_num=True, connectivity=1) if extra_criteria: local_cutoff = 0.333 * threshold_otsu(structure_img_smooth) for idx in range(num_obj): single_obj = lab_low == (idx + 1) local_otsu = threshold_otsu(structure_img_smooth[single_obj > 0]) if local_otsu > local_cutoff: bw_high_level[np.logical_and( structure_img_smooth > local_otsu * local_adjust, single_obj)] = 1 else: for idx in range(num_obj): single_obj = lab_low == (idx + 1) local_otsu = threshold_otsu(structure_img_smooth[single_obj > 0]) bw_high_level[np.logical_and( structure_img_smooth > local_otsu * local_adjust, single_obj)] = 1 if return_object: return bw_high_level > 0, bw_low_level else: return bw_high_level > 0
def create_rois(image, size_thresh, method_thresh, closing, scale_factor): ''' Main entry-point function for generating ROIs automatically. Does thresholding, clever merging of intersecting ROIs and ordering left-right-top-bottom. Parameters: image (np.array): 3-dimensional (2d + RGB) numpy array with pixel data for retrieved jpeg from OMERO size_thresh (num): Minimum size (in full-resolution pixels) for an ROI to be considered an ROI method_thresh (str): Thresholding method. Current options are 'otsu', 'triangle', 'yen' and 'li'. closing (int): radius for the diamond-shaped structuring element used for closing operation. scale_factor (int): scaling that was used to generate the downsampled image. Used to re-scale minimum size threshold. Returns: regions (list): list of pruned, ordered tuples of the form (y1,x1,y2,x2) representing the ROIs to be saved back to OMERO. ''' from skimage.color import rgb2gray from skimage.filters import threshold_otsu, threshold_triangle, threshold_yen, threshold_li from skimage.util import invert from skimage.morphology import diamond, binary_closing from skimage.measure import regionprops, label import numpy as np # we're assuming the image is RGB and dark features on light background im = rgb2gray(image) im = invert(im) # ugly thresholding choice here - I'm assuming the inputs to be well-behaved if method_thresh == 'otsu': im_thresh = im > threshold_otsu(im) elif method_thresh == 'triangle': im_thresh = im > threshold_triangle(im) elif method_thresh == 'yen': im_thresh = im > threshold_yen(im) elif method_thresh == 'li': im_thresh = im > threshold_li(im) # do a bit of closing to already merge regions that are almost touching # how much? up to you, it's an input parameter im_thresh = binary_closing(im_thresh, diamond(closing)) im_lab = label(im_thresh) # get rid of ROIs smaller than required size threshold for i in range(1, im_lab.max() + 1): coords = np.where(im_lab == i) if len(coords[0]) < (size_thresh / (scale_factor**2)): im_lab[coords] = 0 regionproperties = regionprops(im_lab) regions = [] # at least for now we only care about the bounding boxes for ROIs for r in regionproperties: regions.append(r.bbox) regions = prune_regions(regions) regions = order_regions(regions) #return [] return regions
def outer_contour_3D(image, zoom=1): #sort in standard size resize_factor = (128 / image.shape[0], 128 / image.shape[1], 128 / image.shape[2]) ima = ndimage.zoom(image, resize_factor, order=0, mode='constant', cval=0.0) # make binary cast thresh = threshold_triangle(ima) imageg = ndimage.median_filter(ima, size=3) binary_image = imageg > thresh for s in range(ima.shape[0]): binary_image[s, :, :] = ndimage.morphology.binary_fill_holes( binary_image[s, :, :]) for s in range(ima.shape[1]): binary_image[:, s, :] = ndimage.morphology.binary_fill_holes( binary_image[:, s, :]) for s in range(ima.shape[2]): binary_image[:, :, s] = ndimage.morphology.binary_fill_holes( binary_image[:, :, s]) # draw outer contour verts, faces, norm, val = marching_cubes_lewiner(binary_image, 0) vint = np.round(verts).astype('int') contour = np.zeros_like(binary_image) for s in vint: contour[s[0], s[1], s[2]] = 1 # shrink contour image cuz of the gaussian_filter we used earlier. if zoom != 1: c_shape = contour.shape zoom_ = ndimage.zoom(contour, zoom, order=0, mode='constant', cval=0.0) zoom_shape = zoom_.shape npad = ((int(np.ceil((c_shape[0] - zoom_shape[0]) / 2)), int((c_shape[0] - zoom_shape[0]) / 2)), (int(np.ceil((c_shape[1] - zoom_shape[1]) / 2)), int((c_shape[1] - zoom_shape[1]) / 2)), (int(np.ceil((c_shape[2] - zoom_shape[2]) / 2)), int((c_shape[2] - zoom_shape[2]) / 2))) contour_3D = np.pad(zoom_, npad, 'constant', constant_values=(0)) elif zoom == 1: contour_3D = contour #Revert to original size get_back = (image.shape[0] / 128, image.shape[1] / 128, image.shape[2] / 128) contour_3D = ndimage.zoom(contour_3D, get_back, order=0, mode='constant', cval=0.0) return contour_3D
def threshold_triangle(arr1d): """ WORKS !!! :param arr1d: :return: """ import skimage.filters as sf thresh = sf.threshold_triangle(arr1d, nbins=256) return thresh
def get_cells(image, imshow=False): """Threshold image using Otsu automatic threshold. Arguments image: ndarray Image to be thresholded. imshow: bool (default False) Whether to show thresholded image or not. """ # Segment by threshold threshold = threshold_triangle(image) bw = image <= threshold # Label segmentation cells = label(bw) cells = __remove_dirt(cells) # Find nuclei nuclei = __refine(image, cells.copy()) nuclei[nuclei != 0] = 1 labeled_nuclei = label(nuclei) # Remove segments with high eccentricity labeled = __remove_by_eccentricity(cells, labeled_nuclei) labeled = relabel_sequential(labeled)[0] # Remove small segments labeled = __remove_by_area(cells, labeled) labeled = relabel_sequential(labeled)[0] # Increase segments area labeled[labeled != 0] = 1 labeled = dilation(labeled, disk(5)) labeled = np.multiply(labeled, bw) labeled = label(labeled) # Remove small segments again labeled = __remove_by_area(cells, labeled) labeled = relabel_sequential(labeled)[0] # Use other technique to remove small segments labeled = __remove_small_segments(labeled) labeled = relabel_sequential(labeled)[0] # Increase segment area by proximity labeled = __relate_pixels(cells, labeled) # Remove remaining small segments labeled = __remove_small_segments(labeled, 0.2) labeled = relabel_sequential(labeled)[0] if imshow: show_segmentation(image, labeled) return labeled
def QuantCore(self, image, filename, save=False): image = gaussian(rgb2gray(image), sigma=2) thresh = threshold_triangle(image[image > 0]) binary = np.logical_and(image < thresh, image > 0) wholeCore = np.sum(binary) if save: self.info.emit("Saving - " + filename + '_core.tiff') imagesave = Image.fromarray(binary) imagesave.save(self.inputpath + os.sep + filename + '_core.tiff') return wholeCore
class BinaryAlg: _operations = { 'Isodata': lambda x : 1*((abs(x) > skfilters.threshold_isodata(x))), 'Li': lambda x : 1*((abs(x) > skfilters.threshold_li(x))), 'Mean': lambda x : 1*((abs(x) > skfilters.threshold_mean(x))), 'Minimum': lambda x : 1*((abs(x) > skfilters.threshold_minimum(x))), 'Otsu': lambda x : 1*((abs(x) > skfilters.threshold_otsu(x))), 'Triangle': lambda x : 1*((abs(x) > skfilters.threshold_triangle(x))), 'Yen': lambda x : 1*((abs(x) > skfilters.threshold_yen(x))) }
def classify_region(region_props, solidity_list, ellipse_list, major_length_list, minor_length_list, area_list): ellipse_q1 = np.quantile(ellipse_list, 0.25) ellipse_q2 = np.quantile(ellipse_list, 0.5) ellipse_q3 = np.quantile(ellipse_list, 0.75) ellipse_percent_70 = np.quantile(ellipse_list, 0.70) ellipse_percent_75 = np.quantile(ellipse_list, 0.75) ellipse_percent_95 = np.quantile(ellipse_list, 0.95) major_length_q1 = np.quantile(major_length_list, 0.25) major_length_q2 = np.quantile(major_length_list, 0.5) major_length_q3 = np.quantile(major_length_list, 0.75) major_length_percent_70 = np.quantile(major_length_list, 0.70) minor_length_q1 = np.quantile(minor_length_list, 0.25) minor_length_q2 = np.quantile(minor_length_list, 0.5) minor_length_q3 = np.quantile(minor_length_list, 0.75) minor_length_percent_70 = np.quantile(minor_length_list, 0.70) solidity_low_outlier = get_low_outlier(solidity_list) minor_high_bound = get_high_outlier(minor_length_list) triangle_solidity = threshold_triangle(solidity_list, nbins=(10)) good_solidity_region = [] small_chromosome_region = [] solidity_outlier_region = [] minor_outlier_region = [] medium_chromosome_region = [] irregular_ellipse_region = [] bad_else_region = [] for region in region_props: if region.area > 44: if compare_ellipse_and_axis(region, major_length_q2, minor_length_q2): small_chromosome_region.append(region) elif region.solidity < solidity_low_outlier: solidity_outlier_region.append(region) elif region.minor_axis_length > minor_high_bound: minor_outlier_region.append(region) elif region.minor_axis_length < minor_length_percent_70: medium_chromosome_region.append(region) elif get_one_ellipse_ratio( region) < ellipse_percent_75 or get_one_ellipse_ratio( region) > ellipse_percent_95: irregular_ellipse_region.append(region) elif region.solidity >= triangle_solidity: good_solidity_region.append(region) else: bad_else_region.append(region) good_region = good_solidity_region + small_chromosome_region + medium_chromosome_region bad_region = [] bad_outlier_region = solidity_outlier_region + minor_outlier_region + irregular_ellipse_region + bad_else_region return good_region, bad_outlier_region
def get_masks(cd45, dapi, cd45_f: float = 1.0, dapi_f: float = 1.0, cd45_dil: int = 1, dapi_dil: int = 3, cd45_cutoffs: list = [500, 70000], dapi_cutoffs: list = [300, 7000], parallel=True): cd45_thresh = threshold_triangle(cd45[cd45 > 0]) dapi_thresh = threshold_triangle(dapi[dapi > 0]) cd45_thresh = cd45_f * cd45_thresh dapi_thresh = dapi_f * dapi_thresh dapi = dapi > dapi_thresh cd45 = cd45 > cd45_thresh cd45 = dapi_processing(cd45, cd45_dil, 0, cd45_cutoffs)[0] dapi = dapi_processing(dapi, dapi_dil, 0, dapi_cutoffs)[0] return cd45, dapi
def pca_triangle(file, pc_band, outfile=None): if type(file) == str: with rio.open(file) as src: profile = src.profile.copy() #triangle thresholding thr = threshold_triangle(src.read([pc_band])) img_bin = np.where(src.read([pc_band]) > thr, 1, 0) #output profile.update({'nodata': 0, 'dtype': rio.uint8, 'count': 1}) if outfile != None: with rio.open(outfile, 'w', **profile) as dst: dst.write(img_bin.astype(rio.uint8)) else: return img_bin.astype(rio.uint8) elif type(file) == np.ndarray: thr = threshold_triangle(file[pc_band]) img_bin = np.where(file[pc_band] > thr, 1, 0) return img_bin.astype(rio.uint8)
def _extract(self, img): img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) content = self.find_content(img) content = self.add_blur(content) treshold = img > threshold_triangle(content) out_img = np.zeros(treshold.shape).astype(np.uint8) out_img[treshold] = 255 return out_img
def make_segment(case_nr, params): img = plt.imread(R"result\r{}.png".format(case_nr)) img_hsv = clr.rgb2hsv(img) img_value = img_hsv[:, :, 2] v_std = np.std(img_value) img_value = (img_value - params[0]) * (params[1] / v_std) manipulation = np.abs(img_value) if params[2] == 0: thresh = flt.threshold_otsu(manipulation) binary = manipulation > thresh elif params[2] == 1: thresh = flt.threshold_isodata(manipulation) binary = manipulation > thresh elif params[2] == 2: thresh = flt.threshold_li(manipulation) binary = manipulation > thresh elif params[2] == 3: thresh = flt.threshold_mean(manipulation) binary = manipulation > thresh elif params[2] == 4: thresh = flt.threshold_niblack(manipulation) binary = manipulation > thresh elif params[2] == 5: thresh = flt.threshold_sauvola(manipulation) binary = manipulation > thresh elif params[2] == 6: thresh = flt.threshold_triangle(manipulation) binary = manipulation > thresh else: thresh = flt.threshold_yen(manipulation) binary = manipulation > thresh binary = morph.remove_small_holes(binary, area_threshold=100) binary = morph.remove_small_objects(binary, min_size=70, connectivity=2) return binary
def __init__(self, img_mask_name, crop_sz=(64, 64), num_data=10000, transform=None): """ Args: img_mask_name: list of name pairs of image and mask data, each pair is a tuple of (img_name, mask_name) For mask, 1-positive samples, 0-negative samples crop_sz: cropping size num_data: generated sample size transform: data augmentation """ self.img_all = {} self.mask_all = {} self.seg_all = { } # segmented image, used as a reference to generate training samples by random cropping self.num_pairs = len(img_mask_name) for i in range(self.num_pairs): curr_name = img_mask_name[i] assert os.path.exists(curr_name[0]) and os.path.exists(curr_name[1]), \ 'Image or mask does not exist!' img = imread(curr_name[0]) thres = threshold_triangle(img) seg_img = np.zeros(img.shape, dtype=img.dtype) seg_img[img > thres] = 1 self.seg_all[str(i)] = seg_img img = img.astype(float) mu = img.mean(axis=(1, 2)) sigma = img.std(axis=(1, 2)) img = (img - mu.reshape(len(mu), 1, 1)) / sigma.reshape( len(sigma), 1, 1) self.img_all[str(i)] = img msk_data = np.load(curr_name[1], allow_pickle=True).tolist() mask = msk_data['masks'] mask[mask != -1] = 1 mask[mask == -1] = 0 obj_dist = distance_transform_cdt(mask, metric='chessboard') bg = np.zeros(mask.shape, dtype=mask.dtype) bg[mask == 0] = 1 bg_dist = distance_transform_cdt(bg, metric='chessboard') bg_dist[bg_dist > 4] = 4 mask_dist = (obj_dist - bg_dist).astype(float) self.mask_all[str(i)] = mask_dist self.crop_sz = crop_sz self.num_data = num_data self.transform = transform