def binaryFillHoles(binarydata, kernel=np.ones((3, 3, 3))): result = np.zeros_like(binarydata) if kernel is None: ndimage.binary_fill_holes(binarydata, output=result) else: ndimage.binary_fill_holes(binarydata, structure=kernel, output=result) return result
def obj_fill_holes(array, labelled=True): """ Fills holes within objects. """ if labelled: fill = ndimage.binary_fill_holes(array > 0) #holes = fill - array else: fill = ndimage.binary_fill_holes(array) return fill
def pestFeatureExtraction(filename): selem = disk(8) image = data.imread(filename,as_grey=True) thresh = threshold_otsu(image) elevation_map = sobel(image) markers = np.zeros_like(image) if ((image<thresh).sum() > (image>thresh).sum()): markers[image < thresh] = 1 markers[image > thresh] = 2 else: markers[image < thresh] = 2 markers[image > thresh] = 1 segmentation = morphology.watershed(elevation_map, markers) segmentation = dilation(segmentation-1, selem) segmentation = ndimage.binary_fill_holes(segmentation) segmentation = np.logical_not(segmentation) image[segmentation]=0; hist = np.histogram(image.ravel(),256,[0,1]) hist = list(hist[0]) hist[:] = [float(x) / (sum(hist) - hist[0]) for x in hist] hist.pop(0) features = np.empty( (1, len(hist)), 'float' ) a = np.array(list(hist)) f = a.astype('float') features[0,:]=f[:] return features
def main(): for file_path in glob.glob("/home/lucas/Downloads/Lucas/GSK 10uM/*.JPG"): img = data.imread(file_path, as_grey=True) img = transform.resize(img, [600, 600]) img_color = transform.resize(data.imread(file_path), [600, 600]) img[img >img.mean()-0.1] = 0 # io.imshow(img) # io.show() # edges = canny(img) bordas_fechadas = closing(img > 0.1, square(15)) # fechando gaps fill_cells = ndi.binary_fill_holes(bordas_fechadas) # io.imshow(fill_cells) # io.show() img_label = label(fill_cells, background=0) n= 0 for x in regionprops(img_label): if x.area < 2000 and x.area > 300: n +=1 print x.area minr, minc, maxr, maxc = x.bbox try: out_path_name = file_path.split("/")[-1].rstrip(".JPG") io.imsave("out/cell_{}_pic_{}_area_{}.png".format(n, out_path_name, str(round(x.area))),img_color[minr-3: maxr+3, minc-3: maxc+3]) #io.show() except: pass
def clean_by_area(self, binary_image): image = binary_image.copy() image = ndi.binary_fill_holes(image) label_image = label(binary_image) initial_label = regionprops(label_image[0, :, :])[0].label for z in range(0, image.shape[0]): regions = regionprops(label_image[z, :, :]) for region in regions: if region.label != initial_label: for coords in region.coords: image[z, coords[0], coords[1]] = 0 for z in range(0, image.shape[0]): label_image = label(image[z, :, :], connectivity=1) regions = regionprops(label_image) if len(regions) > 1: max_area = np.max([r.area for r in regions]) for region in regions: if region.centroid[1] > 120 and region.area < max_area: for coords in region.coords: image[z, coords[0], coords[1]] = 0 return image
def segment(self, src): ndsrc = src.ndarray / 255. edges = canny(ndsrc, # low_threshold=0.001, # high_threshold=0.1, # low_threshold=self.canny_low_threshold, # high_threshold=self.canny_high_threshold, sigma=self.canny_sigma) filled = ndimage.binary_fill_holes(edges) filled = invert(filled) * 255 # label_objects, _ = ndimage.label(filled) # sizes = bincount(label_objects.ravel()) # # mask_sizes = sizes > 1 # mask_sizes[0] = 0 # cleaned = mask_sizes[label_objects] # cleaned = asarray(cleaned, 'uint8') # cleaned = closing(cleaned, square(5)) # self._locate_helper(invert(cleaned), **kw) nsrc = asarray(filled, 'uint8') return nsrc
def readBinIm(path): """ desc: Reads an image, converts to binary (0 for background, 1 for shape), and fills any internal holes. arguments: path: desc: The image path. type: [str, unicode] returns: desc: An image array. type: ndarray """ im = ndimage.imread(path, flatten=True) i1 = np.where(im == 255) i2 = np.where(im != 255) im[i1] = 0 im[i2] = 1 im = ndimage.binary_fill_holes(im) return im
def get_segmented_lungs(im): binary = im < -320 cleared = clear_border(binary) cleared=morph(cleared,5) label_image = label(cleared) areas = [r.area for r in regionprops(label_image)] areas.sort() if len(areas) > 2: for region in regionprops(label_image): if region.area < areas[-2]: for coordinates in region.coords: label_image[coordinates[0], coordinates[1]] = 0 binary = label_image > 0 selem = disk(2) binary = binary_erosion(binary, selem) selem = disk(10) binary = binary_closing(binary, selem) edges = roberts(binary) binary = ndi.binary_fill_holes(edges) get_high_vals = binary == 0 im[get_high_vals] = 0 binary = morphology.dilation(binary,np.ones([5,5])) return binary
def applyMorphologicalCleaning(self, image): """ Applies a variety of morphological operations to improve the detection of worms in the image. Takes 0.030 s on MUSSORGSKY for a typical frame region Takes 0.030 s in MATLAB too """ # start with worm == 1 image = image.copy() segmentation.clear_border(image) # remove objects at edge (worm == 1) # fix defects in the thresholding by closing with a worm-width disk # worm == 1 wormSE = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (self.wormDiskRadius+1, self.wormDiskRadius+1)) imcl = cv2.morphologyEx(np.uint8(image), cv2.MORPH_CLOSE, wormSE) imcl = np.equal(imcl, 1) # fix defects by filling holes imholes = ndimage.binary_fill_holes(imcl) imcl = np.logical_or(imholes, imcl) # fix barely touching regions # majority with worm pixels == 1 (median filter same?) imcl = nf.median_filter(imcl, footprint=[[1, 1, 1], [1, 0, 1], [1, 1, 1]]) # diag with worm pixels == 0 imcl = np.logical_not(bwdiagfill(np.logical_not(imcl))) # open with worm pixels == 1 openSE = cv2.getStructuringElement(cv2.MORPH_RECT, (1, 1)) imcl = cv2.morphologyEx(np.uint8(imcl), cv2.MORPH_OPEN, openSE) return np.equal(imcl, 1)
def compute_mask(self, params): """Creates the mask for the base image. Needs the base image, an instance of imageloaderparams and the clip area, which should be already defined by the load_base_image method. Creates the mask by improving the base mask created by the compute_base_mask method. Applies the mask closing, dilation and fill holes parameters. """ self.compute_base_mask(params) mask = np.copy(self.base_mask) closing_matrix = np.ones((params.mask_closing, params.mask_closing)) if params.mask_closing > 0: # removes small dark spots and then small white spots mask = img_as_float(morphology.closing( mask, closing_matrix)) mask = 1 - \ img_as_float(morphology.closing( 1 - mask, closing_matrix)) for f in range(params.mask_dilation): mask = morphology.erosion(mask, np.ones((3, 3))) if params.mask_fill_holes: # mask is inverted mask = 1 - img_as_float(ndimage.binary_fill_holes(1.0 - mask)) self.mask = mask self.overlay_mask_base_image()
def clean_classified_image(self): """ clean the binary image resulting from pixel classification using morphological operators """ if self.class_image is None: self.classify_image() bim = self.class_image feature_mask = self.features_object.mask_image if feature_mask is not None: bim = bim & feature_mask bim = ni.binary_fill_holes(bim) min_gap = 0 for n in range(min_gap): bim = ni.binary_dilation(bim) #bim = ni.binary_closing(bim) #bim = ni.binary_fill_holes(bim) min_radius = 8 for n in range(min_radius): bim = ni.binary_erosion(bim) #bim = ni.binary_opening(bim) for n in range(min_radius): bim = ni.binary_dilation(bim) #bim = ni.binary_dilation(bim) #bim = ni.binary_erosion(bim) self.clean_class_image = bim.astype(np.uint8) * 255
def get_segmented_lungs(im, plot=False): # Step 1: Convert into a binary image. binary = im < -400 # Step 2: Remove the blobs connected to the border of the image. cleared = clear_border(binary) # Step 3: Label the image. label_image = label(cleared) # Step 4: Keep the labels with 2 largest areas. areas = [r.area for r in regionprops(label_image)] areas.sort() if len(areas) > 2: for region in regionprops(label_image): if region.area < areas[-2]: for coordinates in region.coords: label_image[coordinates[0], coordinates[1]] = 0 binary = label_image > 0 # Step 5: Erosion operation with a disk of radius 2. This operation is seperate the lung nodules attached to the blood vessels. selem = disk(2) binary = binary_erosion(binary, selem) # Step 6: Closure operation with a disk of radius 10. This operation is to keep nodules attached to the lung wall. selem = disk(10) # CHANGE BACK TO 10 binary = binary_closing(binary, selem) # Step 7: Fill in the small holes inside the binary mask of lungs. edges = roberts(binary) binary = ndi.binary_fill_holes(edges) # Step 8: Superimpose the binary mask on the input image. get_high_vals = binary == 0 im[get_high_vals] = -2000 return im, binary
def test_02_02_one_worm(self): '''Find a single worm''' image = np.zeros((20, 20), bool) index, count, i, j = get_line_pts( np.array([1,6,19,14]), np.array([5,0,13,18]), np.array([6,19,14,1]), np.array([0,13,18,5])) image[i,j] = True image = binary_fill_holes(image) workspace, module = self.make_workspace(image) module.worm_length.value = 12 module.worm_width.value = 5 module.angle_count.value = 16 module.run(workspace) m = workspace.measurements self.assertTrue(isinstance(m, cpmeas.Measurements)) count = m.get_current_image_measurement( '_'.join((ID.I.C_COUNT, OBJECTS_NAME))) self.assertEqual(count, 1) x = m.get_current_measurement(OBJECTS_NAME, ID.I.M_LOCATION_CENTER_X) self.assertEqual(len(x), 1) self.assertAlmostEqual(x[0], 9., 1) y = m.get_current_measurement(OBJECTS_NAME, ID.I.M_LOCATION_CENTER_Y) self.assertEqual(len(y), 1) self.assertAlmostEqual(y[0], 10., 1) a = m.get_current_measurement(OBJECTS_NAME, ID.M_ANGLE) self.assertEqual(len(a), 1) self.assertAlmostEqual(a[0], 135, 0)
def alg(ring): # fill holes in binary objects and then see if anything got filled xor = scipy.logical_xor(ring, ndimage.binary_fill_holes(ring)) if xor.any(): return True else: return False
def load_scenes(filename): zipped_scenes = [] print 'Working on: ' + filename img = data.imread('scenes/' + filename, as_grey=True) tmp = img tmp = filter.canny(tmp, sigma=2.0) tmp = ndimage.binary_fill_holes(tmp) #tmp = morphology.dilation(tmp, morphology.disk(2)) tmp = morphology.remove_small_objects(tmp, 2000) contours = measure.find_contours(tmp, 0.8) ymin, xmin = contours[0].min(axis=0) ymax, xmax = contours[0].max(axis=0) if xmax - xmin > ymax - ymin: xdest = 1000 ydest = 670 else: xdest = 670 ydest = 1000 src = np.array(((0, 0), (0, ydest), (xdest, ydest), (xdest, 0))) dst = np.array(((xmin, ymin), (xmin, ymax), (xmax, ymax), (xmax, ymin))) tform3 = tf.ProjectiveTransform() tform3.estimate(src, dst) warped = tf.warp(img, tform3, output_shape=(ydest, xdest)) tmp = filter.canny(warped, sigma=2.0) tmp = morphology.dilation(tmp, morphology.disk(2)) descriptor_extractor.detect_and_extract(tmp) obj_key = descriptor_extractor.keypoints scen_desc = descriptor_extractor.descriptors zipped_scenes.append([warped, scen_desc, obj_key, filename]) return zipped_scenes
def footprint_fitness_error(self, points): temp_footprint = np.zeros(self.FOOTPRINT_added_boundary.shape, dtype=np.uint8) len_points = len(points) for idx1 in xrange(0, len_points): rr,cc = line(points[idx1][0], points[idx1][1], points[idx1-1][0],points[idx1-1][1]) temp_footprint[rr,cc] = 1 temp_footprint = ndimage.binary_fill_holes(temp_footprint) temp_footprint = temp_footprint * 1 rr,cc = np.nonzero(temp_footprint) #RATIO OF ZEROS AND ONES SA LOOB zero_counter = 0.0 nonzero_counter = 0.0 for point in zip(rr,cc): if self.FOOTPRINT_added_boundary[point[0]][point[1]] == 0: zero_counter += 1.0 else: nonzero_counter += 1.0 footprint_copy = copy.deepcopy(self.FOOTPRINT_added_boundary) footprint_copy[rr,cc] = 0 nonzero = len(footprint_copy[footprint_copy != 0]) total = (len(footprint_copy[footprint_copy == 0]) + nonzero) * 1.0 return (nonzero / total) + (zero_counter / (nonzero_counter + zero_counter))
def __call__(self, image, window_size=10, threshold=0, fill_holes=True, outline_smoothing=2, remove_borderobjects=True, size_min=1, *args, **kw): thresh = threshold_adaptive(image, block_size=window_size, offset=-1*threshold) if outline_smoothing >= 1: thresh = outlineSmoothing(thresh, outline_smoothing) thresh = remove_small_objects(thresh, size_min) seeds = ndi.label(clear_border(~thresh))[0] thresh = ndi.binary_fill_holes(thresh) smask = seeds.astype(bool) # object don't touch border after outline smoothing if remove_borderobjects: thresh = clear_border(thresh) img = np.zeros(thresh.shape) img[~smask] = 1 edt = ndi.morphology.distance_transform_edt(img) edt -= ndi.morphology.distance_transform_edt(seeds) labels = watershed(edt, seeds) labels[smask] = 0 labels[~thresh] = 0 return labels
def compute_mask(aparc, labels=[0, 5000]): import nibabel as nb import numpy as np import os.path as op import scipy.ndimage as nd segnii = nb.load(aparc) seg = segnii.get_data() mask = np.ones_like(seg, dtype=np.uint8) for l in labels: mask[seg == l] = 0 struct = nd.iterate_structure(nd.generate_binary_structure(3, 1), 4) mask = nd.binary_dilation(mask, structure=struct).astype(np.uint8) mask = nd.binary_closing(mask, structure=struct) mask = nd.binary_fill_holes(mask, structure=struct).astype(np.uint8) mask[mask > 0] = 1 mask[mask <= 0] = 0 hdr = segnii.get_header().copy() hdr.set_data_dtype(np.uint8) hdr.set_xyzt_units("mm", "sec") out_file = op.abspath("nobstem_mask.nii.gz") nii = nb.Nifti1Image(mask, segnii.get_affine(), hdr).to_filename(out_file) return out_file
def segmentation(file_name): data_x, data_y, data_z = get_data(file_name) shape_x = len(np.unique(data_x)) shape_y = len(np.unique(data_y)) X = data_x.reshape(shape_x, shape_y) Y = data_y.reshape(shape_x, shape_y) Z = data_z.reshape(shape_x, shape_y) markers = np.zeros_like(Z) markers[Z < 0.15] = 1 markers[Z > 0.3] = 2 elevation_map = roberts(Z) fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(6, 3), sharex=True, sharey=True) # ax.imshow(Z) # ax.imshow(elevation_map, cmap=plt.cm.jet, interpolation='nearest') segmentation = watershed(elevation_map, markers) ax2.imshow(segmentation, interpolation='nearest') # ax.axis('off') # ax.set_title('segmentation') segmentation = ndi.binary_fill_holes(segmentation - 1) labeled_coins, _ = ndi.label(segmentation) ax1.imshow(Z, cmap=plt.cm.gray, interpolation='nearest') ax1.contour(segmentation, [0.5], linewidths=1.2, colors='y') ax1.axis('off') ax1.set_adjustable('box-forced') plt.show()
def guess_corners(bw): """ Infer the corners of an image using a Sobel filter to find the edges and a Harris filter to find the corners. Takes only as single color chanel. Parameters ---------- bw : (m x n) ndarray of ints Returns ------- corners : pixel coordinates of plot corners, unsorted outline : (m x n) ndarray of bools True -> plot area """ assert len(bw.shape) == 2 bw = img_as_uint(bw) e_map = ndimage.sobel(bw) markers = np.zeros(bw.shape, dtype=int) markers[bw < 30] = 1 markers[bw > 150] = 2 seg = ndimage.watershed_ift(e_map, np.asarray(markers, dtype=int)) outline = ndimage.binary_fill_holes(1 - seg) corners = harris(np.asarray(outline, dtype=int)) corners = approximate_polygon(corners, 1) return corners, outline
def form_mask_BR_v2(start_temp, max_temp, temp_rate): dtype = [('temp', float), ('mask', np.ndarray), ('dist', np.ndarray)] masks = [] #IMPROVEMENT!!! #MINUS LAST COORDINATES TO NEXT TEMPERATURE #LESS POINTS TO CHECK while (start_temp <= max_temp): coordinates = [] coor_dist = [] distance = int(round(start_temp)) array_size = distance * 2 + 1 img = np.zeros((array_size, array_size), dtype=np.uint8) rr, cc = circle_perimeter(distance, distance, distance) img[rr, cc] = 1 rr,cc = np.nonzero(ndimage.binary_fill_holes(img).astype(int)) img[rr, cc] = 1 for idx in xrange(0, len(rr)): dist_temp = np.linalg.norm(np.array([rr[idx], cc[idx]]) - np.array([distance, distance])) if dist_temp <= start_temp: coordinates.append([rr[idx], cc[idx]]) coor_dist.append(dist_temp) # coordinates.remove([distance, distance]) coordinates = coordinates - np.array([distance, distance]) masks.append((start_temp, coordinates, np.array(coor_dist))) start_temp += temp_rate return np.array(masks, dtype=dtype)
def main(): plt.figure(figsize=(25, 24)) planes = ['samolot00.jpg', 'samolot01.jpg', 'samolot03.jpg', 'samolot04.jpg', 'samolot05.jpg','samolot07.jpg', 'samolot08.jpg', 'samolot09.jpg', 'samolot10.jpg', 'samolot11.jpg', 'samolot12.jpg', 'samolot13.jpg', 'samolot14.jpg', 'samolot15.jpg', 'samolot16.jpg', 'samolot17.jpg', 'samolot18.jpg', 'samolot20.jpg'] i = 1 for file in planes: img = data.imread(file, as_grey=True) img2 = data.imread(file) ax = plt.subplot(6, 3, i) ax.axis('off') img **= 0.4 img = filter.canny(img, sigma=3.0) img = morphology.dilation(img, morphology.disk(4)) img = ndimage.binary_fill_holes(img) img = morphology.remove_small_objects(img, 1000) contours = measure.find_contours(img, 0.8) ax.imshow(img2, aspect='auto') for n, contour in enumerate(contours): ax.plot(contour[:, 1], contour[:, 0], linewidth=1.5) center = (sum(contour[:, 1])/len(contour[:, 1]), sum(contour[:, 0])/len(contour[:, 0])) ax.scatter(center[0], center[1], color='white') i += 1 plt.savefig('zad2.pdf')
def findPlantsCanny(stackVar, stackSum, showImages=True): edges = canny(stackVar) fill_stack = ndimage.binary_fill_holes(edges) label_objects, nb_labels = ndimage.label(fill_stack) sizes = np.bincount(label_objects.ravel()) mask_sizes = sizes > 25 for label in range(len(mask_sizes)): ''' Get rid of lines in addition to the straight size threshold. ''' pts = np.where(label_objects == label) xRange = (max(pts[0]) - min(pts[0])) yRange = (max(pts[1]) - min(pts[1])) areaCovered = float(len(pts[0])) / (xRange*yRange) if (areaCovered < .33) or (xRange < 3) or (yRange < 3): mask_sizes[label] = False mask_sizes[0] = 0 plants_cleaned = mask_sizes[label_objects] labeled_plants, numPlants = ndimage.label(plants_cleaned) center = findCenters(labeled_plants, stackSum) if showImages: fig, axs = plt.subplots(1,3, figsize=(14,4), sharey=True) axs[0].imshow(stackVar) axs[1].imshow(stackVar, cmap=plt.cm.jet, interpolation='nearest') #@UndefinedVariable axs[1].contour(plants_cleaned, [0.5], linewidths=1.2, colors='y') axs[2].imshow(labeled_plants, cmap=plt.cm.spectral, interpolation='nearest') #@UndefinedVariable axs[2].scatter(np.array(center.tolist())[:,1], np.array(center.tolist())[:,0], color='grey') for ax in axs: ax.axis('off') fig.subplots_adjust(wspace=.01) return labeled_plants, center
def im_proc(im): """Apply series of morphological procedures on image.""" th = threshold_otsu(im) im_bin = im > th return(ndi.binary_fill_holes( morphology.closing( im_bin,np.ones((3,3)))))
def _segment_watershed(image): elevation_map = sobel(image) markers = np.zeros(image.shape) # initialize markers as zero array # determine thresholds for markers sorted_pixels = np.sort(image, axis=None) max_int = np.mean(sorted_pixels[-10:]) min_int = np.mean(sorted_pixels[:10]) #max_int = np.max(orig_image) #min_int = np.min(orig_image) alpha_min = 0.01 alpha_max = 0.4 thresh_background = (1-alpha_min)*min_int + alpha_min*max_int thresh_spots = (1-alpha_max)*min_int + alpha_max*max_int markers[image < thresh_background] = 1 # mark background markers[image > thresh_spots] = 2 # mark background segmentation = watershed(elevation_map, markers) segmentation = segmentation-1 segmentation = ndi.binary_fill_holes(segmentation) # fill holes return segmentation
def detect_clouds(self,k=np.array([[-1,-2,-1],[0,0,0],[1,2,1]]), umbral=40): 'Descripcion: Obtiene los bordes de una imagen entregada \n'\ 'puede retornar los bordes y entregar la imagen rellenada \n'\ '\n'\ 'Parametros\n'\ '----------\n'\ 'imageIn : Imagen raster con informacion de Z o de ref.\n'\ 'k : forma del filtro que se utiliza para obtener los bordes.\n'\ 'umbral : Umbral utilizado para determinar si un objeto es o no.\n'\ ' un borde.\n'\ '\n'\ 'Retornos\n'\ '----------\n'\ 'borders : Matriz con los bordes detectados.\n'\ 'binario : Matriz binaria con los bordes rellenos.\n'\ '\n'\ 'Ejemplo\n'\ '----------\n'\ 'borders,binario=detect_clouds(Z).\n'\ #Obtiene el gradiente, y el binario gradiente=radar_f90.detect_clouds(self.Z,k,k.T,radar_f90.ncols,radar_f90.nrows) bordes=np.zeros(gradiente.shape) bordes[gradiente>umbral]=1 #Llena el binario y quita el ruido binario=nd.binary_fill_holes(bordes)*1 #Retorna lo obtenido self.borders=bordes self.binario=binario
def _segment_threshold(image): thresh = threshold_otsu(image) seg = image > thresh seg = ndi.binary_fill_holes(seg) # fill holes return seg
def fill_holes(self, binary_image, selem, iterations): image = binary_image.copy() for j in range(0, iterations): image = dilation(image, selem) image = ndi.binary_fill_holes(image) for j in range(0, iterations): image = erosion(image, selem) return image
def applyFilter(self, data, chanNum, frNum, im): import skimage.morphology if len(data.shape) == 3: #3D selem = skimage.morphology.ball(self.radius) else: selem = skimage.morphology.disk(self.radius) return ndimage.binary_fill_holes(data, selem)
def analyse(self, **kwargs): image_object = kwargs['image'] if image_object is None: raise RuntimeError() # Read the image image = cv2.imread(self.image_utils.getOutputFilename(image_object.id)) if image is None: print('File not found') return # Work on green channel gray = image[:, :, 1] # Apply otsu thresholding thresh = filters.threshold_otsu(gray) gray[gray < thresh] = 0 # Apply histogram equalization gray = exposure.equalize_adapthist(gray) * 255 # Create elevation map elevation_map = filters.sobel(gray) gray = gray.astype(int) # Create cell markers markers = numpy.zeros_like(gray) markers[gray < 100] = 2 # seen as white in plot markers[gray > 150] = 1 # seen as black in plot # Segment with watershed using elevation map segmentation = morphology.watershed(elevation_map, markers) segmentation = ndi.binary_fill_holes(segmentation - 1) # labeled_image, n = ndi.label(segmentation) # Watershed with distance transform kernel = numpy.ones((5, 5), numpy.uint8) distance = ndi.distance_transform_edt(segmentation) distance2 = cv2.erode(distance, kernel) distance2 = cv2.dilate(distance2, kernel) local_max = peak_local_max(distance2, num_peaks=1, indices=False, labels=segmentation) markers2 = ndi.label(local_max)[0] labels = morphology.watershed(-distance2, markers2, mask=segmentation) # Extract regions (caching signifies more memory use) regions = regionprops(labels, cache=True) # Filter out big wrong regions regions = [region for region in regions if region.area < 2000] # Set result result = str(len(regions)) return result
def run(self, ips, snap, img, para=None): ndimg.binary_fill_holes(snap, output=img) img *= 255
# Create method identifier method_id = [m for m in mlist for s in slist for rdx in range(nrun)] # Resample images to geometry of template and rescale TSNR value with SQRT(NVol) imgs = [] for i, e in enumerate(method_id): if 'spm' in e: img = resample_to_img(filelist[i], template) else: img = load_img(filelist[i]) imgs.append(math_img('img * np.sqrt(%d)' % nvol, img=img)) # Create mask (containing only voxels with values in at least half of the images) img_concat = concat_imgs(imgs) mask = np.sum(img_concat.get_data()!=0, axis=-1)>=(img_concat.shape[-1] * 0.8) mask = binary_fill_holes( binary_dilation(binary_erosion(mask, iterations=2), iterations=2)) group_mask = new_img_like(img_concat, mask.astype('int'), copy_header=True) # Create 2nd-level model design_matrix = design_matrix = pd.get_dummies(method_id) second_level_model = SecondLevelModel(n_jobs=-1, mask=group_mask) second_level_model = second_level_model.fit(imgs, design_matrix=design_matrix) # Compute contrasts, save nifti and plot glass brain weights = [ [1, 0, 0, 0, 0], [1,-1, 0, 0, 0], [1, 0,-1, 0, 0], [1, 0, 0,-1, 0], [1, 0, 0, 0,-1], [-1, 1, 0, 0, 0], [0, 1, 0, 0, 0], [0, 1,-1, 0, 0], [0, 1, 0,-1, 0], [0, 1, 0, 0,-1], [-1, 0, 1, 0, 0], [0,-1, 1, 0, 0], [0, 0, 1, 0, 0], [0, 0, 1,-1, 0], [0, 0, 1, 0,-1], [-1, 0, 0, 1, 0], [0,-1, 0, 1, 0], [0, 0,-1, 1, 0], [0, 0, 0, 1, 0], [0, 0, 0, 1,-1], [-1, 0, 0, 0, 1], [0,-1, 0, 0, 1], [0, 0,-1, 0, 1], [0, 0, 0,-1, 1], [0, 0, 0, 0, 1]] for i, w in enumerate(weights):
from skimage.feature import canny edges = canny(coins) fig, ax = plt.subplots(figsize=(4, 3)) ax.imshow(edges, cmap=plt.cm.gray) ax.set_title('Canny detector') ax.axis('off') plt.savefig('LKP7/canny.png') ###################################################################### # These contours are then filled using mathematical morphology. from scipy import ndimage as ndi fill_coins = ndi.binary_fill_holes(edges) fig, ax = plt.subplots(figsize=(4, 3)) ax.imshow(fill_coins, cmap=plt.cm.gray) ax.set_title('filling the holes') ax.axis('off') plt.savefig('LKP7/filling the holes') ###################################################################### # Small spurious objects are easily removed by setting a minimum size for # valid objects. from skimage import morphology coins_cleaned = morphology.remove_small_objects(fill_coins, 21)
""" Created on Thu Oct 22 11:30:55 2020 @author: Usuario """ import cv2 #OpenCV import numpy as np import matplotlib.pyplot as plt from scipy import ndimage img1 = cv2.imread('img/bananas.jpg') I = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY) umbral, _ = cv2.threshold(I, 0, 255, cv2.THRESH_OTSU) mascara = np.uint8((I < umbral) * 255) #Binary image #cv2.imshow("Img-COLOR",img1) #cv2.imshow("Img-GRAY",I) cv2.imshow("Img-BINARY", mascara) #Get labels output = cv2.connectedComponentsWithStats(mascara, 4, cv2.CV_32F) cantObj = output[0] #objects quantify labels = output[1] #labels stats = output[2] #Get ArgMax mascara = (np.argmax(stats[:, 4][1:]) + 1 == labels) mascara = ndimage.binary_fill_holes(mascara).astype(int) cv2.waitKey(0) cv2.destroyAllWindows()
def ProcessImage(path): global count count += 1 sys.stderr.write('%3d Processing %s...\n' % (count, path)) rects = [] B = LoadAndBinarizeImage(path) # Exclude borders B[:10, :] = 0 B[-10:, :] = 0 B[:, :10] = 0 B[:, -10:] = 0 if ShowImage: ShowBinaryArray(B) B = ndimage.binary_fill_holes(B, structure=np.ones((2, 2))) if ShowImage: ShowBinaryArray(B) # Following # http://scipy-lectures.github.com/advanced/image_processing/index.html s = ndimage.generate_binary_structure(2, 2) label_im, nb_labels = ndimage.label(B, structure=s) # remove small components # TODO(danvk): how does this work? sizes = ndimage.sum(B, label_im, range(nb_labels + 1)) mask_size = sizes < 1000 remove_pixel = mask_size[label_im] label_im[remove_pixel] = 0 labels = np.unique(label_im) label_im = np.searchsorted(labels, label_im) # Use OpenCV to get info about each component. # http://stackoverflow.com/questions/9056646/python-opencv-find-black-areas-in-a-binary-image cs, _ = cv2.findContours(label_im.astype('uint8'), mode=cv2.RETR_LIST, method=cv2.CHAIN_APPROX_SIMPLE) # regions ordered by area regions = [(cv2.moments(c)['m00'], idx) for idx, c in enumerate(cs)] regions.sort() regions.reverse() for area, idx in regions: c = cs[idx] #convexI = np.zeros(label_im.shape[0:2]).astype('uint8') x, y, w, h = cv2.boundingRect(c) ConvexHull = cv2.convexHull(c) ConvexArea = cv2.contourArea(ConvexHull) Solidity = area / ConvexArea if ConvexArea else 0 #cv2.drawContours( convexI, [ConvexHull], -1, # color=255, thickness=-1 ) x2 = x + w y2 = y + h if w > 20 and h > 20: sys.stderr.write('%d x %d, solidity %f\n' % (w, h, Solidity)) if w > MIN_PHOTO_SIZE and h > MIN_PHOTO_SIZE and Solidity > MIN_PHOTO_SOLIDITY: rects.append({ 'left': 80 + 5 * x, 'top': 80 + 5 * y, 'right': 80 + 5 * x2, 'bottom': 80 + 5 * y2, 'solidity': Solidity }) output = { 'file': path, 'shape': { 'w': 5 * B.shape[1] + 160, 'h': 5 * B.shape[0] + 160 } } if AcceptPhotoDetection(B, rects): output['rects'] = rects print json.dumps(output)
def manualSliceBySlice(img, initLineList=None, lengthScaleRatio=0.2): if initLineList is not None: if isinstance(initLineList, list) and len(initLineList[0].shape) == 2: a = img.show(disable=['click', 'swap'], initLineList=initLineList) else: newInitLineList = [[]] currentslice = initLineList[0][0] for n in range(len(initLineList)): if currentslice != initLineList[n][0]: newInitLineList.append([]) currentslice = initLineList[n][0] newInitLineList[-1].append(initLineList[n]) for n in range(len(newInitLineList)): newInitLineList[n] = np.array(newInitLineList[n]) a = img.show(disable=['click', 'swap'], initLineList=newInitLineList) else: a = img.show(disable=['click', 'swap']) while not (a.enter): a = img.show(disable=['click', 'swap'], initLineList=a.lines) for n in range(len(a.lines) - 1, -1, -1): if len(a.lines[n]) < 3: a.lines.pop(n) if a.color: if len(img.dim) > 4: raise Exception('Dimension of image more than 3,' + str(img.dim)) else: if len(img.dim) > 3: raise Exception('Dimension of image more than 3,' + str(img.dim)) getind = [] for n in range(len(a.lines)): getind.append(a.lines[n][0][0]) getind = np.array(getind).astype(int) a.lines = [a.lines[i] for i in np.sort(getind)] aind = 0 img2 = img.clone() if a.color: img2.changeGreyscaleFormat() img2.data[:] = 0 img2.data = img2.data.astype('uint8') minArea = float('inf') for n in range(img2.data.shape[0]): while a.lines[aind][0][0] == n: for num in [1000, 10000, 100000, 1000000]: ar = np.array(a.lines[aind]) tck, temp = interpolate.splprep([ar[:, -2], ar[:, -1]], s=0, k=min(4, len(ar)) - 1) cspline_detectline = np.array( interpolate.splev(np.linspace(0, 1, num=num), tck)).T cspline_detectline = np.floor(cspline_detectline).astype(int) for nn in range(len(cspline_detectline)): img2.data[n][tuple(cspline_detectline[nn])] = 1 ar2 = np.array([ar[0], 0.5 * (ar[0] + ar[-1]), ar[-1]]) tck, temp = interpolate.splprep([ar2[:, -2], ar2[:, -1]], s=0, k=1) cspline_detectline = np.array( interpolate.splev(np.linspace(0, 1, num=num), tck)).T cspline_detectline = np.floor(cspline_detectline).astype(int) for nn in range(len(cspline_detectline)): img2.data[n][tuple(cspline_detectline[nn])] = 1 countpixel = img2.data[n].sum() img2.data[n] = binary_fill_holes(img2.data[n]).astype( img2.data.dtype) if img2.data[n].sum() > (countpixel * 1.1): break else: logger.warning( 'Could not form a closed surface with area larger than 1.1 of boundary on Slice ' + str(n)) temp_area = img2.data[n].sum() if temp_area < minArea: minArea = temp_area aind += 1 if aind >= len(a.lines): break if aind >= len(a.lines): break img2.data *= 255 lengthScale = max(2, lengthScaleRatio * minArea**0.5) img2.data = gaussian_filter(img2.data, (0, lengthScale, lengthScale)) img3 = img2.clone() currentind = 0 for n in range(getind[0] + 1, getind[-1]): if n == getind[currentind + 1]: currentind += 1 else: ratio = float(n - getind[currentind]) / (getind[currentind + 1] - getind[currentind]) img3.data[n] = (img2.data[getind[currentind + 1]] * ratio + img2.data[getind[currentind]] * (1. - ratio)).astype(img2.data.dtype) sigma = [] if a.color: nDim = [0, -3, -2] else: nDim = [0, -2, -1] for n in nDim: sigma.append(img3.dimlen[img3.dim[n]]) sigma = 1. / np.array(sigma) sigma = sigma / sigma[1:].mean() * lengthScale img3.data = gaussian_filter(img3.data, sigma) return (a.lines, img3)
def fillHoles(bImg): return ndimage.binary_fill_holes(bImg)
def get_segmented_lungs(im, plot=True): ''' This funtion segments the lungs from the given 2D slice. ''' # if plot == True: # f, plots = plt.subplots(8, 1, figsize=(40, 40)) ''' Step 1: Convert into a binary image. ''' print('step1') binary = im < 604 plt.imshow(binary, cmap=plt.cm.gray) plt.show() ''' Step 2: Remove the blobs connected to the border of the image. ''' print('step2') cleared = clear_border(binary) plt.imshow(cleared, cmap=plt.cm.gray) plt.show() ''' Step 3: Label the image. ''' print('step3') label_image = label(cleared) plt.imshow(label_image, cmap=plt.cm.gray) plt.show() ''' Step 4: Keep the labels with 2 largest areas. ''' print('step4') areas = [r.area for r in regionprops(label_image)] areas.sort() if len(areas) > 2: for region in regionprops(label_image): if region.area < areas[-2]: for coordinates in region.coords: label_image[coordinates[0], coordinates[1]] = 0 binary = label_image > 0 plt.imshow(binary, cmap=plt.cm.gray) plt.show() ''' Step 5: Erosion operation with a disk of radius 2. This operation is seperate the lung nodules attached to the blood vessels. ''' print('step5') selem = disk(2) binary = binary_erosion(binary, selem) plt.imshow(binary, cmap=plt.cm.gray) plt.show() ''' Step 6: Closure operation with a disk of radius 10. This operation is to keep nodules attached to the lung wall. ''' print('step6') selem = disk(10) binary = binary_closing(binary, selem) plt.imshow(binary, cmap=plt.cm.gray) plt.show() ''' Step 7: Fill in the small holes inside the binary mask of lungs. ''' print('step7') edges = roberts(binary) binary = ndi.binary_fill_holes(edges) plt.imshow(binary, cmap=plt.cm.gray) plt.show() ''' Step 8: Superimpose the binary mask on the input image. ''' print('step8') get_high_vals = binary == 0 im[get_high_vals] = 0 plt.imshow(im, cmap=plt.cm.gray) plt.show() return im
def load_mask(self, image_id): """Generate instance masks for an image. Returns: masks: A bool array of shape [height, width, instance count] with one mask per instance. class_ids: a 1D array of class IDs of the instance masks. """ # If not a Mitochondria dataset image, delegate to parent class. image_info = self.image_info[image_id] nuevo = os.path.dirname(os.path.dirname(image_info['path'])) nuevo = os.path.join(nuevo, 'mask') path, filename = os.path.split(image_info['path']) final = os.path.join(nuevo, filename) mask = skimage.io.imread(final) mask[mask < 150] = 0 mask[mask > 150] = 255 contours = measure.find_contours(mask, 0.6) lista = [] #TOTALMENTE PRESCINDBLE for n, contour in enumerate(contours): if (contour.shape[0] > 0): centro = np.mean(contour, axis=0) if (mask[int(centro[0]), int(centro[1])] != 0): if (False == np.array_equal(contour[0, :], contour[-1, :])): w = ((contour[0, :] + contour[-1, :]) / 2).astype(int) if (mask[w[0], w[1]] != 0): if ((contour[0, 0] == contour[-1, 0] or contour[0, 1] == contour[-1, 1])): lista.append(contour) else: if (len(contour) > 30): if (mask[w[0], w[1] - 1] == 255 and mask[w[0] + 1, w[1]] == 255 and mask[w[0] - 1, w[1]] == 255 and 255 == mask[w[0], w[1] + 1]): lista.append(contour) else: lista.append(contour) if (len(lista) == 0): return np.empty([mask.shape[0], mask.shape[1], 1]), np.zeros([1], dtype=np.int32) lista3 = np.empty([mask.shape[0], mask.shape[1], len(lista)]) for i in range(len(lista)): if (False == np.array_equal(lista[i][0, :], lista[i][-1, :])): #centro=lista[i].sum(axis=0)/lista[i].shape[0] centro = (lista[i][0, :] + lista[i][-1, :]) / 2 #rad=(min(np.sqrt(np.square(lista[i]-centro).sum(axis=1)))+max(np.sqrt(np.square(lista[i]-centro).sum(axis=1))))/2 rad = max(np.sqrt(np.square(lista[i] - centro).sum(axis=1))) lista3[:, :, i] = create_circular_mask(mask.shape[0], mask.shape[1], center=[centro[1], centro[0]], radius=rad) * mask else: r_mask = np.zeros_like(mask, dtype='bool') r_mask[np.round(lista[i][:, 0]).astype('int'), np.round(lista[i][:, 1]).astype('int')] = 1 r_mask = ndimage.binary_fill_holes(r_mask) lista3[:, :, i] = r_mask * mask lista3[np.isnan(lista3)] = 0 lista3[lista3 < 150] = 0 lista3[lista3 > 150] = 1 lista4 = np.sum(lista3, axis=2) for i in range(0, lista3.shape[-1]): c = measure.find_contours(lista3[:, :, i], 0.5) if (len(c) > 1): lista3[:, :i] = lista3[:, :, i][lista4 == 2] = 0 return lista3, np.ones([lista3.shape[-1]], dtype=np.int32)
def generate_datasets(volume_size=(512, 512, 512), n_fibers=50, radius_lim=(4, 10), length_lim=(0.2, 0.8), gap_lim=(3, 10), max_fails=100, median_rad=3, intersect=False, output_dir=None, params=None): """Simulates speficied configurations of fibers and stores in a npy file. Simulates a number of fiber configurations speficied in `params` with `n_fibers` of the radii and lengths in ranges `radius_lim` and `length_lim`, separated with gaps in a range of `gap_lim`. The simulation process stops if the number of attempts to generate a fiber exceeds `max_fails`. Parameters ---------- volume_size : tuple Indicates the size of the volume. n_fibers : integer Indicates the number of fibers to be generated. radius_lim : tuple Indicates the range of radii for fibers to be generated. length_lim : tuple Indicates the range of lengths for fibers to be generated. gap_lim : tuple Indicates the range of gaps separating the fibers from each other. max_fails : integer Indicates the maximum number of failures during the simulation process. median_rad : integer Indicates the radius of median filter to fill holes occured due to rounding of coordinates of the generated fibers. intersect : boolean Specifies if generated fibers can intersect. output_dir : str Indicates the path to the output folder where the data will be stored. params : dict Indicates the configurations of orientation of fibers to be generated. Returns ------- out : dict The dictionary of generated datasets of specified configurations. """ if params is None: params = { 'aligned': { 'lat_rng': (15, 15), 'azth_rng': (27, 27) }, 'medium': { 'lat_rng': (0, 45), 'azth_rng': (-45, 45) }, 'disordered': { 'lat_rng': (0, 90), 'azth_rng': (-89, 90) } } out = {} for name, config in params.items(): data, lat_data, azth_data, diameter_data, n_gen_fibers, elapsed_time = \ simulate_fibers(volume_size, lat_lim=tuple([np.deg2rad(v) for v in config['lat_rng']]), azth_lim=tuple([np.deg2rad(v) for v in config['azth_rng']]), radius_lim=radius_lim, n_fibers=n_fibers, max_fails=max_fails, gap_lim=gap_lim, length_lim=length_lim, intersect=intersect) data_8bit = data.astype(np.uint8) data_8bit = ndi.binary_fill_holes(data_8bit) data_8bit = ndi.median_filter(data_8bit, footprint=morphology.ball(median_rad)) lat_data = ndi.median_filter(lat_data, footprint=morphology.ball(median_rad)) azth_data = ndi.median_filter(azth_data, footprint=morphology.ball(median_rad)) diameter_data = ndi.median_filter( diameter_data, footprint=morphology.ball(median_rad)) out[name] = { 'data': data_8bit, 'lat': lat_data, 'azth': azth_data, 'diameter': diameter_data, 'skeleton': morphology.skeletonize_3d(data_8bit).astype(np.float32), 'props': { 'n_gen_fibers': n_gen_fibers, 'time': elapsed_time, 'intersect': intersect } } if output_dir is not None and not os.path.exists(output_dir): os.makedirs(output_dir) np.save( os.path.join( output_dir, 'dataset_fibers_n{}_r{}_{}_g{}_{}_mr{}_i{}.npy'.format( n_fibers, radius_lim[0], radius_lim[-1], gap_lim[0], gap_lim[-1], median_rad, int(intersect))), out) return out
from skimage.filters import rank # Loading Images di1 = 'C:\\Projects\\Images\\diestrus1.tif' di2 = 'C:\\Projects\\Images\\diestrus2.tif' es1 = 'C:\\Projects\\Images\\estrus.tif' es2 = 'C:\\Projects\\Images\\estrus2tif' met1 = 'C:\\Projects\\Images\\metestrus1.tif' met2 = 'C:\\Projects\\Images\\metestrus2.tif' pro1 = 'C:\\Projects\\Images\\proestrus1.tif' pro2 = 'C:\\Projects\\Images\\proestrus2.tif' ex1 = 'C:\\Projects\\Images\\example_cells_1.tif' ex2 = 'C:\\Projects\\Images\\example_cells_2.tif' img = io.imread(di1) # Gaussian Smoothing sigma = 2 smooth = img[:, :, 2] smooth_filter = ndi.filters.gaussian_filter(smooth, sigma) plt.imshow(smooth_filter) plt.show(smooth_filter.any()) # Adaptive background struct = ( (np.mgrid[:31, :31][0] - 15) ** 2 + (np.mgrid[:31, :31][1] - 15) ** 2 ) <= 15 ** 2 bg = rank.mean(smooth_filter, selem=struct) # Threshold threshold = smooth_filter >= bg threshold = ndi.binary_fill_holes(np.logical_not(threshold)) plt.imshow(threshold, interpolation='none', cmap='gray') plt.show(threshold.any())
def extractFeatures(self, img): # threshold gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) thresh = threshold_otsu(gray) binary = gray >= thresh bw_img1 = morphology.closing(binary, morphology.square(3)) # pad to ensure contour is continuous bw_img = np.pad(bw_img1, 1, 'constant') # plt.imshow(bw_img1) # plt.title('Black and White') # plt.savefig(self.fnm+"_BW.png",bbox_inches='tight') # plt.close() # compute intensity histogram features gray2 = np.pad(gray, 1, 'constant') pixVals = gray2[bw_img > 0] maxPixel = np.max(pixVals) minPixel = np.min(pixVals) if (maxPixel == 0): maxPixel = 1 # normalize histogram pixVals = (np.float32(pixVals) - minPixel) / np.max(pixVals) histVals = exposure.histogram(pixVals, nbins=64) # discrete cosine transform of normalized histogram of pixel values allHistFeatures = fftpack.dct(np.float32(histVals[0])) histFeatures = allHistFeatures[1:15] # Find contours contours = measure.find_contours(bw_img, 0.5) # Select largest contour maxLength = -1 maxContour = [] for cc in contours: if (len(cc) > maxLength): maxLength = len(cc) maxContour = cc # fig, ax = plt.subplots() # #ax.imshow(r, interpolation='nearest', cmap=plt.cm.gray) # for n, contour in enumerate(contours): # ax.plot(contour[:, 1], contour[:, 0], linewidth=2) # ax.axis('image') # plt.title("Contours") # plt.savefig(self.fnm+"_C.png",bbox_inches='tight') # plt.close() # Represent contour in fourier space. Make scale invarient by # dividing by DC term. Can make rotation invariant by subtracting # phase of first term # Interpolate to 4096 point contour interpX = interpolate.interp1d(range(0, maxLength), maxContour[:, 0]) interpY = interpolate.interp1d(range(0, maxLength), maxContour[:, 1]) newS = np.linspace(0, maxLength - 1, 4096) cX = interpX(newS) cY = interpY(newS) cPath = cX + 1j * cY FdAll = np.fft.fft(cPath) FdSave = np.log(np.absolute(FdAll[2:18]) / np.absolute(FdAll[1])) # Simplify the boundary cen = np.fft.fftshift(FdAll) # take first 10% of fourier coefficents cen2 = np.hstack([np.zeros(1843), cen[1843:2253], np.zeros(1843)]) # Back project to simplified boundary back = np.fft.ifft(np.fft.ifftshift(cen2)) xx = np.round(back.real) yy = np.round(back.imag) m = bw_img.shape[0] n = bw_img.shape[1] xx = xx.astype(np.int) yy = yy.astype(np.int) simp = np.zeros([m, n]) simp[xx, yy] = 1 # fig, ax = plt.subplots() # ax.imshow(img) # ax.plot(maxContour[:, 1], maxContour[:, 0], linewidth=2) # ax.axis('image') # plt.title("Max Contour") # plt.savefig(self.fnm+"_MC.png",bbox_inches='tight') # plt.close() # Get the appropriate FFT padded out to 300 x 300 freq_simp = fftpack.fftshift(fftpack.fft2(simp, [300, 300])) # 48 rings, 50 wedges selected from 0 to pi ann = AnnulusProcessing(freq_simp, 48, 50) # add number of wedges, etc to init rings = ann.make_annular_mean() wedges = ann.make_wedge() # Fill the simplified boundary fill = ndimage.binary_fill_holes(simp).astype(int) masked = fill * np.pad(gray, 1, 'constant') # plt.imshow(masked) # plt.title("Masked") # plt.savefig(self.fnm+"_M.png",bbox_inches='tight') # plt.close() # Gray level coocurrence matrix P = greycomatrix(masked, distances=self.dist, angles=self.ang, normed=True) grey_mat = np.zeros([24, 2]) flag = 0 for name in self.grey_props: stat = greycoprops(P, name) grey_mat[flag:flag + 6, 0] = np.mean(stat, 1) grey_mat[flag:flag + 6, 1] = np.std(stat, 1) flag += 6 # Texture descripters prob = np.histogram(masked, 256) # assume gray scale with 256 levels prob = np.asarray(prob[0]) prob[0] = 0 # don't count black pixels prob = prob / prob.sum() vec = np.arange(0, len(prob)) / (len(prob) - 1) ind = np.nonzero(prob)[0] # mean grey value mu = np.sum(vec[ind] * prob[ind]) # variance var = np.sum((((vec[ind] - mu)**2) * prob[ind])) # standard deviation std = np.sqrt(var) # contrast cont = 1 - 1 / (1 + var) # 3rd moment thir = np.sum(((vec[ind] - mu)**3) * prob[ind]) # Uniformity uni = np.sum(prob[0]**2) # Entropy ent = -np.sum(prob[ind] * np.log2(prob[ind])) # Compute morphological descriptors label_img = measure.label(bw_img, neighbors=8, background=0) features = measure.regionprops(label_img + 1) maxArea = 0 maxAreaInd = 0 for f in range(0, len(features)): if features[f].area > maxArea: maxArea = features[f].area maxAreaInd = f # Compute translation, scal and rotation invariant features ii = maxAreaInd aspect = features[ii].minor_axis_length / features[ii].major_axis_length area1 = features[ii].area / features[ii].convex_area area2 = features[ii].area / (features[ii].bbox[3] * features[ii].bbox[2]) area3 = features[ii].area / (features[ii].perimeter * features[ii].perimeter) area4 = area2 / area1 area5 = area3 / area1 per = features[ii].perimeter simp_area = features[ii].area pa = per / simp_area fillArea = features[ii].filled_area ecc = features[ii].eccentricity esd = features[ii].equivalent_diameter en = features[ii].euler_number sol = features[ii].solidity momC = features[ii].moments_central ext = features[ii].extent # copeTestImg = cv2.imread("copeTest.png") # copegray = cv2.cvtColor(copeTestImg,cv2.COLOR_BGR2GRAY) # copethresh = threshold_otsu(copegray) # copebinary = copegray >= copethresh # cope_img1 = morphology.closing(copebinary,morphology.square(3)) # pad to ensure contour is continuous # cope_img = np.pad(cope_img1, 1, 'constant') # size=bw_img.shape # copeTestImgRes = transform.resize(cope_img,size, mode='nearest') # intarray=np.around(copeTestImgRes) # intarray = intarray.astype(dtype="uint8") # copeTestImgRot = transform.rotate(cope_img,features[ii].orientation).astype(dtype="uint8") # copeTestImgBoth = transform.rotate(copeTestImgRes, features[ii].orientation).astype(dtype="uint8") # SS_res = measure.structural_similarity(bw_img,intarray) # SS_both = measure.structural_similarity(bw_img,copeTestImgBoth) # MT = feature.match_template(bw_img,copeTestImgBoth) # maxMT = np.amax(MT) #likelyT=measure.structural_similarity(bw_img,copeTestImg) X = np.zeros(212) X[0:16] = FdSave X[17] = aspect X[18] = area1 X[19] = area2 X[20] = area3 X[21] = area4 X[22] = area5 X[23] = fillArea X[24] = ecc X[25] = esd X[26] = en X[27] = sol X[28:35] = np.log(features[ii].moments_hu) X[36:50] = histFeatures X[50:98] = rings # only use first 10? X[98:148] = wedges # sort these X[148:172] = grey_mat[:, 0] X[172:196] = grey_mat[:, 1] X[196] = mu X[197] = std X[198] = cont X[199] = thir X[200] = uni X[201] = ent X[202] = per X[203] = simp_area X[204] = pa X[205] = ext # X[206] = np.log(features[ii].inertia_tensor_eigvals[0]) # X[207] = np.log(features[ii].inertia_tensor_eigvals[1]) # X[208] = features[ii].orientation # X[209] = maxMT # X[210] = SS_res # X[211] = SS_both return X
def run_loop(bag_path, seg_model, seg_opts, save_images=False): # Create pipeline pipeline = rs.pipeline() # Create a config object config = rs.config() # Tell config that we will use a recorded device from filem to be used by the pipeline through playback. rs.config.enable_device_from_file(config, args.input) # Start streaming from file Pipe = pipeline.start(config) # Getting the depth sensor's depth scale (see rs-align example for explanation) depth_sensor = Pipe.get_device().first_depth_sensor() depth_scale = depth_sensor.get_depth_scale() print("Depth Scale is: ", depth_scale) # Create opencv window to render image in cv2.namedWindow("Full Stream", cv2.WINDOW_NORMAL) # Create colorizer object colorizer = rs.colorizer() idx = 0 # initial frame delay idx_limit = 30 pre_seg_mask_sum = None # previous frame path segmentation area # Streaming loop try: while True: idx += 1 # Get frameset of depth frames = pipeline.wait_for_frames() # ignore first idx frames if idx < idx_limit: continue else: pass align = rs.align(rs.stream.color) frames = align.process(frames) # Get color frame color_frame = frames.get_color_frame() # Get depth frame depth_frame = frames.get_depth_frame() # Get intrinsics and extrinsics if idx == idx_limit: camera_intrinsics(color_frame, depth_frame, Pipe) color_image = np.asanyarray(color_frame.get_data()) ### Add Segmentation part here ### pred = test(color_image, seg_model, seg_opts) # pavement, floor, road, earth/ground, field, path, dirt/track seg_mask = (pred == 11) | (pred == 3) | (pred == 6) | ( pred == 13) | (pred == 29) | (pred == 52) | ( pred == 91) #.astype(np.uint8) if idx == idx_limit: # 1st frame detection needs to be robust pre_seg_mask_sum = np.sum(seg_mask) # checking for bad detection new_seg_sum = np.sum(seg_mask) diff = abs(new_seg_sum - pre_seg_mask_sum) # if diff > pre_seg_mask_sum/15: # smoothening between segmentation outputs - seems like a bad idea since the model inputs are not connected between timesteps # seg_mask = np.ones_like(pred).astype(np.uint8) # need to add depth (5mt) criterea for calculation for robustness # del new_seg_sum # else: pre_seg_mask_sum = new_seg_sum ### mask Hole filling seg_mask = nd.binary_fill_holes(seg_mask).astype(int) seg_mask = seg_mask.astype(np.uint8) ##### seg_mask_3d = np.dstack((seg_mask, seg_mask, seg_mask)) pred_color = colorEncode( pred, loadmat(os.path.join(model_folder, 'color150.mat'))['colors']) ################################## depth_frame = depth_filter(depth_frame) depth_array = np.asarray(depth_frame.get_data()) # Colorize depth frame to jet colormap depth_color_frame = colorizer.colorize(depth_frame) # Convert depth_frame to numpy array to render image in opencv depth_color_image = np.asanyarray(depth_color_frame.get_data()) ############ Plane Detection ## need to add smoothening between frames - by plane weights' variance? try: ### need to add multithreading here (and maybe other methods?) planes_mask_binary = plane_detection(color_image*seg_mask_3d, depth_array*seg_mask,\ loop=5) except TypeError as e: try: print("plane mask 1st error") planes_mask, planes_normal, list_plane_params = test_PlaneDetector_send( img_color=color_image * seg_mask_3d, img_depth=depth_array * seg_mask) except TypeError as e: print("plane mask not detected-skipping frame") continue ## removed this part planes_mask = np.ones_like(depth_array).astype(np.uint8) planes_mask = np.dstack( (planes_mask, planes_mask, planes_mask)) ############################################## ## Hole filling for plane_mask (plane mask isn't binary - fixed that!) planes_mask_binary = nd.binary_fill_holes(planes_mask_binary) planes_mask_binary = planes_mask_binary.astype(np.uint8) # Clean plane mask object detection by seg_mask planes_mask_binary *= seg_mask planes_mask_binary_3d = np.dstack( (planes_mask_binary, planes_mask_binary, planes_mask_binary)) edges = planes_mask_binary - nd.morphology.binary_dilation( planes_mask_binary) # edges calculation edges = cv2.cvtColor(edges, cv2.COLOR_GRAY2BGR) ############################################# # for cv2 output pred_color = cv2.cvtColor(pred_color, cv2.COLOR_RGB2BGR) color_image = cv2.cvtColor(color_image, cv2.COLOR_RGB2BGR) # if save_images == True: # cv2.imwrite("data_/color/frame%d.png" % idx, color_image) # save frame as JPEG file # cv2.imwrite("data_/depth/frame%d.png" % idx, depth_array) # save frame as JPEG file # cv2.imwrite("data_/color_depth/frame%d.png" % idx, depth_color_image) # save frame as JPEG file # cv2.imwrite("data_/thresholded_color/frame%d.png" % idx, thresholded_color_image) # save frame as JPEG file # # cv2.imwrite("data_/thresholded_depth/frame%d.png" % idx, thresholded_depth_image) # save frame as JPEG file # # Blending images alpha = 0.2 beta = (1.0 - alpha) dst = cv2.addWeighted(color_image, alpha, pred_color, beta, 0.0) # kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(11,11)) # res = cv2.morphologyEx(planes_mask,cv2.MORPH_OPEN,kernel) dst2 = cv2.addWeighted(depth_color_image, alpha, color_image, beta, 0.0) ## for displaying seg_mask seg_mask = (np.array(seg_mask) * 255).astype(np.uint8) seg_mask = cv2.cvtColor(seg_mask, cv2.COLOR_GRAY2BGR) ################################## ### delete later final_output = color_image * planes_mask_binary_3d mask = (final_output[:, :, 0] == 0) & ( final_output[:, :, 1] == 0) & (final_output[:, :, 2] == 0) final_output[:, :, :3][mask] = [255, 255, 255] ###### # if np.sum(planes_mask) == depth_array.shape[0]*depth_array.shape[1]: # image_set1 = np.vstack((dst, color_image)) # else: image_set1 = np.vstack((color_image, depth_color_image)) # image_set2 = np.vstack((planes_mask_binary_3d*255, seg_mask)) image_set2 = np.vstack((dst, final_output)) # image_set2 = np.vstack((edges, final_output)) combined_images = np.concatenate((image_set1, image_set2), axis=1) if save_images == True: cv2.imwrite("./meeting_example/frame%d.png" % idx, combined_images) try: cv2.imshow('Full Stream', combined_images) except TypeError as e: print(idx, e) key = cv2.waitKey(1) # if pressed escape exit program if key == 27: cv2.destroyAllWindows() break finally: pipeline.stop() cv2.destroyAllWindows() # if save_images == True: # pkl.dump( threshold_mask, open( "data_/depth_threshold.pkl", "wb" ) ) # print("Mask pickle saved") return
fs_area.append(fsarea) # Area densities inside and outside the focus in_area_density.append(incount * np.mean(insize) / fsarea) out_area_density.append(outcount * np.mean(outsize) / (1. - fsarea)) # Point densities inside and outside the focus in_point_density.append(incount / fsarea) out_point_density.append(outcount / (1. - fsarea)) print "Densities calculated." # Variance and CoV of outside the focus mask = np.zeros_like(clean) for c in cent: mask[int(np.round(c[0])), int(np.round(c[1]))] = 1 mask = ndimage.binary_fill_holes(ndimage.maximum_filter(mask, 35)) areadensity = filter.gaussian_filter(clean, 51) var_area_density.append(np.var(areadensity[mask == 0])) cov_area_density.append( np.std(areadensity[mask == 0] / np.mean(areadensity[mask == 0]))) pointdensity = np.zeros_like(clean) for n in nuclei: pointdensity[int(np.round(n.centroid[0])), int(np.round(n.centroid[1]))] = 1 pointdensity = filter.gaussian_filter(pointdensity, 51) var_point_density.append(np.var(pointdensity[mask == 0])) cov_point_density.append( np.std(pointdensity[mask == 0] / np.mean(pointdensity[mask == 0])))
from scipy.ndimage import gaussian_filter gaus = gaussian_filter(test, 4) ut.imshow(gaus) from skimage.feature import canny edges = canny(gaus) type(edges) plt.imshow(edges) from scipy import ndimage as ndi fill = ndi.binary_fill_holes(edges) plt.imshow(fill) from skimage.filters import sobel elevation_map = sobel(test) ut.imshow(elevation_map) markers = np.zeros_like(test) markers[test < 0.1] = 1 markers[test > 0.9] = 2 plt.imshow(markers) from skimage.morphology import watershed segmentation = watershed(elevation_map, markers)
def lungmask_pro(img, morph=True): # to avoid many tears img = img.copy() # set intensity range to standard (corners have problems) -> doesn't really matter, robust method, but looks better img[img <= -1024] = -1024 img[img >= 1024] = 1024 # also this, because of circular region artifacts (actually also for the one above) # scale image to be in the range [0,255] -> because method robust enough to handle it -> smarter thresholds img = np.uint8(maxminscale(img)) # keep scaled original image for masking later img_orig = img.copy() # blur img to easier being able to segment the lung using kmeans img = medianBlur(img, 5) # get dimensions of image row_size, col_size = img.shape # specify window for k-means to work on, such that you get the lung, and not the rest middle = img[int(col_size / 5):int(col_size / 5 * 4), int(row_size / 5):int(row_size / 5 * 4)] # apply otsu's method to threshold image th = threshold_otsu(middle) thresh_img = np.where(img < th, 1.0, 0.0) # label each object from the filtering above and only get the lung including juxta-vascular nodules labels = label( thresh_img) # Different labels are displayed in different colors regions = regionprops(labels) good_labels = [] for prop in regions: B = prop.bbox if B[2] - B[0] < row_size / 10 * 9 and B[3] - B[ 1] < col_size / 10 * 9 and B[0] > row_size / 10 and B[ 2] < col_size / 10 * 9: # better window! good_labels.append(prop.label) mask = np.ndarray([row_size, col_size], dtype=np.int8) mask[:] = 0 # gets objects of interest from criteria defined and used above for N in good_labels: mask = mask + np.where(labels == N, 1, 0) ## fill regions surrounded by lung regions -> final ROI # to fill holes -> without filling unwanted larger region in the middle res = binary_fill_holes(mask) # need to filter out the main airways easily seperated from lung, because else they will affect the resulting algorithm res2 = remove_small_objects(label(res).astype(bool), min_size=800) res2[res2 > 0] = 1 # separate each object in image (i.e. each lung part), and do morphology to include juxta-pleural nodules lungmask = np.zeros(res2.shape) labels = label(res2) for i in range(1, len(np.unique(labels))): tmp = np.zeros(labels.shape) tmp[labels == i] = 1 # whether or not to apply morphology to fix lung boundary -> to include juxta-pleural nodules (nodules attached to lung boundary) if (morph == True): mask = dilate(np.uint8(tmp), disk(17)) # 17 : radius of 2D-disk mask = remove_small_objects(label(bitwise_not( maxminscale(mask))).astype(bool), min_size=500).astype(int) mask[mask != 0] = -1 mask = np.add(mask, np.ones(mask.shape)) filled_tmp = erode(np.uint8(mask), disk(19)) else: mask = remove_small_objects(label(bitwise_not( maxminscale(tmp))).astype(bool), min_size=500).astype(int) mask[mask != 0] = -1 filled_tmp = np.add(mask, np.ones(mask.shape)) lungmask += filled_tmp return lungmask
def fillHoles(image): #0-1 rgb return ndi.binary_fill_holes(image)
def run(self, ips, imgs, para=None): imgs[:] = ndimg.binary_fill_holes(imgs) imgs *= 255
def recognize(out_file, most_common, coord_imgs, imgs_with_staff, imgs_spacing, imgs_rows): black_names = [ '4', '8', '8_b_n', '8_b_r', '16', '16_b_n', '16_b_r', '32', '32_b_n', '32_b_r', 'a_4', 'a_8', 'a_16', 'a_32', 'chord' ] ring_names = ['2', 'a_2'] whole_names = ['1', 'a_1'] disk_size = most_common / 4 if len(coord_imgs) > 1: out_file.write("{\n") for i, img in enumerate(coord_imgs): res = [] prev = '' time_name = '' primitives, prim_with_staff, boundary = get_connected_components( img, imgs_with_staff[i]) for j, prim in enumerate(primitives): prim = binary_opening( prim, square(np.abs(most_common - imgs_spacing[i]))) saved_img = (255 * (1 - prim)).astype(np.uint8) labels = predict(saved_img) octave = None label = labels[0] if label in black_names: test_img = np.copy(prim_with_staff[j]) test_img = binary_dilation(test_img, disk(disk_size)) comps, comp_w_staff, bounds = get_connected_components( test_img, prim_with_staff[j]) comps, comp_w_staff, bounds = filter_beams( comps, comp_w_staff, bounds) bounds = [np.array(bound) + disk_size - 2 for bound in bounds] if len(bounds) > 1 and label not in [ '8_b_n', '8_b_r', '16_b_n', '16_b_r', '32_b_n', '32_b_r' ]: l_res = [] bounds = sorted(bounds, key=lambda b: -b[2]) for k in range(len(bounds)): idx, p = estim(boundary[j][0] + bounds[k][2], i, imgs_spacing, imgs_rows) l_res.append(f'{label_map[idx][p]}/4') if k + 1 < len(bounds) and ( bounds[k][2] - bounds[k + 1][2]) > 1.5 * imgs_spacing[i]: idx, p = estim( boundary[j][0] + bounds[k][2] - imgs_spacing[i] / 2, i, imgs_spacing, imgs_rows) l_res.append(f'{label_map[idx][p]}/4') res.append(sorted(l_res)) else: for bbox in bounds: c = bbox[2] + boundary[j][0] line_idx, p = estim(int(c), i, imgs_spacing, imgs_rows) l = label_map[line_idx][p] res.append(get_note_name(prev, l, label)) elif label in ring_names: head_img = 1 - binary_fill_holes(1 - prim) head_img = binary_closing(head_img, disk(disk_size)) comps, comp_w_staff, bounds = get_connected_components( head_img, prim_with_staff[j]) for bbox in bounds: c = bbox[2] + boundary[j][0] line_idx, p = estim(int(c), i, imgs_spacing, imgs_rows) l = label_map[line_idx][p] res.append(get_note_name(prev, l, label)) elif label in whole_names: c = boundary[j][2] line_idx, p = estim(int(c), i, imgs_spacing, imgs_rows) l = label_map[line_idx][p] res.append(get_note_name(prev, l, label)) elif label in [ 'bar', 'bar_b', 'clef', 'clef_b', 'natural', 'natural_b', 't24', 't24_b', 't44', 't44_b' ] or label in []: continue elif label in ['#', '#_b']: if prim.shape[0] == prim.shape[1]: prev = '##' else: prev = '#' elif label in ['cross']: prev = '##' elif label in ['flat', 'flat_b']: if prim.shape[1] >= 0.5 * prim.shape[0]: prev = '&&' else: prev = '&' elif label in ['dot', 'dot_b', 'p']: if len(res) == 0 or (len(res) > 0 and res[-1] in [ 'flat', 'flat_b', 'cross', '#', '#_b', 't24', 't24_b', 't44', 't44_b' ]): continue res[-1] += '.' elif label in ['t2', 't4']: time_name += label[1] elif label == 'chord': img = thin(1 - prim.copy(), max_iter=20) head_img = binary_closing(1 - img, disk(disk_size)) if label not in ['flat', 'flat_b', 'cross', '#', '#_b']: prev = '' if len(time_name) == 2: out_file.write("[ " + "\\" + "meter<\"" + str(time_name[0]) + "/" + str(time_name[1]) + "\">" + ' '.join([ str(elem) if type(elem) != list else get_chord_notation(elem) for elem in res ]) + "]\n") elif len(time_name) == 1: out_file.write("[ " + "\\" + "meter<\"" + '4' + "/" + '2' + "\">" + ' '.join([ str(elem) if type(elem) != list else get_chord_notation(elem) for elem in res ]) + "]\n") else: out_file.write("[ " + ' '.join([ str(elem) if type(elem) != list else get_chord_notation(elem) for elem in res ]) + "]\n") if len(coord_imgs) > 1: out_file.write("}") print("###########################", res, "##########################")
def filled_image(self): structure = np.ones((3, ) * self._ndim) return ndi.binary_fill_holes(self.image, structure)
mark_boundaries) image = data.coins() ############################################################################### # First, we generate the true segmentation. For this simple image, we know # exact functions and parameters that will produce a perfect segmentation. In # a real scenario, typically you would generate ground truth by manual # annotation or "painting" of a segmentation. elevation_map = sobel(image) markers = np.zeros_like(image) markers[image < 30] = 1 markers[image > 150] = 2 im_true = watershed(elevation_map, markers) im_true = ndi.label(ndi.binary_fill_holes(im_true - 1))[0] ############################################################################### # Next, we create three different segmentations with different characteristics. # The first one uses :func:`skimage.segmentation.watershed` with # *compactness*, which is a useful initial segmentation but too fine as a # final result. We will see how this causes the oversegmentation metrics to # shoot up. edges = sobel(image) im_test1 = watershed(edges, markers=468, compactness=0.001) ############################################################################### # The next approach uses the Canny edge filter, :func:`skimage.filters.canny`. # This is a very good edge finder, and gives balanced results.
def seeds(args): """ %prog seeds [pngfile|jpgfile] Extract seed metrics from [pngfile|jpgfile]. Use --rows and --cols to crop image. """ p = OptionParser(seeds.__doc__) p.set_outfile() opts, args, iopts = add_seeds_options(p, args) if len(args) != 1: sys.exit(not p.print_help()) pngfile, = args pf = opts.prefix or op.basename(pngfile).rsplit(".", 1)[0] sigma, kernel = opts.sigma, opts.kernel rows, cols = opts.rows, opts.cols labelrows, labelcols = opts.labelrows, opts.labelcols ff = opts.filter calib = opts.calibrate outdir = opts.outdir if outdir != '.': mkdir(outdir) if calib: calib = json.load(must_open(calib)) pixel_cm_ratio, tr = calib["PixelCMratio"], calib["RGBtransform"] tr = np.array(tr) pngfile = convert_background(pngfile) resizefile, mainfile, labelfile, exif = \ convert_image(pngfile, pf, outdir=outdir, rotate=opts.rotate, rows=rows, cols=cols, labelrows=labelrows, labelcols=labelcols) oimg = load_image(resizefile) img = load_image(mainfile) fig, (ax1, ax2, ax3, ax4) = plt.subplots(ncols=4, nrows=1, figsize=(iopts.w, iopts.h)) # Edge detection img_gray = rgb2gray(img) logging.debug("Running {0} edge detection ...".format(ff)) if ff == "canny": edges = canny(img_gray, sigma=opts.sigma) elif ff == "roberts": edges = roberts(img_gray) elif ff == "sobel": edges = sobel(img_gray) edges = clear_border(edges, buffer_size=opts.border) selem = disk(kernel) closed = closing(edges, selem) if kernel else edges filled = binary_fill_holes(closed) # Watershed algorithm if opts.watershed: distance = distance_transform_edt(filled) local_maxi = peak_local_max(distance, threshold_rel=.05, indices=False) coordinates = peak_local_max(distance, threshold_rel=.05) markers, nmarkers = label(local_maxi, return_num=True) logging.debug("Identified {0} watershed markers".format(nmarkers)) labels = watershed(closed, markers, mask=filled) else: labels = label(filled) # Object size filtering w, h = img_gray.shape canvas_size = w * h min_size = int(round(canvas_size * opts.minsize / 100)) max_size = int(round(canvas_size * opts.maxsize / 100)) logging.debug("Find objects with pixels between {0} ({1}%) and {2} ({3}%)"\ .format(min_size, opts.minsize, max_size, opts.maxsize)) # Plotting ax1.set_title('Original picture') ax1.imshow(oimg) params = "{0}, $\sigma$={1}, $k$={2}".format(ff, sigma, kernel) if opts.watershed: params += ", watershed" ax2.set_title('Edge detection\n({0})'.format(params)) closed = gray2rgb(closed) ax2_img = labels if opts.edges: ax2_img = closed elif opts.watershed: ax2.plot(coordinates[:, 1], coordinates[:, 0], 'g.') ax2.imshow(ax2_img, cmap=iopts.cmap) ax3.set_title('Object detection') ax3.imshow(img) filename = op.basename(pngfile) if labelfile: accession = extract_label(labelfile) else: accession = pf # Calculate region properties rp = regionprops(labels) rp = [x for x in rp if min_size <= x.area <= max_size] nb_labels = len(rp) logging.debug("A total of {0} objects identified.".format(nb_labels)) objects = [] for i, props in enumerate(rp): i += 1 if i > opts.count: break y0, x0 = props.centroid orientation = props.orientation major, minor = props.major_axis_length, props.minor_axis_length major_dx = cos(orientation) * major / 2 major_dy = sin(orientation) * major / 2 minor_dx = sin(orientation) * minor / 2 minor_dy = cos(orientation) * minor / 2 ax2.plot((x0 - major_dx, x0 + major_dx), (y0 + major_dy, y0 - major_dy), 'r-') ax2.plot((x0 - minor_dx, x0 + minor_dx), (y0 - minor_dy, y0 + minor_dy), 'r-') npixels = int(props.area) # Sample the center of the blob for color d = min(int(round(minor / 2 * .35)) + 1, 50) x0d, y0d = int(round(x0)), int(round(y0)) square = img[(y0d - d):(y0d + d), (x0d - d):(x0d + d)] pixels = [] for row in square: pixels.extend(row) logging.debug("Seed #{0}: {1} pixels ({2} sampled) - {3:.2f}%".\ format(i, npixels, len(pixels), 100. * npixels / canvas_size)) rgb = pixel_stats(pixels) objects.append(Seed(filename, accession, i, rgb, props, exif)) minr, minc, maxr, maxc = props.bbox rect = Rectangle((minc, minr), maxc - minc, maxr - minr, fill=False, ec='w', lw=1) ax3.add_patch(rect) mc, mr = (minc + maxc) / 2, (minr + maxr) / 2 ax3.text(mc, mr, "{0}".format(i), color='w', ha="center", va="center", size=6) for ax in (ax2, ax3): ax.set_xlim(0, h) ax.set_ylim(w, 0) # Output identified seed stats ax4.text(.1, .92, "File: {0}".format(latex(filename)), color='g') ax4.text(.1, .86, "Label: {0}".format(latex(accession)), color='m') yy = .8 fw = must_open(opts.outfile, "w") if not opts.noheader: print(Seed.header(calibrate=calib), file=fw) for o in objects: if calib: o.calibrate(pixel_cm_ratio, tr) print(o, file=fw) i = o.seedno if i > 7: continue ax4.text(.01, yy, str(i), va="center", bbox=dict(fc='none', ec='k')) ax4.text(.1, yy, o.pixeltag, va="center") yy -= .04 ax4.add_patch( Rectangle((.1, yy - .025), .12, .05, lw=0, fc=rgb_to_hex(o.rgb))) ax4.text(.27, yy, o.hashtag, va="center") yy -= .06 ax4.text(.1, yy, "(A total of {0} objects displayed)".format(nb_labels), color="darkslategray") normalize_axes(ax4) for ax in (ax1, ax2, ax3): xticklabels = [int(x) for x in ax.get_xticks()] yticklabels = [int(x) for x in ax.get_yticks()] ax.set_xticklabels(xticklabels, family='Helvetica', size=8) ax.set_yticklabels(yticklabels, family='Helvetica', size=8) image_name = op.join(outdir, pf + "." + iopts.format) savefig(image_name, dpi=iopts.dpi, iopts=iopts) return objects
def TestPreprocess(img, plot=False): if plot == True: f, plots = plt.subplots(2, 4) ''' Step 1: 以604(HU=400)为分界点二值化 ''' binary = img < 604 if plot == True: plt.subplot(2, 4, 1) plt.axis('off') plt.title(u"二值化", fontproperties=zhfont) plt.imshow(binary, cmap=plt.cm.bone) ''' Step 2: 移除与边界相连的部分 ''' cleared = clear_border(binary) if plot == True: plt.subplot(2, 4, 2) plt.axis('off') plt.title(u"移除边界", fontproperties=zhfont) plt.imshow(cleared, cmap=plt.cm.bone) ''' Step 3: 标记连通区域 ''' label_image = label(cleared) if plot == True: plt.subplot(2, 4, 3) plt.axis('off') plt.title(u"标记联通区域", fontproperties=zhfont) plt.imshow(label_image, cmap=plt.cm.bone) ''' Step 4: 只保留两个最大的连通区域 ''' areas = [r.area for r in regionprops(label_image)] areas.sort() if len(areas) > 2: for region in regionprops(label_image): if region.area < areas[-2]: for coordinates in region.coords: label_image[coordinates[0], coordinates[1]] = 0 binary = label_image > 0 if plot == True: plt.subplot(2, 4, 4) plt.axis('off') plt.title(u"保留最大的两个区域", fontproperties=zhfont) plt.imshow(binary, cmap=plt.cm.bone) ''' Step 5: 半径为2的腐蚀操作,分离附着于血管的肺结节 ''' selem = disk(2) binary = binary_erosion(binary, selem) if plot == True: plt.subplot(2, 4, 5) plt.axis('off') plt.title(u"腐蚀", fontproperties=zhfont) plt.imshow(binary, cmap=plt.cm.bone) ''' Step 6: 半径为10的闭操作,合并粘在肺壁上的结节 ''' selem = disk(10) binary = binary_closing(binary, selem) if plot == True: plt.subplot(2, 4, 6) plt.axis('off') plt.title(u"闭", fontproperties=zhfont) plt.imshow(binary, cmap=plt.cm.bone) ''' Step 7: 填充小洞 ''' edges = roberts(binary) #边缘检测,Roberts算子,也可以使用sobel算子 binary = ndi.binary_fill_holes(edges) #空洞填充 if plot == True: plt.subplot(2, 4, 7) plt.axis('off') plt.title(u"填充小洞", fontproperties=zhfont) plt.imshow(binary, cmap=plt.cm.bone) "此时binnary就是最终的掩码了" # ''' # 7.1 非肺部区域绿色,肺部区域蓝色 # ''' # # 拷贝一个binnary # ColorMask = np.zeros((binary.shape[0],binary.shape[1],3), np.uint8) # # for i in range(ColorMask.shape[0]): # for j in range(ColorMask.shape[1]): # if binary[i,j] == 0: # ColorMask[i,j]=(0,255,0) # if binary[i,j] == 1: # ColorMask[i, j] = (0, 0, 255) # # if plot == True: # plt.subplot(3, 4, 9) # plt.axis('off') # plt.title(u"上色", fontproperties=zhfont) # plt.imshow(ColorMask) # # ''' # 7.2 ROI描点,连接成封闭区域,填充 # ''' # if len(rois)>=1: # for roi in rois: # cv2.fillPoly(ColorMask, [roi], (255, 0, 0)) # # # cv2.polylines(ColorMask, [pts], True, (255, 0, 0), 2) # # cv2.fillPoly(ColorMask, [pts], (255, 0, 0)) # if plot == True: # plt.subplot(3, 4, 10) # plt.axis('off') # plt.title(u"ROI勾画", fontproperties=zhfont) # plt.imshow(ColorMask) ''' Step 8: 使用掩码提取原始图像中的肺区域 ''' get_high_vals = binary == 0 img[get_high_vals] = 0 if plot == True: plt.subplot(2, 4, 8) plt.axis('off') plt.title(u"使用掩码提取原始数据", fontproperties=zhfont) plt.imshow(img, cmap=plt.cm.bone) return img
#%% ### Watershed segmentation from skimage import morphology from scipy import ndimage as ndi #mask_combo = normalize(mask_combo) markers = np.zeros_like(mask_combo) markers[mask_combo < .12] = 1 #markers[mask_combo > .12] = 0 fill_markers = ndi.binary_fill_holes(markers) new_edges = 0.5*fill_markers + mask_combo fig, ax = plt.subplots(figsize=(8, 8)) ax.imshow(new_edges[0:1000, 0:1000], cmap = "viridis", interpolation='nearest') ax.set_title('markers') ax.axis('off') #segmentation = morphology.watershed(mask_combo, markers) #fig, ax = plt.subplots(figsize=(8, 8)) #ax.imshow(segmentation[3000:4000, 2000:3000], cmap=plt.cm.nipy_spectral, interpolation='nearest') #ax.set_title('segmentation') #ax.axis('off') #from rasterio.plot import show_hist #import skimage
def edge_segmentation(img, low_th=25): """ Detect edges to create a mask that indicates where the paintings are located """ sx, sy = np.shape(img)[:2] datatype = np.uint8 kernel = np.ones((15,15), dtype=np.uint8) img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) done = False while not done: edges = cv2.Canny(img, low_th, 80, None, 3) # Closing to ensure edges are continuous edges = cv2.dilate(edges, kernel, iterations=1) edges = cv2.erode(edges, kernel, iterations=1) # Filling kernel = np.ones((15,15), dtype=np.uint8) mask = (ndimage.binary_fill_holes(edges)).astype(np.float64) mask = cv2.erode(mask, kernel, iterations=1) mask = cv2.erode(mask, kernel, iterations=1) #mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, np.ones((1,int(mask.shape[1]*0.05)))) nb_components, output, stats, centroids = cv2.connectedComponentsWithStats(mask.astype(np.uint8), connectivity=8) sizes = stats[:, -1] top_two_conn_comp_idx = sizes.argsort() top_two_conn_comp_idx = top_two_conn_comp_idx[top_two_conn_comp_idx!=0] idxs_tt = ((np.arange(0, min(3, len(top_two_conn_comp_idx)))+1)*(-1))[::-1] top_two_conn_comp_idx = top_two_conn_comp_idx[idxs_tt][::-1] idxs = [idx for idx in top_two_conn_comp_idx] bc = np.zeros(output.shape) bc[output == idxs[0]] = 255 bc = create_convex_painting(mask, bc) #cv2.waitKey(0) #bc = refine_mask(img, bc, get_bbox(bc)) if len(idxs) > 1: sbc = np.zeros(output.shape) sbc[output == idxs[1]] = 255 sbc = create_convex_painting(mask, sbc) #if sbc.astype(np.uint8).sum() > 0: # sbc = refine_mask(img, sbc, get_bbox(sbc)) if len(idxs) > 2: tbc = np.zeros(output.shape) tbc[output == idxs[2]] = 255 tbc = create_convex_painting(mask, tbc) #if tbc.astype(np.uint8).sum() > 0: # tbc = refine_mask(img, tbc, get_bbox(tbc)) bboxes = [get_bbox(bc)] resulting_masks = bc splitted_resulting_masks = [bc] # Second painting if first one does not take most part + more or less a rectangular shape + no IoU if len(idxs) > 1: if not takes_most_part_image(bc) and regular_shape(sbc) and check_no_iou(bc, sbc): bbox_sbc = get_bbox(sbc) if ((bbox_sbc[2]-bbox_sbc[0])*(bbox_sbc[3]-bbox_sbc[1]))/(img.shape[0]*img.shape[1]) > 0.05: bboxes.append(bbox_sbc) resulting_masks = np.logical_or(resulting_masks==255, sbc==255).astype(np.uint8)*255 splitted_resulting_masks.append(sbc) # Third painting if len(idxs) > 2: if regular_shape(tbc) and check_no_iou(bc, tbc) and check_no_iou(sbc, tbc): bbox_tbc = get_bbox(tbc) if ((bbox_tbc[2]-bbox_tbc[0])*(bbox_tbc[3]-bbox_tbc[1]))/(img.shape[0]*img.shape[1]) > 0.05: bboxes.append(bbox_tbc) resulting_masks = np.logical_or(resulting_masks==255, tbc==255).astype(np.uint8)*255 splitted_resulting_masks.append(tbc) #cv2.imshow("bc", cv2.resize(bc,(512,512))) #cv2.waitKey(0) done = True if not rectangular_shape2(bc): done = False low_th = low_th - 4 if low_th < 0: done = True return resulting_masks, bboxes, splitted_resulting_masks
sigma_spatial=15, multichannel=False) buf = np.zeros((2 * width, 2 * width)) buf[:sub.shape[0], :sub.shape[1]] = sub thresh = threshold_otsu(sub) * 1.15 bin = sub > thresh # area[i] = np.sum(bin) labeled, n = ndimage.label(bin) thresh = threshold_otsu(sub) * 1.3 bin = sub > thresh # bin = convex_hull_image(bin) bin = ndimage.binary_fill_holes(bin) sub = buf sub = np.flipud(sub) p2, p98 = np.percentile(sub, (2, 100)) sub = exposure.rescale_intensity(sub, in_range=(p2, p98)) # labeled, n = ndimage.label(bin) distance = ndimage.distance_transform_edt(bin) distance = filters.gaussian_filter(distance, sigma=5) local_maxi = peak_local_max(distance, indices=False, footprint=np.ones((3, 3)), labels=bin) markers = measure.label(local_maxi) labeled = watershed(-distance, markers, mask=bin) # markers[~bin] = -1
def get_segmented_lungs_mask(im, i, plot=False): size = im.shape[1] if plot == True: f, plots = plt.subplots(8, 1, figsize=(5, 40)) ''' Step 1: Convert into a binary image. ''' binary = im < -320 if plot == True: plots[0].axis('off') plots[0].imshow(binary, cmap=plt.cm.bone) ''' Step 2: Remove the blobs connected to the border of the image. ''' cleared = clear_border(binary) temp_label = label(cleared) for region in regionprops(temp_label): if region.area < 50: # print region.label for coordinates in region.coords: temp_label[coordinates[0], coordinates[1]] = 0 cleared = temp_label > 0 cleared = ndi.binary_dilation(cleared, iterations=5) ################################################### if plot == True: plots[1].axis('off') plots[1].imshow(cleared, cmap=plt.cm.bone) ''' Step 3: Label the image. ''' label_image = label(cleared) if plot == True: plots[2].axis('off') plots[2].imshow(label_image, cmap=plt.cm.bone) ''' Step 4: Keep the labels with 2 largest areas. ''' for region in regionprops(label_image): if region.eccentricity > 0.99 \ or region.centroid[0] > 0.90 * size \ or region.centroid[0] < 0.12 * size \ or region.centroid[1] > 0.88 * size \ or region.centroid[1] < 0.10 * size \ or (region.centroid[1] > 0.46 * size and region.centroid[1] < 0.54 * size and region.centroid[ 0] > 0.75 * size) \ or (region.centroid[0] < 0.2 * size and region.centroid[1] < 0.2 * size) \ or (region.centroid[0] < 0.2 * size and region.centroid[1] > 0.8 * size) \ or (region.centroid[0] > 0.8 * size and region.centroid[1] < 0.2 * size) \ or (region.centroid[0] > 0.8 * size and region.centroid[1] > 0.8 * size): for coordinates in region.coords: label_image[coordinates[0], coordinates[1]] = 0 binary = label_image > 0 if plot == True: plots[3].axis('off') plots[3].imshow(binary, cmap=plt.cm.bone) ''' Step 5: Erosion operation with a disk of radius 2. This operation is seperate the lung nodules attached to the blood vessels. ''' selem = disk(2) binary = binary_erosion(binary, selem) if plot == True: plots[4].axis('off') plots[4].imshow(binary, cmap=plt.cm.bone) ''' Step 6: Closure operation with a disk of radius 10. This operation is to keep nodules attached to the lung wall. ''' selem = disk(10) binary = binary_closing(binary, selem) if plot == True: plots[5].axis('off') plots[5].imshow(binary, cmap=plt.cm.bone) ''' Step 7: Fill in the small holes inside the binary mask of lungs. ''' edges = roberts(binary) binary = ndi.binary_fill_holes(edges) if plot == True: plots[6].axis('off') plots[6].imshow(binary, cmap=plt.cm.bone) # print "step 7", time()-t1 return binary, i
from scipy import ndimage as ndi from skimage.feature import canny from skimage import morphology import numpy as np from skimage.segmentation import watershed from skimage.feature import peak_local_max data_array = cv2.imread("./CIRA/dehaze_example.tif", 1) b, g, r = cv2.split(data_array) # Sauvola binary_global = canny(r) fill_masks = ndi.binary_fill_holes(binary_global) cells_cleaned = morphology.remove_small_objects(fill_masks, 70) labeled_cells, num = ndi.label(cells_cleaned) print("Number of Cells detected: " + str(num)) # Now we want to separate the two objects in image # Generate the markers as local maxima of the distance to the background distance = ndi.distance_transform_edt(cells_cleaned) local_maxi = peak_local_max(distance, indices=False, footprint=np.ones((100, 100)), labels=labeled_cells) markers = ndi.label(local_maxi)[0] labels = watershed(-distance, markers, mask=cells_cleaned) fig, axes = plt.subplots(ncols=4, figsize=(9, 3), sharex=True, sharey=True)
import numpy as np import matplotlib.pyplot as plt from scipy import ndimage as ndi from skimage import io from skimage import feature filename = "r1240_39_satellite_image_spot5_2.5m_gambia_river_gambia_2006.jpg" image = io.imread(filename, as_grey=True) print(image.size) edges = feature.canny(image, sigma=3) fill_segment = ndi.binary_fill_holes(edges) fig, (ax1, ax2, ax3) = plt.subplots(nrows=1, ncols=3, sharex=True, sharey=True, figsize=(12, 8)) ax1.imshow(io.imread(filename)) ax1.axis('off') ax1.set_title('Original image', fontsize=20) ax2.imshow(edges, cmap=plt.cm.gray) ax2.axis('off') ax2.set_title('Canny filter, $\sigma=1$', fontsize=20)
(ellipse[0], (ellipse[1][0], ellipse[1][1]), ellipse[2]), 1, thickness=-1) ellipse_mask[z][tmp_img > 0] = 1 ellipse_mask = ellipse_mask.resample2D(img.header['pixelSize'][0], interpolation='nearest') #irtk.imwrite(output_dir + "/ellipse_mask.nii", ellipse_mask ) mask[ellipse_mask == 1] = 1 # fill holes, close and dilate disk_close = irtk.disk(5) disk_dilate = irtk.disk(2) for z in xrange(mask.shape[0]): mask[z] = nd.binary_fill_holes(mask[z]) mask[z] = nd.binary_closing(mask[z], disk_close) mask[z] = nd.binary_dilation(mask[z], disk_dilate) neg_mask = np.ones(mask.shape, dtype='uint8') * 2 # irtk.imwrite(output_dir + "/mask.nii", mask ) # irtk.imwrite(output_dir + "/mask.vtk", mask ) #x,y,z = img.WorldToImage(center) x, y, z = center x = int(round(x / img.header['pixelSize'][0])) y = int(round(y / img.header['pixelSize'][1])) z = int(round(z / img.header['pixelSize'][2])) w = h = int(round(ofd / img.header['pixelSize'][0]))