def parasites(image, cells, voronoi): img = Functions.global_otsu(image) cells = Functions.global_otsu(cells) s_elem = Functions.fig(Functions.fig_size) # Remove cells for i in range(Functions.iterations): cells = binary_dilation(cells, s_elem) return_image = Functions.subtraction(img, cells) # Remove stuff from cells for i in range(Functions.iterations-1): return_image = binary_erosion(return_image) return_image = binary_opening(return_image) for i in range(Functions.iterations - 1): return_image = binary_dilation(return_image) # Remove bigger objects removal_image = return_image.copy() for i in range(Functions.iterations + 5): removal_image = binary_erosion(removal_image) removal_image = binary_opening(removal_image) for i in range(Functions.iterations + 10): removal_image = binary_dilation(removal_image) return_image = Functions.subtraction(return_image, removal_image) # Remove voronoi lines for better quality return Functions.subtraction(return_image, voronoi)
def opening3D(data, selem=skimor.disk(3), sliceId=0): if sliceId == 0: for i in range(data.shape[0]): data[i,:,:] = skimor.binary_opening(data[i,:,:], selem) elif sliceId == 2: for i in range(data.shape[2]): data[:,:,i] = skimor.binary_opening(data[:,:,i], selem) return data
def edge_confidence(epi, window=9, threshold=0.02): """ Calculates the edge confidence according to eq. 2. This is a simple measurement which designates an edge if pixel intensities of gray value changes. An edge is determined by the sum of difference in pixel intensity of a central pixel to all pixels in a 1D window of size window. It is assumed that there is an edge if the sum is greater than a given threshold. Parameters ---------- epi : numpy.array [v,u] Set of all gray-value epis for scanline s_hat. window_size : int, optional The 1D window siz in pixels. As the window should be centered symmetrically around the pixel to process the value shpuld be odd. For even numbers the next higher odd number is chosen. threshold : float, optional The threshold giving the smallest difference in EPI luminescence which must be overcome to designate an edge. Returns ------- Ce : numpy.array [v,u] Edge confidence values for each EPI pixel. Me : numpy.array [v,u] of boolean. True means an edge was discovered for at that pixel. """ v_dim = epi.shape[0] u_dim = epi.shape[1] # Check dimensions of input data assert epi.shape == (v_dim, u_dim,), 'Input EPI has wrong shape in function \'edge_confidence\'.' # Make window size odd if window % 2 == 0: warnings.warn( 'window should be an odd number in function \'edge_confidence\'. Window size {g} was given but {u} is used instead.'.format( g=window, u=window + 1)) window += 1 # We avoid the border problem by padding the epi. padded_epi = np.pad(epi, ((0, 0), (int(window // 2), int(window // 2))), 'edge') assert padded_epi.shape == (v_dim, u_dim + window - 1,), 'Padded epi has wrong shape in function \'edge_confidence\'.' # Calculate confidence values Ce = np.zeros(epi.shape, dtype=np.float32) # initiate array for k in range(window): Ce += (epi[...] - padded_epi[:, k:epi.shape[1] + k]) ** 2 Me = Ce > threshold # create confidence Mask Me = binary_opening(Me, selem=square(2), out=Me) # work with square to avoid aliasing # Let's see if our results have reasonable meaning' assert np.all( Ce >= 0), 'Negative edge confidence found in function \'edge_confidence\'.' assert Ce.shape == (v_dim, u_dim,), 'Ce output has incorrect shape in fucntion \'edge_confidence\'.' assert Me.shape == (v_dim, u_dim,), 'Me output has incorrect shape in fucntion \'edge_confidence\'.' return Ce, Me
def opening(gray_img, kernel=None): """Wrapper for scikit-image opening functions. Opening can remove small bright spots (i.e. salt). Inputs: gray_img = input image (grayscale or binary) kernel = optional neighborhood, expressed as an array of 1s and 0s. If None, use cross-shaped structuring element. :param gray_img: ndarray :param kernel = ndarray :return filtered_img: ndarray """ params.device += 1 # Make sure the image is binary/grayscale if len(np.shape(gray_img)) != 2: fatal_error("Input image must be grayscale or binary") # If image is binary use the faster method if len(np.unique(gray_img)) == 2: bool_img = morphology.binary_opening(gray_img, kernel) filtered_img = np.copy(bool_img.astype(np.uint8) * 255) # Otherwise use method appropriate for grayscale images else: filtered_img = morphology.opening(gray_img, kernel) if params.debug == 'print': print_image(filtered_img, os.path.join(params.debug_outdir, str(params.device) + '_opening' + '.png')) elif params.debug == 'plot': plot_image(filtered_img, cmap='gray') return filtered_img
def split_image_into_sudoku_pieces_adaptive_global(image, otsu_local=False, apply_gaussian=False): L = image.shape[0] d = int(np.ceil(L / 9)) dd = d // 5 output = [] if apply_gaussian: image = gaussian_filter(image, sigma=1.0) if not otsu_local: image = to_binary_adaptive(image) for k in range(9): this_row = [] start_row_i = max([k * d - dd, 0]) stop_row_i = min([(k + 1) * d + dd, L]) for kk in range(9): start_col_i = max([kk * d - dd, 0]) stop_col_i = min([(kk + 1) * d + dd, L]) i = image[start_row_i:stop_row_i, start_col_i:stop_col_i].copy() if otsu_local: i = to_binary_otsu(i) i = binary_opening(i) i = to_binary_otsu(i) if apply_gaussian: i = to_binary_otsu(binary_dilation(i)) this_row.append(i) output.append(this_row) return output, image
def outlineSmoothing(image, radius=1): """Smooth outlines of foreground object using morphological operations.""" struct = median(disk(radius), disk(1)) label_image = binary_closing(image, struct) label_image = binary_opening(label_image, struct) return label_image.astype(image.dtype)
def ProcessImage(im, targetDim = 250, doDenoiseOpening = True): #Resize to specified pixels max edge size scaling = 1. if im.shape[0] > im.shape[1]: if im.shape[0] != targetDim: scaling = float(targetDim) / im.shape[0] im = misc.imresize(im, (targetDim, int(round(im.shape[1] * scaling)))) else: if im.shape[1] != targetDim: scaling = float(targetDim) / im.shape[1] im = misc.imresize(im, (int(round(im.shape[0] * scaling)), targetDim)) #print "scaling", scaling greyim = 0.2126 * im[:,:,0] + 0.7152 * im[:,:,1] + 0.0722 * im[:,:,2] #Highlight number plate imnorm = np.array(greyim, dtype=np.uint8) se = np.ones((3, 30), dtype=np.uint8) opim = morph.opening(imnorm, se) diff = greyim - opim + 128. misc.imsave("diff.png", diff) #Binarize image vals = diff.copy() vals = vals.reshape((vals.size)) meanVal = vals.mean() stdVal = vals.std() threshold = meanVal + stdVal #print "Threshold", threshold binIm = diff > threshold misc.imsave("threshold.png", binIm) #print vals.shape #plt.plot(vals) #plt.show() #Denoise diamond = morph.diamond(2) if doDenoiseOpening: currentIm = morph.binary_opening(binIm, diamond) else: currentIm = binIm denoiseIm2 = morph.binary_closing(currentIm, np.ones((3, 13))) #print "currentIm", currentIm.min(), currentIm.max(), currentIm.mean() #print "denoiseIm2", denoiseIm2.min(), denoiseIm2.max(), currentIm.mean() #misc.imsave("denoised1.png", currentIm * 255) #misc.imsave("denoised2.png", denoiseIm2 * 255) #Number candidate regions #print "Numbering regions" numberedRegions, maxRegionNum = morph.label(denoiseIm2, 4, 0, return_num = True) return numberedRegions, scaling
def get_connected(landmask,TEST_CONN=True): # find connected regions # - land (landmask==1) is the background # - connectivity=1, diagonal connectivity doesn't count labels,Nlabels = msr.label(landmask,background=1,return_num=True,connectivity=1) # ================================================== # find largest connected region maxlen = 0 maxlab = 0 for n in range(1,Nlabels): N = len(labels[labels==n]) # print(n,N) if N>maxlen: maxlen = N maxlab = n print(n,N) Landmask = 1+0*landmask Landmask[labels==maxlab] = 0. # ================================================== # ================================================== # open to avoid "singular points" selem = np.ones((3,3)) if 1: selem = None # default (corners=0) Landmask = morph.binary_opening(Landmask.astype('int'),selem=selem).astype(int) if 0: # plot original landmask fig1 = plt.figure() ax1 = fig1.add_subplot(1,1,1) I1 = ax1.imshow(landmask.transpose(),origin='lower') fig1.colorbar(I1) fig1.show() if TEST_CONN: # plot processed landmask fig3 = plt.figure() ax3 = fig3.add_subplot(1,1,1) I3 = ax3.imshow(Landmask.transpose(),origin='lower') fig3.colorbar(I3) plt.show(fig3) if 0: # plot all labels found fig2 = plt.figure() ax2 = fig2.add_subplot(1,1,1) I2 = ax2.imshow(labels,cmap='spectral') fig2.colorbar(I2) plt.show(fig2) return Landmask
def BinMM(img,thresh,size): #threshold at sliderval (param1) img = thrhold(img,thresh) structElement = morphology.rectangle(size,size) #structElement = morphology.disk(size) #structElement = morphology.diamond(size) img = morphology.binary_opening(np.squeeze(img), structElement).astype(np.uint8) return img[:,:,np.newaxis]
def get_CC_size(img): # here a much simpler function is used as the original was way too slow sx = ndimage.sobel(img, axis=0, mode='constant') sy = ndimage.sobel(img, axis=1, mode='constant') sob = np.hypot(sx, sy) thresh = np.median(sob) * 2 sob_binary = sob > thresh im_dilated = morphology.binary_opening(sob_binary, selem = strel(7, shape = 'disk')) im_filled = ndimage.binary_fill_holes(im_dilated) return np.sum(im_filled)
def noise_removal(img, radius_1=1, radius_2=2, median_iterations=3): """ Cleans a binary image by separating loosely connected objects, eliminating small objects, and finally smoothing edges of the remaining objects. The method is ``binary_opening``, ``binary_closing``, and two rounds of ``median_filter``. Parameters ---------- img : array a boolean ndarray radius_1 : int Radius of disk structuring element for opening and closing. Default = 1, which gives 3x3 square connectivity (manhattan distance = 1). Can also supply own boolean array. structure_2 : int Radius of disk structuring element for smoothing with a median filter. Default = 2, which gives a is euclidean distance < 2*sqrt(2). Can also supply own boolean array. Returns ------- A boolean ndarray of the same dimensions as ``img``. See Also -------- In ``scipy.ndimage``, see ``skimage.morphology.binary_opening``, ``skimage.morphology.binary_closing``, and ``skimage.filters.median`` """ if len(np.array([radius_1]).shape) == 1: ELEMENT_1 = _disk(radius=radius_1) else: ELEMENT_1 = structure_1 if len(np.array([radius_2]).shape) == 1: ELEMENT_2 = _disk(radius=radius_2) else: ELEMENT_2 = structure_2 out = morphology.binary_opening(img, selem=ELEMENT_1) out = morphology.binary_closing(out, selem=ELEMENT_1) i = 0 while i < median_iterations: out = filters.median(out, selem=ELEMENT_2) i += 1 return(out)
def get_primary_object_mask(self, img, img_pk): assert img.ndim == 3, 'Expecting 3D image, got shape {}'.format( img.shape) assert img_pk.dtype == np.bool # Remove frequencies above scale of individual cells (this results in clusters near spheroid centers) img = np.abs( ndi.gaussian_filter(img, sigma=1 * self.factors) - ndi.gaussian_filter(img, sigma=8 * self.factors)) img = img.max(axis=0) img = img > filters.threshold_otsu(img) img = img | img_pk # Merge threshold mask with given peaks/markers img = morphology.binary_closing(img, selem=morphology.disk(8)) img = ndi.morphology.binary_fill_holes(img) img = morphology.binary_opening(img, selem=morphology.disk(8)) # Not necessary with larger opening (min size = ~227 w/ 8 radius disk) # img = morphology.remove_small_objects(img, min_size=256) return img
def evaluate(image): ''' input : RGB (png, jpg, etc.) image of neuron output : B&W image of segmentation, B&W image of soma ''' input = ImageOps.grayscale(image) input = np.reshape(input, (1, 1, 512, 512)) input = torch.from_numpy(input) input = input.type(torch.FloatTensor) output = model(input) output = F.sigmoid(output).data.cpu().numpy() output[0, 1] = binary_opening(output[0, 1] > 0.8 * np.max(output[0, 1]), disk(1)).astype(np.int) output[0, 0] = output[0, 0] > threshold_otsu(output[0, 0]) return output[0, 0], output[0, 1]
def calculate_dice_coeff(ground_truth=Y_val, test_data=X_val, model=model): predicted_masks = model.predict(test_data) dice_coef_list = [] for i in range(predicted_masks.shape[0]): pred_mask = predicted_masks[i].reshape((320, 480)) pred_mask[pred_mask >= 0.5] = 1. pred_mask[pred_mask < 0.5] = 0. pred_mask = ndi.binary_closing(pred_mask, np.ones((1, 1))).astype(int) pred_mask = ndi.binary_fill_holes(pred_mask, np.ones( (10, 10))).astype(int) pred_mask = morphology.binary_opening(pred_mask, np.ones((10, 10))) z = skm.confusion_matrix( ground_truth[i].reshape((320, 480)).astype(int).flatten(), pred_mask.astype(int).flatten()) dice_coef_list.append(2 * (z[1][1]) / float(2 * z[1][1] + z[0][1] + z[1][0])) print 'Avg. Dice Coeff: ' + str(np.mean(dice_coef_list))
def show_pred_mask(num): image_rgb = misc.imread('train_resized/' + image_list[num])/255. image_all_mask = misc.imread('train_all_angle_masks_resized/' + image_list[num].split('_')[0] + '.jpg',flatten=True)/255. image_bw = misc.imread('train_resized/' + image_list[num],flatten=True)/255. angle_id = int(image_list[num].split('.')[0].split('_')[1]) min_mask = misc.imread('min_and_max_masks/' + 'min_' + str(int(angle_id) - 1) + '.jpg',flatten=True)/255. max_mask = misc.imread('min_and_max_masks/' + 'max_' + str(int(angle_id) - 1) + '.jpg',flatten=True)/255. X = np.empty((1, 320, 480, 12), dtype=np.float32) X[0,...,:3] = image_rgb X[0,...,3] = image_all_mask X[0,...,4] = min_mask X[0,...,5] = max_mask z = filters.sobel(image_bw) smoothed_edges = filters.gaussian(z,1) X[0,...,6] = smoothed_edges z = canny(z) z = ndi.binary_closing(z,structure=np.ones((5,5))) X[0,...,7] = ndi.binary_fill_holes(z,np.ones((3,3))).astype(int) threshold_otsu_val = filters.threshold_otsu(image_bw) threshold_otsu = image_bw > threshold_otsu_val X[0,...,8] = threshold_otsu image_index = np.where(z >= 0) df = pd.DataFrame() df['l1_dist_y'] = abs((image_index[0] - 159.5)/159.5) df['l1_dist_x'] = abs((image_index[1] - 239.5)/239.5) df['l2_dist'] = np.sqrt((df['l1_dist_x'])**2 + (df['l1_dist_y'])**2)/np.sqrt(2) X[0,...,9] = df.l2_dist.reshape((320,480)) X[0,...,10] = df.l1_dist_x.reshape((320,480)) X[0,...,11] = df.l1_dist_y.reshape((320,480)) pred_mask = model.predict(X).reshape((320,480)) pred_mask[pred_mask >= 0.5] = 1. pred_mask[pred_mask < 0.5] = 0. pred_mask = ndi.binary_closing(pred_mask,np.ones((1,1))).astype(int) pred_mask = ndi.binary_fill_holes(pred_mask,np.ones((10,10))).astype(int) pred_mask = morphology.binary_opening(pred_mask,np.ones((10,10))) act_mask = misc.imread('train_masks_resized/' + image_list[num].split('.')[0] + '_mask.jpg',flatten=True)/255. z = skm.confusion_matrix(act_mask.astype(int).flatten(),pred_mask.astype(int).flatten()) dice_coeff = 2*(z[1][1])/float(2*z[1][1] + z[0][1] + z[1][0]) print 'Dice Coeff: ' + str(dice_coeff) fig = plt.figure(figsize = (13,13)) ax1 = fig.add_subplot(121) io.imshow(act_mask - pred_mask) ax2 = fig.add_subplot(221) io.imshow(image_rgb) plt.show()
def img_2d_stack_to_binary_array(img_2d_stack, bth_k=3, wth_k=3, close_k=1, plot_all=False, window_size=(7, 15, 15), slice_contrast=0, pre_thresh='sauvola'): print(' - Converting each z-plane to a binary mask') img_2d_stack = np.asarray(img_2d_stack) img_stacked = [] for im_plane in range(0, len(img_2d_stack)): im = img_2d_stack[im_plane] if slice_contrast: im = st2.contrasts(im, plot=False)[slice_contrast] im = st2.black_top_hat(im, plot=False, k=bth_k, verbose=False) im = st2.white_top_hat(im, plot=False, k=wth_k, verbose=False) img_stacked.append(im) img_out = [] if pre_thresh != 'none': thresh_3d = threshold_sauvola(np.asarray(img_stacked), window_size=window_size, k=0.3) else: thresh_3d = np.asarray(img_stacked) for plane in range(0, len(thresh_3d)): thresh = thresh_3d[plane] > threshold_li(thresh_3d[plane]) img_out.append( st2.close_binary(thresh, k=close_k, plot=False, verbose=False)) img_out = np.asarray(img_out) img_out = img_out / np.amax(img_out) img_out = morphology.binary_opening(img_out) img_out = morphology.binary_closing(img_out) #img_out = st2.get_largest_connected_region(img_out, plot=False, verbose=False) if plot_all: tif.imsave('tmp.tiff', np.asarray(img_out, 'uint8'), bigtiff=True) t = tif.imread('tmp.tiff') tif.imshow(t) plt.show() os.remove('tmp.tiff') return img_out
def segments_extraction(image): """ :param image: :return: """ # бинарим изображение binary = image < .5 # ширина и высота w, h = image.shape # коэффициент уменьшения изображения для создания карты сегментов scale = 800 / max(w, h) scaled = rescale(binary, scale) w, h = scaled.shape window_o = np.ones((1, int(w / 100))) window = np.ones((8, 8)) edges = sobel(scaled) open_image = binary_closing(edges, window_o) close_image = binary_opening(open_image, window_o) # dilate = dilation(close_image, window) # contours = find_contours(dilate, .8) # список для хранения сегментов segments = [] for contour in contours: segment = binary[int(min(contour[:, 0]) / scale):int(max(contour[:, 0]) / scale), int(min(contour[:, 1]) / scale):int(max(contour[:, 1]) / scale)] # Если в сегмента средний уровень яркости маленький, значит полезной # информации там нет if segment.mean() <= .05: continue coordinates = min(contour[:, 0]) / scale, max(contour[:, 0]) / scale, \ min(contour[:, 1]) / scale, max(contour[:, 1]) / scale segments.append((segment, coordinates)) return segments
def create_cloud_mask(im_QA, satname, cloud_mask_issue): """ Creates a cloud mask using the information contained in the Quality Assessment (QA) band for each satellite. Arguments: ----------- im_QA: np.array Image containing the QA band satname: string short name for the satellite: 'L5', 'L7', 'L8' or 'S2'/'S2_RGB' cloud_mask_issue: boolean Set to True if there is an issue with the cloud mask and pixels are being erroneously masked on the images. It will check pixels around to determine if the cloud information is a mistake and shouldn't be taken into account. Returns: ----------- cloud_mask : np.array boolean array with True if a pixel is cloudy and False otherwise """ # convert QA bits (the value of bits allocated to cloud cover vary depending on the satellite mission) if satname == 'L8': cloud_values = [2800, 2804, 2808, 2812, 6896, 6900, 6904, 6908] elif satname == 'L7' or satname == 'L5': cloud_values = [752, 756, 760, 764] elif satname == 'S2' or satname == 'S2_RGB': cloud_values = [1024, 2048] # 1024 = dense clouds, 2048 = cirrus clouds # find which pixels have bits corresponding to cloud values cloud_mask = np.isin(im_QA, cloud_values) # remove cloud pixels that form very thin features. These can be for example beach or swash pixels # that are erroneously identified as clouds by the CFMASK algorithm applied to the images by the USGS if sum(sum(cloud_mask)) > 0 and sum(sum(~cloud_mask)) > 0: morphology.remove_small_objects(cloud_mask, min_size=10, connectivity=1, in_place=True) if cloud_mask_issue: elem = morphology.square(3) # use a square of width 3 pixels cloud_mask = morphology.binary_opening(cloud_mask,elem) # perform image opening # remove objects with less than 25 connected pixels morphology.remove_small_objects(cloud_mask, min_size=25, connectivity=1, in_place=True) return cloud_mask
def thresh_and_binarize(image_, method='rosin', invert=True, min_size=10, thr_percent=95): """ receives greyscale np.ndarray image inverts the intensities thresholds on the minimum peak converts the image into binary about that threshold :param image_: np.ndarray :param method: str 'bimodal' or 'unimodal' :return: spots threshold_min on this image """ if invert: image_ = u.invert(image_) if method == 'bimodal': thresh = threshold_minimum(image_, nbins=512) spots = copy(image_) spots[image_ < thresh] = 0 spots[image_ >= thresh] = 1 elif method == 'otsu': spots = create_otsu_mask(image_, scale=1) elif method == 'rosin': spots = create_unimodal_mask(image_, str_elem_size=3) elif method == 'bright_spots': spots = image_ > np.percentile(image_, thr_percent) str_elem = disk(min_size) # spots = binary_closing(spots, str_elem) spots = binary_opening(spots, str_elem) spots = clear_border(spots) else: raise ModuleNotFoundError( "not a supported method for thresh_and_binarize") return spots
def task4(): img = mimg.imread("x.png") img = rgb2gray(img) img = img_as_ubyte(img) ret, thresh = cv2.threshold(img, 150, 255, cv2.THRESH_BINARY) new_img = binary_opening(thresh, selem=disk(35)) # fig, ax = plt.subplots(1, 3) # show(ax[0], img, "original") # show(ax[1], thresh, "thresh") # show(ax[2], new_img, "new_img") # plt.show() fig, ax = plt.subplots(1, 1) show(ax, new_img) plt.show()
def post_process(img,min_size=100): ''' 图像后处理过程 包括开运算和去除过小体素 返回uint16格式numpy二值数组 ''' img = img.cpu() img = img.numpy().astype(np.bool) b,c,w,h = img.shape if c==1: for i in range(b): img_tmp = img[i,0,:,:] img_tmp = binary_opening(img_tmp) remove_small_objects(img_tmp, min_size=min_size, in_place=True) img_tmp = ~remove_small_objects(~img_tmp, min_size=min_size) img[i,0,:,:] = img_tmp return img.astype(np.uint16)
def get_spine_bbox(x): s = (x > 250).sum(axis=(2)) # размытие s_ = gaussian(s, sigma=3, preserve_range=True) s_ = s_ / s_.max() > 0.45 # открытие морфология s_ = binary_opening(s_, disk(4)) # наиб связ компонента s_ = get_greatest_component(s_) # bbox = mask2bounding_box(s_) # s_[1][0]-=10 bbox = mask2bounding_box(s_) bbox = add_margin(bbox, [20, 0]) b = bbox.copy() b[0][0] -= 20 return b
def segmentTumor(path, save_path=None, return_contour=True): name = path[path.rfind('/') + 1:path.rfind('.')] image_array = sitk.GetArrayFromImage(sitk.ReadImage(path)) converted = convertImagePixel(image_array[0, :, :]).astype( np.int16) # 转化为0~255的图像 # scipy.misc.toimage(converted, cmin=0, cmax=255).save(name) # 暂存灰度图 # img = cv2.imread(name) # gray_img = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) thresh = np.array(converted > int(255 * 0.4), dtype=np.int8) # 变为二值图像, 可调整参数 dst_close = sm.binary_closing(thresh, sm.disk(3.5)) #闭操作滤波,填充空洞, 可调整参数 dst_open = sm.binary_opening(dst_close, sm.disk(3.5)) # 开操作滤波,消除小斑点, 可调整参数 plt.imshow(dst_open) plt.show()
def task2(): img = mimg.imread("bw2.bmp") # domkniecie robi najpierw dylatacje potem erozje wiec usuwa wystajace elementy new_img = binary_closing(img, selem=disk(2.4)) # otwarcie robi najpierw erosje potem dylatacje, usuwa rysy new_img = binary_opening(new_img, selem=disk(2)) # alternatywa # new_img = binary_closing(img, selem=disk(2.4)) # new_img= 1-new_img # new_img = binary_closing(img, selem=disk(2.4)) # new_img=1-new_img fig, ax = plt.subplots(1, 2) show(ax[0], img, "before") show(ax[1], new_img, "after") plt.show()
def threshold(self): """Threshold by first removing nuclear stain bleed through""" dna_im = self.dreader.get_max_im(self.iminfo, 'dna') im_subtracted = imfuns.subtract(self.im, self.C['DNA_FACTOR'] * dna_im) im_mask = imfuns.imthresh(im_subtracted, self.C['THRESH']) > 0 im_closed = morphology.binary_closing(im_mask, selem=morphology.disk( self.C['MORPH_CLOSING_SZ'])) im_opened = morphology.binary_opening(im_closed, selem=morphology.disk( self.C['MORPH_OPENING_SZ'])) self.im_threshed = morphology.remove_small_objects( im_opened, min_size=self.C['MIN_SZ']) self.im_smooth = imfuns.mask_im(self.im, self.im_threshed) return im_subtracted, im_mask, im_closed, im_opened
def bin_open(img: np.ndarray, disk_size: int) -> np.ndarray: """ Performs binary opening of an image img : np.ndarray Image to filter. masking_radius : int Radius of the disk-shaped structuring element. Returns ------- np.ndarray : Filtered image, same shape as input """ selem = disk(disk_size) res = binary_opening(img, selem) return res
def binary_filter(image, threshold=False, percentage=0.6, size=15): """ :param image: :param threshold: set threshold manually :param percentage: get brightest percentage of image :return: biary mask """ if not threshold: ord_img = np.sort(image.flatten()) value = ceil(len(ord_img) * percentage) if value < len(ord_img): threshold = ord_img[value] else: print("threshold too high") threshold = 0.5 binary = image > threshold binary = binary_opening(binary, selem=disk(size)) return binary
def create_cloud_mask(im_QA, satname, cloud_mask_issue): """ Creates a cloud mask using the information contained in the QA band. KV WRL 2018 Arguments: ----------- im_QA: np.array Image containing the QA band satname: string short name for the satellite (L5, L7, L8 or S2) cloud_mask_issue: boolean True if there is an issue with the cloud mask and sand pixels are being masked on the images Returns: ----------- cloud_mask : np.array A boolean array with True if a pixel is cloudy and False otherwise """ # convert QA bits (the bits allocated to cloud cover vary depending on the satellite mission) if satname == 'L8': cloud_values = [2800, 2804, 2808, 2812, 6896, 6900, 6904, 6908] elif satname == 'L7' or satname == 'L5' or satname == 'L4': cloud_values = [752, 756, 760, 764] elif satname == 'S2': cloud_values = [1024, 2048] # 1024 = dense cloud, 2048 = cirrus clouds # find which pixels have bits corresponding to cloud values cloud_mask = np.isin(im_QA, cloud_values) # remove cloud pixels that form very thin features. These are beach or swash pixels that are # erroneously identified as clouds by the CFMASK algorithm applied to the images by the USGS. if sum(sum(cloud_mask)) > 0 and sum(sum(~cloud_mask)) > 0: morphology.remove_small_objects(cloud_mask, min_size=10, connectivity=1, in_place=True) if cloud_mask_issue: elem = morphology.square(3) # use a square of width 3 pixels cloud_mask = morphology.binary_opening(cloud_mask,elem) # perform image opening # remove objects with less than 25 connected pixels morphology.remove_small_objects(cloud_mask, min_size=25, connectivity=1, in_place=True) return cloud_mask
def segment_image(image, remove_bg=True, conv_sigma=2, opening_size=30): """ Segment larger regions from an image. Give it an image and it returns a list of region objects, approximately ordered accoring the numbering at the Excel file (i.e. from top to bottom and from left to right). Inputs: - image: greyscale image to segment - remove_bg: remove background? (bool, default: True) - conv_sigma: sigma of the Gaussian convolution (float, default: 2.0) - opening_size: size of the patch for binary opening (int, default: 30) Output: - regions: the segmented regions, sorted from top to bottom and from left to right """ image_greyscale = rgb2grey(image) # smoothing image_greyscale = gaussian_filter(image_greyscale, sigma=conv_sigma) # erosion seed = np.copy(image_greyscale) seed[1:-1, 1:-1] = image_greyscale.max() mask = image_greyscale dilated = reconstruction(seed, mask, method='erosion') # thresholding and binary opening image_thresholded = dilated > 0.5 * threshold_otsu(dilated) segmentation = binary_opening(image_thresholded, np.ones((opening_size, opening_size))) if 0: distance = ndi.distance_transform_edt(segmentation) local_maxi = peak_local_max(distance, indices=False, footprint=np.ones((3, 3)), labels=segmentation) markers = ndi.label(local_maxi)[0] label_image = watershed(-distance, markers, mask=segmentation) segmentation = np.logical_or(label_image > 0, segmentation) if remove_bg: image[segmentation == False] = 0 label_image = label(segmentation) # find regions and sort them regions = sort_regions(regionprops(label_image)) return regions
def closing(image, struct=None): """ Open up black phase so that struct fits without overlapping white phase. :param image: data :type image: :py:class:`numpy.ndarray` :type struct: :py:class:`numpy.ndarray` :type struct: :py:class:`numpy.ndarray` :return: modified image data :rtype: :py:class:`numpy.ndarray` """ if not struct: struct = morphology.disk(1) i = morphology.binary_opening(image, struct) return i > i.mean()
def finalProcessingSpur(s, params): logging.info(f"{s['filename']} - \tfinalProcessingSpur") disk_radius = int(params.get("disk_radius ", 25)) selem = disk(disk_radius) mask = s["img_mask_use"] mask_opened = binary_opening(mask, selem) mask_spur = ~mask_opened & mask s.addToPrintList("spur_pixels", str(len(mask_spur.nonzero()[0]))) io.imsave(s["outdir"] + os.sep + s["filename"] + "_spur.png", mask_spur * 255) s["img_mask_use"] = mask_opened if len(s["img_mask_use"].nonzero() [0]) == 0: #add warning in case the final tissue is empty logging.warning( f"{s['filename']} - After BasicModule.finalProcessingSpur NO tissue remains detectable! Downstream modules likely to be incorrect/fail" ) s["warnings"].append( f"After BasicModule.finalProcessingSpur NO tissue remains detectable! Downstream modules likely to be incorrect/fail" )
def cell_mask(Img, method): if (method == 'Otsu'): thresh = filters.threshold_otsu(Img) bw = (Img < thresh) elif (method == 'Customized'): # rough definition of background bw = (Img < 1.5 * np.min(Img)) # cell area bw = ndimage.gaussian_filter(1.0 * bw, sigma=3 * DL) bw = (bw > 0) dc = np.mean(Img[np.where( bw == False)]) # assume that background is a constant value # the definition of customized extracellular boundary thresh = division_coeff * dc + (1 - division_coeff) * np.min(Img) bw = (Img < thresh) bw = ndimage.binary_fill_holes(bw) kernal = morphology.disk(np.round(DL)) bw = morphology.binary_opening(bw, kernal) return bw
def RefineLungSegmentation(im,binary_before,binary): binary[binary_before>0] = 0 selem = disk(5) binary = binary_opening(binary, selem) label_image = label(binary) for region in regionprops(label_image): if region.major_axis_length>60: for coordinates in region.coords: im[coordinates[0], coordinates[1]] = -2000 # plt.figure(13) # plt.imshow(im, cmap=plt.cm.gray) # plt.show() return im
def applies_morphological_cleanup(labels, bg_label, morph_radius=5, morph_min_size=25): """ Applies morphological cleanup to labeling assignment per component / grain. Parameters --------- labels : NumPy Array labeling assignment bg_label : int GMM background label morph_radius : int disk radius for the morphological orperation morph_min_size : int remove small objects smaller than this value Returns ---------- clean_labels : NumPy Array labeling after morphological cleanup """ components = slu.get_unique_labels(labels) components.remove(bg_label) # Initialize clean labels as bacdground clean_labels = (labels == bg_label) * bg_label for i in components: # non-background gmm components in increasing order gmm_labels = labels == i clean_gmm_labels = morphology.binary_opening( gmm_labels, morphology.disk(morph_radius)) clean_gmm_labels = morphology.remove_small_objects( clean_gmm_labels, min_size=morph_min_size) clean_gmm_labels = clean_gmm_labels.astype(np.uint8) clean_labels[clean_gmm_labels == 1] = i clean_labels[(clean_gmm_labels == 0) * gmm_labels] = bg_label return clean_labels
def threshold_segmentation(image, threshold, size=10): """Segment an image with a global threshold and binary opening. Parameters ---------- image : numpy.array Image to segment. threshold : scalar or numpy.array size : int Size of a disk-shaped element to perform a binary opening. Returns ------- numpy.array An array of labels. """ mask = image > threshold mask = morphology.binary_opening(mask, morphology.disk(size), out=mask) return morphology.label(mask.astype(int))
def sigmaClippedOpening(data): """ Perform Gaussian filtering, sigma clipping and binary opening to define a mask for the background pixels. """ image = gaussian_filter(data, 0.5) #sigma clip masked = sigma_clip(image, sig=5., iters=None) mask = ~masked.mask d = masked.data #update mask with opening mask = binary_opening(mask, disk(8)) #plot the image fig = plt.figure(figsize=(18, 10)) ax1 = fig.add_subplot(121) ax2 = fig.add_subplot(122) ax1.set_title('Data, Single Quadrant') ax2.set_title('Background Mask') im1 = ax1.imshow(np.log10(data), origin='lower', vmin=2., vmax=3.5, interpolation='none') im2 = ax2.imshow(mask, origin='lower', interpolation='none') c1 = plt.colorbar(im1, ax=ax1, orientation='horizontal') c2 = plt.colorbar(im2, ax=ax2, orientation='horizontal', ticks=[0, 1]) c2.ax.set_xticklabels(['False', 'True']) c1.set_label('$\log_{10}$(Counts [ADU])') c2.set_label('Mask') plt.savefig('opening.png') plt.close() out = data*mask fileIO.writeFITS(out, 'opening.fits', int=False) o = out.ravel() o = o[o > 0.] print o.min(), o.max(), o.mean(), o.std(), len(o) return o
def get_filter_thresh(image, opening_selem=10, closing_selem=20, std_factor=1.0, auto=False): ''' Desc: Get image filter using thresh hold difference method. args: image: rgb image opening_selem: the square matrix size for removing white speckles closing_selem: the square matrix size for removing black speckles auto: whether to display the image at the end of the function and prompt user for inputs returns: filter: black and white image with background pixels as black ''' log.info('Getting background filter') log.debug(f'Pixel Mean: {BG_PXL_MEAN}') log.debug(f'Pixel STD: {BG_PXL_STD}') # find where difference of background exceeds stddev bg_px_map = abs(np.subtract(image, BG_PXL_MEAN)) \ <= std_factor * BG_PXL_STD bg_px_map = np.all(bg_px_map, axis=2) # compute filter image filter = np.zeros(image.shape[:2]) filter[~bg_px_map] = 1 clean = binary_opening(filter, selem=square(opening_selem)) clean = binary_closing(clean, selem=square(closing_selem)) fig, (ax1, ax2, ax3) = plt.subplots(ncols=3, sharey=True, figsize = (15,10)) ax1.imshow(image) ax1.set_title('Original') ax2.imshow(filter, cmap='gray') ax2.set_title('Threshold applied') ax3.imshow(clean, cmap='gray') ax3.set_title('Noise removed') plt.axis('off') fig.suptitle("Adjust threshold factor in command line to improve filter") if not auto: plt.show() return clean
def get_brightest_blobs(image): close_size = 5 open_size = 5 watershed_footprint = (5, 5) # Make sure types are the same input_image = img_as_float(image) # Filter Image filtered_image = filters.median(input_image, behavior='ndimage') # Edge Detection edge_sobel = filters.sobel(filtered_image) # Threshold thresh = filters.threshold_otsu(filtered_image) binary_otsu = filtered_image > thresh # Binary Morphology Operations structure_element = morphology.disk(close_size) closed_image = morphology.binary_closing(binary_otsu, structure_element) structure_element = morphology.disk(open_size) opened_image = morphology.binary_opening(closed_image, structure_element) # Watershed distance = distance_transform_edt(opened_image) local_maxi = peak_local_max(distance, indices=False, footprint=np.ones(watershed_footprint), labels=opened_image) markers = label(local_maxi)[0] labels = watershed(-distance, markers, mask=opened_image) # Labeling and Sorting regions = regionprops_table(labels, intensity_image=image, properties=('label', 'centroid', 'max_intensity', 'mean_intensity')) df = pd.DataFrame(regions) df = df.sort_values(by=['mean_intensity', 'max_intensity'], ascending=False) return df
def geometric(image_roi, attrs={}, debug=False): """ Geometric """ image_roi, _ = pad_for_rotation(image_roi) grayscale = rgb2gray(image_roi) lesion_mask = image_roi[..., 3] labels = label(lesion_mask, background=0)+1 props = regionprops(labels) sizes = [ (p['area'], i) for i, p in enumerate(props) ] max_value, max_index = max(sizes) masked = np.ma.masked_array(grayscale, 1-lesion_mask) tmin, tptp = masked.min(), masked.ptp() # percentages reversed, lesion is darkest in the center p25 = tptp * .75 + tmin p50 = tptp * .50 + tmin p75 = tptp * .25 + tmin if debug: print "=== Geometric ===" plt.subplot(141) plt.imshow(labels.copy()) for i, threshold in enumerate([p25, p50, p75], 1): pieces = masked < threshold pieces = binary_opening(pieces, disk(1)) labels = label(pieces, background=0)+1 N = labels.max() attrs['Geometric p%d' % (25*i)] = N if debug: print "%dth percentile : %d" % (25*i, N) plt.subplot(141 + i) plt.imshow(labels) if debug: plt.show()
def geometric(image_roi, attrs={}, debug=False): """ Geometric """ image_roi, _ = pad_for_rotation(image_roi) grayscale = rgb2gray(image_roi) lesion_mask = image_roi[..., 3] labels = label(lesion_mask, background=0) + 1 props = regionprops(labels) sizes = [(p['area'], i) for i, p in enumerate(props)] max_value, max_index = max(sizes) masked = np.ma.masked_array(grayscale, 1 - lesion_mask) tmin, tptp = masked.min(), masked.ptp() # percentages reversed, lesion is darkest in the center p25 = tptp * .75 + tmin p50 = tptp * .50 + tmin p75 = tptp * .25 + tmin if debug: print "=== Geometric ===" plt.subplot(141) plt.imshow(labels.copy()) for i, threshold in enumerate([p25, p50, p75], 1): pieces = masked < threshold pieces = binary_opening(pieces, disk(1)) labels = label(pieces, background=0) + 1 N = labels.max() attrs['Geometric p%d' % (25 * i)] = N if debug: print "%dth percentile : %d" % (25 * i, N) plt.subplot(141 + i) plt.imshow(labels) if debug: plt.show()
def grow_mask(anat, aseg, ants_segs=None, ww=7, zval=2.0, bw=4): """ Grow mask including pixels that have a high likelihood. GM tissue parameters are sampled in image patches of ``ww`` size. This is inspired on mindboggle's solution to the problem: https://github.com/nipy/mindboggle/blob/master/mindboggle/guts/segment.py#L1660 """ from skimage import morphology as sim selem = sim.ball(bw) if ants_segs is None: ants_segs = np.zeros_like(aseg, dtype=np.uint8) aseg[aseg == 42] = 3 # Collapse both hemispheres gm = anat.copy() gm[aseg != 3] = 0 refined = refine_aseg(aseg) newrefmask = sim.binary_dilation(refined, selem) - refined indices = np.argwhere(newrefmask > 0) for pixel in indices: # When ATROPOS identified the pixel as GM, set and carry on if ants_segs[tuple(pixel)] == 2: refined[tuple(pixel)] = 1 continue window = gm[ pixel[0] - ww:pixel[0] + ww, pixel[1] - ww:pixel[1] + ww, pixel[2] - ww:pixel[2] + ww, ] if np.any(window > 0): mu = window[window > 0].mean() sigma = max(window[window > 0].std(), 1.0e-5) zstat = abs(anat[tuple(pixel)] - mu) / sigma refined[tuple(pixel)] = int(zstat < zval) refined = sim.binary_opening(refined, selem) return refined
def __IsolateBody(self): """ create segmentation of only the human body :return:segmentation of the human body """ seg = self.__activate_threshold(self.ct_mat, MIN_TH, MAX_TH) # clean noise seg = binary_opening(seg) seg = remove_small_objects(seg, CLEAN_CONSTANT, connectivity=2) # delete components until there is only one! seg = self.__choose_largest_co_component(seg, 1) # save nifty file seg_file = nib.Nifti1Image(seg, self.ct_file.affine) nib.save( seg_file, self.dir_results + self.ct_scan + '_' + CLEAN_BODY + 'a' + NIFTY_END) return seg
def adapt_thresh(equalized, returnmasked=False): # Normalize by subtracting image mean # Clip values less than zero to remove background signal equalized = (equalized - equalized.mean()).clip(min=0) # Otsu threshold of CLAHE equalized "grayscale" otsu1 = threshold_otsu(equalized) # print "Otsu threshold: {0}".format(otsu1) thresh1 = remove_small_objects(equalized > otsu1) colonies = thresh1*equalized thresh2 = threshold_adaptive(colonies, 21) # Use morphological opening to help separate clusters and remove noise opened = binary_opening(thresh2, selem=disk(3)) if returnmasked == True: clusters = opened*equalized return(opened, masked) else: return opened
def grow_mask(anat, aseg, ants_segs=None, ww=7, zval=2.0, bw=4): """ Grow mask including pixels that have a high likelihood. GM tissue parameters are sampled in image patches of ``ww`` size. This is inspired on mindboggle's solution to the problem: https://github.com/nipy/mindboggle/blob/master/mindboggle/guts/segment.py#L1660 """ selem = sim.ball(bw) if ants_segs is None: ants_segs = np.zeros_like(aseg, dtype=np.uint8) aseg[aseg == 42] = 3 # Collapse both hemispheres gm = anat.copy() gm[aseg != 3] = 0 refined = refine_aseg(aseg) newrefmask = sim.binary_dilation(refined, selem) - refined indices = np.argwhere(newrefmask > 0) for pixel in indices: # When ATROPOS identified the pixel as GM, set and carry on if ants_segs[tuple(pixel)] == 2: refined[tuple(pixel)] = 1 continue window = gm[ pixel[0] - ww:pixel[0] + ww, pixel[1] - ww:pixel[1] + ww, pixel[2] - ww:pixel[2] + ww ] if np.any(window > 0): mu = window[window > 0].mean() sigma = max(window[window > 0].std(), 1.e-5) zstat = abs(anat[tuple(pixel)] - mu) / sigma refined[tuple(pixel)] = int(zstat < zval) refined = sim.binary_opening(refined, selem) return refined
def volumeMask(vol): """ :param vol: a 3-dimensional numpy array :return: mask, a binary mask with the same shape as vol, and mCoords, a list of (x,y,z) indices representing the masked coordinates. """ from numpy import array, where from scipy.signal import medfilt2d from skimage.filter import threshold_otsu from skimage import morphology as morph filtVol = array([medfilt2d(x.astype('float32')) for x in vol]) thr = threshold_otsu(filtVol.ravel()) mask = filtVol > thr strel = morph.selem.disk(3) mask = array([morph.binary_closing(x, strel) for x in mask]) mask = array([morph.binary_opening(x, strel) for x in mask]) z, y, x = where(mask) mCoords = zip(x, y, z) return mask, mCoords
def _apply_threshold(img, threshold): binary_img = img < threshold #remove small speckles binary_img = binary_opening(binary_img, disk(3)) return binary_img
def func(frame): opened = binary_opening(frame, disk(smooth_size)) opened = opened & frame return opened
from skimage import filters import matplotlib.pyplot as plt from scipy import ndimage as ndi from skimage import morphology from skimage import feature import os test1 = io.imread("Img09-3.tif", 1) edge_img = io.imread("edges.png",1) testnp = np.asarray(test1) testnp = testnp[0:1024,0:1024] val = filters.threshold_otsu(testnp) mask = testnp < val morphology.binary_opening(mask, morphology.diamond(10)).astype(np.uint8) edges1 = feature.canny(mask) edges2 = feature.canny(mask, sigma = 3) fig, (ax1, ax2, ax3) = plt.subplots(nrows=1, ncols=3,figsize =(8,3), sharex = True, sharey = True) ax1.imshow(mask, cmap=plt.cm.gray) ax1.axis('off') ax1.set_title('noisy image', fontsize=20) ax2.imshow(edges1, cmap=plt.cm.gray) ax2.axis('off') ax2.set_title('Canny filter, $\sigma=1$', fontsize=20) ax3.imshow(edges2, cmap=plt.cm.gray) ax3.axis('off')
y_size = img.shape[0] dataset = driver.Create(filename, x_size, y_size) dataset.GetRasterBand(1).WriteArray(img) # load original image dataset = gdal.Open('img/mozambique-after-subset.tif') band = dataset.GetRasterBand(1) img = band.ReadAsArray().astype(np.uint8) # otsu thresholding of the image threshold = threshold_otsu(img) img_thresholded = img > threshold print 'Threshold for original image:', threshold write_image(img_thresholded, 'img/mozambique-after-thresholded.tif') # dilation of the thresholded image img_thresholded_dilated = binary_dilation(img_thresholded) write_image(img_thresholded_dilated, 'img/mozambique-after-thresholded-dilated.tif') # erosion of the thresholded image img_thresholded_eroded = binary_erosion(img_thresholded) write_image(img_thresholded_eroded, 'img/mozambique-after-thresholded-eroded.tif') # closing of the thresholded image img_thresholded_closed = binary_closing(img_thresholded) write_image(img_thresholded_closed, 'img/mozambique-after-thresholded-closed.tif') # opening of the thresholded image img_thresholded_opened = binary_opening(img_thresholded) write_image(img_thresholded_opened, 'img/mozambique-after-thresholded-opened.tif')
def opening3D(data, selem=skimor.disk(3)): for i in range(data.shape[0]): data[i,:,:] = skimor.binary_opening(data[i,:,:], selem) return data
num_col_strides = int_(between_fields.shape[1]/stride) r_stride = int_(between_fields.shape[0]/num_row_strides) c_stride = int_(between_fields.shape[1]/num_col_strides) for r in range(num_row_strides+1): for c in range(num_col_strides+1): h, theta, d = hough_line(between_fields[r*r_stride:(r+1)*r_stride, c*c_stride:(c+1)*c_stride]) threshold = 0 #0.0005*max(h) h, theta, d = hough_line_peaks(h, theta, d, min_distance=20, threshold=threshold) for n in range(len(theta)): if abs(theta[n]) < 0.1 or abs(theta[n]) > ((pi/2) - 0.1): draw_hough_line(field_mask[r*r_stride:(r+1)*r_stride, c*c_stride:(c+1)*c_stride], d[n], theta[n]) # do a few small openings field_mask = binary_opening(field_mask, rectangle(1, 5)) field_mask = binary_opening(field_mask, rectangle(5, 1)) imsave(fname_template.format('segmented_fields', 'png'), field_mask) # Label fields field_mask = label(field_mask, 4, 0) + 1 remove_small_objects(field_mask, 100, 1, True) field_props = regionprops(field_mask) # Write field_props to csv file out_file = open(fname_template.format('field_props', 'csv'), 'w') print('label,area,center_row,center_col,nw_col,nw_row,se_col,se_row', file=out_file) for prop in field_props: if (prop.area > 100) and (prop.area < 700): print(','.join([str(x) for x in [ prop.label,
def hierarchical_segmentation(grayscale, pickle_me=False): ''' Segments a grayscale image by first applying adaptive histogram equalization to enhance contrast followed by an Otsu threshold to isolate cell colonies. An adaptive thresholding method is then used to isolate clusters of close-packed cells. Estimated regions of interest for individual cells are finally generated using the Watershed algorithm, and the cell regions are given unique labels and various measurements are calculated for the regions from the original grayscale image. Inputs: ------- grayscale: A grayscale image loaded into a NumPy array pickle_me: Boolean, dumps NumPy arrays of intermediate images to pickle files in the current working directory if True Outputs: -------- labels: The labels associated with the thresholded regions props: The properties of the regions-of-interest measured from the original grayscale image ''' # Apply CLAHE equalized = equalize_adapthist(grayscale, ntiles_x=16, ntiles_y=16, clip_limit=0.01, nbins=256) # Otsu threshold of CLAHE equalized "grayscale" otsu1 = threshold_otsu(equalized) print "Otsu threshold: {0}".format(otsu1) thresh1 = remove_small_objects(equalized > otsu1) colonies = thresh1*equalized thresh2 = threshold_adaptive(colonies, 21) # Use morphological opening to help separate clusters and remove noise opened = binary_opening(thresh2, selem=disk(3)) clusters = opened*equalized # Generate labels for Watershed using local maxima of the distance # transform as markers distance = distance_transform_edt(opened) local_maxi = peak_local_max(distance, min_distance=6, indices=False, labels=opened) markers = ndimage.label(local_maxi)[0] # plt.imshow(markers) # Apply Watershed labels = watershed(-distance, markers, mask=opened) # plt.imshow(label2rgb(labels)) # Measure labeled region properties in the illumination-corrected image # (not the contrast stretched image) props = regionprops(labels, intensity_image=grayscale) # fig, axs = plt.subplots(2, 4) # axs[0, 0].imshow(equalized, cmap=plt.cm.gray) # axs[0, 0].set_title('CLAHE Equalized') # axs[0, 1].imshow(thresh1, cmap=plt.cm.gray) # axs[0, 1].set_title('Threshold 1, Otsu') # axs[0, 2].imshow(colonies, cmap=plt.cm.gray) # axs[0, 2].set_title('Colonies') # axs[0, 3].imshow(thresh2, cmap=plt.cm.gray) # axs[0, 3].set_title('Threshold 2, Adaptive') # axs[1, 0].imshow(opened, cmap=plt.cm.gray) # axs[1, 0].set_title('Threshold 2, Opened') # axs[1, 1].imshow(clusters, cmap=plt.cm.gray) # axs[1, 1].set_title('Clusters') # axs[1, 2].imshow(distance, cmap=plt.cm.gray) # axs[1, 2].set_title('Distance Transform') # axs[1, 3].imshow(label2rgb(labels)) # axs[1, 3].set_title('Labelled Segmentation') if pickle_me: equalized.dump('CLAHE_equalized.p') thresh1.dump('thresh1_otsu.p') colonies.dump('colonies.p') thresh2.dump('thresh2_adaptive.p') opened.dump('opened_thresh2.p') clusters.dump('clusters.p') distance.dump('distance_transform.p') markers.dump('max_dist_markers.p') return(labels, props)
dest = image_source.split(image_name)[0] if verbose: print "\n" + pa + "*** Starting to vectorize image %s ***"%image_name print "\n" + pa + "Current step: Image preparations" start = time.clock() #start timer previous_step = time.clock() image = nh.getImage(image_source).astype(np.uint8) #Load the image. if image.ndim > 2: image = nh.RGBtoGray(image) #In case it is not yet grayscale, convert to grayscale. image = np.where(image < 127,0,1) #In case it is not yet binary, perform thresholding image = remove_small_objects(image.astype(bool),\ min_size=minimum_feature_size,connectivity=1) if smoothing: #standard binary image noise-removal with opening followed by closing image = binary_opening(image,disk(smoothing)) #maybe remove this processing step if depicted structures are really tiny image = binary_closing(image,disk(smoothing)) if minimum_feature_size: image = remove_small_objects(image.astype(bool),\ min_size=minimum_feature_size,connectivity=1) distance_map = nh.cvDistanceMap(image).astype(np.int) #Create distance map height,width = distance_map.shape if save_distance_map: scipy.misc.toimage(distance_map, cmin=0, cmax=255)\ .save(join(dest,image_name + "_dm.png")) #save the distance map in case we need it later if debug: scipy.misc.imsave(join(dest,image_name + "_processed.png"),image) #debug output if verbose:
cleared__ = clear_border(nuclei__) # closed = binary_closing(cleared, disk(int(sys.argv[2]))) # # closed_ = binary_closing(cleared_, disk(int(sys.argv[2]))) # # closed__ = binary_closing(cleared__, disk(int(sys.argv[2]))) filled = ndi.binary_fill_holes(cleared) filled_ = ndi.binary_fill_holes(cleared_) filled__ = ndi.binary_fill_holes(cleared__) bopened = binary_opening(filled, disk(int(sys.argv[2]))) bopened_ = binary_opening(filled_, disk(int(sys.argv[3]))) bopened__ = binary_opening(filled__, disk(int(sys.argv[4]))) boundaries = find_boundaries(bopened, mode="inner") boundaries_ = find_boundaries(bopened_, mode="inner") boundaries__ = find_boundaries(bopened__, mode="inner") # plt.subplot(131) # # plt.imshow(hematoxylin_) #
if sigma != int(sigma): print('skipping σ={}'.format(sigma)) continue # get 'structureness' for each channel at each pixel R = (K1 / K2)**2 # conservative threshold R_thresh = ma.median(R) targets = (R < R_thresh).all(axis=-1).filled(0) # erode based on scale space selem = disk(sigma) targets = binary_opening(targets, selem=selem) #targets = remove_small_objects(targets, min_size=selem.sum() + 1) labeled, n_labels = label(targets, background=0, connectivity=1, return_num=True) sizes = np.bincount(labeled.flatten()) rankings = np.argsort(sizes) # labels for the N largest regions N = 30 # number of regions to view largest = rankings[-(1+N):-1] #size_thresh = sigma**2 #largest = np.argwhere(sizes >= size_thresh).flatten()[1:] #N= largest.size #if N > 100:
def crop_lesion(image, attrs={}, debug=False): """ crop image to the segmented lesion """ cleaned = binary_opening(image[...,3], disk(3)) labels = label(cleaned, 4, background=0) props = regionprops(labels+1, intensity_image=rgb2gray(image)) sizes = [ (p['area'], i) for i, p in enumerate(props) ] max_value, max_index = max(sizes) p = props[max_index] bbox = p['bbox'] image_roi = image[bbox[0]:bbox[2], bbox[1]:bbox[3], :3].copy() alpha_roi = p['filled_image'] # or 'image' if debug: print """\ Image properties ---------------- Area : %d (%d filled) Centroid : (%.3f, %.3f) Axes : (%.3f, %.3f) Orientation : %.3f """ % ( p['area'], p['filled_area'], p['centroid'][1], p['centroid'][0], p['major_axis_length'], p['minor_axis_length'], math.degrees(p['orientation']) ) plt.subplot(221) plt.imshow(image[...,3]) plt.subplot(222) plt.imshow(labels) plt.subplot(223) imgplot = plt.imshow(image_roi) imgplot.set_interpolation('nearest') plt.subplot(224) imgplot = plt.imshow(alpha_roi) imgplot.set_interpolation('nearest') plt.show() attrs.update([ ('Lesion Area', int(p['area'])), ('Lesion Area Filled', p['filled_area']), ('--Lesion Centroid X', p['centroid'][1]), ('--Lesion Centroid Y', p['centroid'][0]), ('--Lesion Orientation', math.degrees(p['orientation']) % 180), ('--Lesion Extent', p['extent']), ('Lesion Perimeter', p['perimeter']), ('Lesion Solidity', p['solidity']), ('Lesion Major Axis Length', p['major_axis_length']), ('Lesion Minor Axis Length', p['minor_axis_length']), ('--Lesion Bounding Box X1', p['bbox'][1]), ('--Lesion Bounding Box Y1', p['bbox'][0]), ('--Lesion Bounding Box X2', p['bbox'][3]), ('--Lesion Bounding Box Y2', p['bbox'][2]), ('Lesion Intensity Min', p['min_intensity']), ('Lesion Intensity Mean', p['mean_intensity']), ('Lesion Intensity Max', p['max_intensity']), ('Lesion Eccentricity', p['eccentricity']), ('Lesion FormFactor', p['area'] / (p['perimeter']**2)), ]) return np.dstack((image_roi, alpha_roi))
def predict(img, path=test_image_dir): c_img = imread(os.path.join(path, c_img_name)) c_img = np.expand_dims(c_img, 0)/255.0 cur_seg = final_model.predict(c_img)[0] cur_seg = binary_opening(cur_seg>0.5, np.expand_dims(disk(2), -1)) return cur_seg, c_img
# <codecell> x = [] for i in range(3, 51, 2) : s = filter.gaussian_filter(clean, i) x.append(len(feature.peak_local_max(ndimage.distance_transform_edt(s > filter.threshold_otsu(s)), min_distance=5))) plt.plot(range(3, 51, 2), x) # <codecell> Q = [clean] kernelsize = 51 downsamplesize = 3 for i in range(1, 6) : im = filter.gaussian_filter(morphology.binary_opening(Q[i-1], morphology.disk(5)), kernelsize) im2 = zeros((im.shape[0]/downsamplesize, im.shape[1]/downsamplesize)) for x in range(im2.shape[0]) : for y in range(im2.shape[1]) : im2[x, y] = np.mean(im[downsamplesize*x:downsamplesize*(x+1), downsamplesize*y:downsamplesize*(y+1)]) im2 -= im2.min() im2 /= im2.max() Q.append(np.round(im2*1.)) # <codecell> q = [] for i in Q : q.append(np.sum(i) / (i.shape[0] * i.shape[1])) plt.plot(q)