def test_MorphGeodesicActiveContour(): """Unit test for MorphGeodesicActiveContour method. Checks if evaluate function output\ is the same as manually running the skimage function.""" ac1 = Segmentors.MorphGeodesicActiveContour() assert ac1.evaluate(TEST_IM_COLOR).all() == segmentation.morphological_geodesic_active_contour(\ segmentation.inverse_gaussian_gradient(color.rgb2gray(TEST_IM_COLOR), 0.2, 0.3),\ iterations=10, init_level_set='checkerboard', smoothing=5, threshold='auto',\ balloon=10).all() assert ac1.evaluate(TEST_IM_GRAY).all() == segmentation.morphological_geodesic_active_contour(\ segmentation.inverse_gaussian_gradient(TEST_IM_GRAY, 0.2, 0.3), iterations=10,\ init_level_set='checkerboard', smoothing=5, threshold='auto', balloon=10).all()
def extract_image_features(self, data): # Please do not modify the header above # extract feature vector from image data feature_data = [] for img in data: img = color.rgb2gray(img) img = segmentation.inverse_gaussian_gradient(img, alpha=75.0, sigma=3.0) img = transform.resize(img, (100, 200), anti_aliasing=True, anti_aliasing_sigma=0.5) hog = feature.hog(img, orientations=12, pixels_per_cell=(24, 24), cells_per_block=(3, 3), transform_sqrt=True, block_norm="L1-sqrt", feature_vector=True, visualize=False, multichannel=False) feature_data.append(hog) feature_data = np.asarray(feature_data) # Please do not modify the return type below return (feature_data)
def geodesic_active_contour(): I = imread("{}/input/donuts-2.jpg".format(PROJECT_FOLDER), as_gray=True) IColor = imread("{}/input/donuts-2.jpg".format(PROJECT_FOLDER)) M = np.zeros(I.shape, dtype=np.int8) M[2:-2, 2:-2] = 1 gacContour = ContourGather([1, 50, 300]) gac(inverse_gaussian_gradient(I), 300, init_level_set=M, balloon=-1, threshold=0.78, iter_callback=lambda x: gacContour.callback(x)) fig, ax = plt.subplots(1, 1) set_plot_no_axes() ax.imshow(IColor) for e, c, i in zip(gacContour.evolution, colors, gacContour.it_hold): contour = ax.contour(e, [0.5], colors=c) contour.collections[0].set_label("Iteration {}".format(i)) plt.savefig( "{}/output/segmentation/geodesic-seg-don.png".format(PROJECT_FOLDER), bbox_inches='tight', pad_inches=0)
def createMask(x0, y0, x1, y1, fileName, patientID, rawDataPath): filePath = (rawDataPath + '/' + fileName) maskDataPath = '/home/faqih/ITB/TA/Web/server/static/maskData' segmentedImPath = '/home/faqih/ITB/TA/Web/server/static/segmentedImage' binaryCircle = _init(x0, y0, x1, y1) image = pydicom.filereader.dcmread(filePath).pixel_array gimage = inverse_gaussian_gradient(image, 200, 8) mask = morphological_geodesic_active_contour(gimage, 100, binaryCircle, smoothing=3, balloon=-1, threshold=0.6) fig, ax = plt.subplots(figsize=(7, 7)) plt.subplots_adjust(left=0, bottom=0, right=1, top=1, wspace=0, hspace=0) ax.imshow(image, cmap=plt.cm.gray) ax.contour(mask, [0.5], colors='r', linestyles='dashed', linewidths=2) ax.set_xticks([]), ax.set_yticks([]) ax.axis([0, image.shape[1], image.shape[0], 0]) #plt.show() ax.figure.savefig(os.path.join(segmentedImPath, fileName.split('.', 1)[0])) np.savez_compressed(os.path.join(maskDataPath, fileName.split('.', 1)[0] + '.npz'), mask=mask) return (fileName, patientID)
def probmap2bound_slicewise(i, prob_map_b, thres=0.7, ks=9): """ obtain boundary from probability map for each slice :param prob_map_b: ndarray of size [B, H, W], probability map :param thres: float, thres for filtering out pixels with prob lower than given thres :param outer_ks: int, kernel size for bound detection :return: lses: list of obtained bounds """ n_channel, height, width = prob_map_b.shape iter_max = 30 lses = [] for bound_inx in range(1, n_channel): # inner and outer bound prob_map_bb = prob_map_b[bound_inx] pred_filter = (prob_map_bb >= thres).astype(np.uint8) kernel_close = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (ks, ks)) for inx in range(iter_max): image_close = cv2.morphologyEx(pred_filter, cv2.MORPH_CLOSE, kernel_close, iterations=inx+1) _, contours, _ = cv2.findContours(image_close, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) contours = [contour for contour in contours if len(contour) > 4 and cv2.contourArea(contour) / len(contour) >= 4.0] if len(contours) > 0: # find the optimal number of iterations break if len(contours) > 0: mask = np.zeros(image_close.shape[:2], np.uint8) ls = cv2.drawContours(mask, contours, -1, 1, -1) else: # use Snake to find contours if cv2.findContours doesn't work well if bound_inx == 1: gimage = inverse_gaussian_gradient(img_as_float(image_close), alpha=100, sigma=5.0) else: gimage = inverse_gaussian_gradient(img_as_float(image_close), alpha=100, sigma=3.0) init = np.zeros(gimage.shape, dtype=np.int8) init[5:-5, 5:-5] = 1 ls = morphological_geodesic_active_contour(gimage, 100, init, smoothing=1, balloon=-1, threshold='auto') lses.append(ls) reg = lslist2bound(lses) return reg
def _filter_inv_gauss(imgs, alpha=10, sigma=1.5): """ TV denoising :param imgs: slice to denoise [2D] :param weight: TV weight :return: """ return segmentation.inverse_gaussian_gradient(imgs, alpha=alpha, sigma=sigma)
def preview(self, ips, para): snap, img = ips.snap, ips.img gimage = inverse_gaussian_gradient(img_as_float(snap)) init = np.ones(img.shape, dtype=np.bool) msk = morphological_geodesic_active_contour(gimage, para['iter'], init_level_set=init, smoothing=para['smooth'], threshold='auto' if para['auto'] else para['thr'], balloon=para['balloon']) > 0 (c1, c2), img[:] = ips.range, snap if para['out'] == 'mask': img[~msk], img[msk] = c1, c2 else: img[binary_dilation(msk) ^ msk] = c2 ips.update()
def snake_GAC(filename): image = io.imread(filename) gimage = inverse_gaussian_gradient(image) # Initial level set init_ls = np.zeros(image.shape, dtype=np.int8) init_ls[10:-10, 10:-10] = 1 # List with intermediate results for plotting the evolution evolution2 = [] callback = store_evolution_in(evolution2) ls = morphological_geodesic_active_contour(gimage, iterations, iter_callback=callback) return evolution2[-1]
def run(self, ips, snap, img, para=None): gimage = inverse_gaussian_gradient(img_as_float(snap)) init = ips.get_msk('out') msk = morphological_geodesic_active_contour( gimage, para['iter'], init_level_set=init, smoothing=para['smooth'], threshold='auto' if para['auto'] else para['thr'], balloon=para['balloon']) > 0 (c1, c2), img[:] = ips.range, snap if para['out'] == 'mask': img[~msk], img[msk] = c1, c2 else: img[binary_dilation(msk) ^ msk] = c2
def run(self, ips, snap, img, para = None): stackimg = [] callback = lambda x: stackimg.append((x*255).astype(np.uint8)) if para['sub'] else 0 gimage = inverse_gaussian_gradient(img_as_float(snap)) init = np.ones(img.shape, dtype=np.bool) msk = morphological_geodesic_active_contour(gimage, para['iter'], init_level_set=init, smoothing=para['smooth'], threshold='auto' if para['auto'] else para['thr'], balloon=para['balloon'], iter_callback=callback) > 0 (c1, c2), img[:] = ips.range, snap if para['out'] == 'mask': img[~msk], img[msk] = c1, c2 else: img[binary_dilation(msk) ^ msk] = c2 if para['sub']: self.app.show_img(stackimg, ips.title+'-sub')
def supercluster(self,clustered_data): gimage = inverse_gaussian_gradient(clustered_data) # Initial level set # this makes alternate squares active at the first iteration of 10 macro-pixels #init_ls = checkerboard_level_set(clustered_data.shape, 10) init_ls = np.zeros(clustered_data.shape, dtype=np.int8) init_ls[10:-10, 10:-10] = 1 # List with intermediate results for plotting the evolution evolution = [] callback = self.store_evolution_in(evolution) ls = morphological_geodesic_active_contour(gimage, 300, init_ls, smoothing=1, balloon=-1, threshold=0.69, iter_callback=callback) return ls
def test_morphsnakes_simple_shape_geodesic_active_contour(): img = (disk_level_set((11, 11), center=(5, 5), radius=3.5)).astype(float) gimg = inverse_gaussian_gradient(img, alpha=10.0, sigma=1.0) ls = disk_level_set(img.shape, center=(5, 5), radius=6) ref = np.array( [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0], [0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0], [0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0], [0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0], [0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0], [0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0], [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], dtype=np.int8) gac_ls = morphological_geodesic_active_contour(gimg, num_iter=10, init_level_set=ls, balloon=-1) assert_array_equal(gac_ls, ref) assert gac_ls.dtype == np.int8
def test_morphsnakes_simple_shape_geodesic_active_contour(): img = np.float_(circle_level_set((11, 11), (5, 5), 3.5)) gimg = inverse_gaussian_gradient(img, alpha=10.0, sigma=1.0) ls = circle_level_set(img.shape, (5, 5), 6) ref = np.array( [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0], [0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0], [0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0], [0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0], [0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0], [0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0], [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], dtype=np.int8) gac_ls = morphological_geodesic_active_contour(gimg, iterations=10, init_level_set=ls, balloon=-1) assert_array_equal(gac_ls, ref) assert gac_ls.dtype == np.int8
def test_morphsnakes_simple_shape_geodesic_active_contour(): img = np.float_(circle_level_set((11, 11), (5, 5), 3.5)) gimg = inverse_gaussian_gradient(img, alpha=10.0, sigma=1.0) ls = circle_level_set(img.shape, (5, 5), 6) ref = np.array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0], [0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0], [0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0], [0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0], [0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0], [0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0], [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], dtype=np.int8) gac_ls = morphological_geodesic_active_contour(gimg, iterations=10, init_level_set=ls, balloon=-1) assert_array_equal(gac_ls, ref) assert gac_ls.dtype == np.int8
def supercluster(self, clustered_data): #print ("clu data = ",clustered_data) gimage = inverse_gaussian_gradient(clustered_data, 10, 1.5) print("Fatto") # Initial level set # this makes alternate squares active at the first iteration of 10 macro-pixels #init_ls = checkerboard_level_set(clustered_data.shape, 10) init_ls = np.zeros(clustered_data.shape, dtype=np.int8) init_ls[10:-10, 10:-10] = 1 # List with intermediate results for plotting the evolution #evolution = [] #callback = self.store_evolution_in(evolution) #ls = morphological_geodesic_active_contour(gimage, 400, init_ls, # smoothing=1, balloon=-1, # threshold=0.6) #iter_callback=callback) ls = morphological_chan_vese(gimage, 400, init_ls, smoothing=1, lambda1=8., lambda2=10.) print("Bene!") return ls
def morphological(image): # Morphological ACWE img = img_as_float(skimage.color.rgb2gray(image)) # Initial level set init_ls = checkerboard_level_set(img.shape, 6) # List with intermediate results for plotting the evolution evolution = [] callback = store_evolution_in(evolution) ls = morphological_chan_vese(img, 200, init_level_set=init_ls, smoothing=4, iter_callback=callback) fig, axes = plt.subplots(2, 2, figsize=(8, 8)) ax = axes.flatten() ax[0].imshow(img, cmap="gray") ax[0].set_axis_off() ax[0].contour(ls, [0.5], colors='r') ax[0].set_title("Morphological ACWE segmentation", fontsize=12) ax[1].imshow(ls, cmap="gray") ax[1].set_axis_off() contour = ax[1].contour(evolution[2], [0.5], colors='g') contour.collections[0].set_label("Iteration 2") contour = ax[1].contour(evolution[7], [0.5], colors='y') contour.collections[0].set_label("Iteration 7") contour = ax[1].contour(evolution[-1], [0.5], colors='r') contour.collections[0].set_label("Iteration 35") ax[1].legend(loc="upper right") title = "Morphological ACWE evolution" ax[1].set_title(title, fontsize=12) # Morphological GAC img = img_as_float(skimage.color.rgb2gray(image)) gimage = inverse_gaussian_gradient(img) # Initial level set init_ls = np.zeros(img.shape, dtype=np.int8) init_ls[10:-10, 10:-10] = 1 # List with intermediate results for plotting the evolution evolution = [] callback = store_evolution_in(evolution) ls = morphological_geodesic_active_contour(gimage, 230, init_ls, smoothing=5, balloon=-1, threshold=0.5, iter_callback=callback) ax[2].imshow(img, cmap="gray") ax[2].set_axis_off() ax[2].contour(ls, [0.5], colors='r') ax[2].set_title("Morphological GAC segmentation", fontsize=12) ax[3].imshow(ls, cmap="gray") ax[3].set_axis_off() contour = ax[3].contour(evolution[0], [0.5], colors='g') contour.collections[0].set_label("Iteration 0") contour = ax[3].contour(evolution[100], [0.5], colors='y') contour.collections[0].set_label("Iteration 100") contour = ax[3].contour(evolution[-1], [0.5], colors='r') contour.collections[0].set_label("Iteration 230") ax[3].legend(loc="upper right") title = "Morphological GAC evolution" ax[3].set_title(img, fontsize=12) fig.tight_layout() plt.show()
def run(self): self.beginTaskRun() # Get input 0 : input = self.getInput(0) # Get output : output = self.getOutput(0) # Get parameters : param = self.getParam() # Get image from input/output (numpy array): srcImage = input.getImage() # Convert to grey Image if RGB if len(srcImage.shape) == 3: image = cv2.cvtColor(srcImage, cv2.COLOR_RGB2GRAY) else: image = srcImage # Convert to float imagef = img_as_float(image) # enhances borders if param.mgac_amplification_contour == "Inverse gaussian gradient": gimage = inverse_gaussian_gradient(imagef) else: gimage = imagef # initial level set initlevelSetInput = self.getInput(2) if initlevelSetInput.isDataAvailable(): initlevelSetBinary = initlevelSetInput.getImage() if param.method == "mgac": proc_img = morphological_geodesic_active_contour( gimage, param.mgac_iterations, init_level_set=initlevelSetBinary, smoothing=param.mgac_smoothing, threshold=param.mgac_threshold, balloon=param.mgac_balloon, iter_callback=(lambda callback: self.emitStepProgress() )).astype(np.uint8) * 255 else: proc_img = morphological_chan_vese( gimage, param.mcv_iterations, init_level_set=initlevelSetBinary, smoothing=param.mcv_smoothing, lambda1=param.mcv_lambda1, lambda2=param.mcv_lambda2, iter_callback=(lambda callback: self.emitStepProgress() )).astype(np.uint8) * 255 else: # input graph -> by user / by previous aoperation in worflow graphInput = self.getInput(1) if graphInput.isDataAvailable(): self.createGraphicsMask(imagef.shape[1], imagef.shape[0], graphInput) binImg = self.getGraphicsMask(0) if param.method == "mgac": proc_img = morphological_geodesic_active_contour( gimage, param.mgac_iterations, init_level_set=binImg, smoothing=param.mgac_smoothing, threshold=param.mgac_threshold, balloon=param.mgac_balloon, iter_callback=( lambda callback: self.emitStepProgress())).astype( np.uint8) * 255 else: proc_img = morphological_chan_vese( gimage, param.mcv_iterations, init_level_set=binImg, smoothing=param.mcv_smoothing, lambda1=param.mcv_lambda1, lambda2=param.mcv_lambda2, iter_callback=( lambda callback: self.emitStepProgress())).astype( np.uint8) * 255 else: raise Exception( "No initial level-set given: it must be graphics input or binary image." ) # set output mask binary image output.setImage(proc_img) # add foward input image self.forwardInputImage(0, 1) # Call endTaskRun to finalize process self.endTaskRun()
from skimage.color import rgb2gray from skimage import measure imagedir = '/home/winshare/下载/1723236901.jpg' from skimage.segmentation import (morphological_chan_vese, morphological_geodesic_active_contour, inverse_gaussian_gradient, checkerboard_level_set) import numpy as np origin = cv2.imread(imagedir) gray = rgb2gray(origin) print(gray.mean() * 255) mean1 = gray.mean() gray[gray > mean1] = 0 image = inverse_gaussian_gradient(gray, alpha=20, sigma=0.9) image = 1 - image # gray1=np.float(gray) contours = measure.find_contours(origin[:, :, 0], mean1 * 255) print(contours) fig, ax = plt.subplots(nrows=1, ncols=2, figsize=(10, 10), sharex=True, sharey=True) ax[0].imshow(origin, cmap=plt.cm.nipy_spectral, interpolation='nearest') ax[1].imshow(origin) for n, contour in enumerate(contours): ax[1].plot(contour[:, 1], contour[:, 0], linewidth=2)
{ -3.0, -4.0, -4.0, -5.0, -5.0, -4.0, -4.0, -3.0}, { -2.0, -3.0, -3.0, -4.0, -4.0, -3.0, -3.0, -2.0}, { -1.0, -2.0, -2.0, -2.0, -2.0, -2.0, -2.0, -1.0}, { 2.0, 2.0, 0.0, 0.0, 0.0, 0.0, 2.0, 2.0 }, { 2.0, 3.0, 1.0, 0.0, 0.0, 1.0, 3.0, 2.0 } }; image_object = filters.normalize(alpha = 0.01, beta = 0.1, scale = 'absolute') image_object_gray = color.rgb2gray(image_object) absolute_best_segmented_image = NULL no_of_segments_in_abs_best = 1 iterations_till_now_for_t = 0 for(t in range(25, max(image_object_gray))): try: new_segmented_image = seg.inverse_gaussian_gradient(image_object_gray) selected_threshold = t iterations_till_now_for_s = 0 for(s in range(1, 255)): single_88_positive_image = new_segmented_image.filter(single_88_positive) single_88_negative_image = new_segmented_image.filter(single_88_negative) new_segmented_image = min(single_88_positive_image, single_88_negative_image) new_segmented_image = seg.join_segmentations(image_object_gray, new_segmented_image) if(quality(new_segmented_image) > quality(absolute_best_segmented_image)): absolute_best_segmented_image = new_segmented_image no_of_segments_in_abs_best = s iterations_till_now_for_s += 1 iterations_till_now_for_t += 1 except: print("Error: Finding optimized image is not possible for given image.") finally:
ax[1].imshow(ls, cmap="gray") ax[1].set_axis_off() contour = ax[1].contour(evolution[2], [0.5], colors='g') contour.collections[0].set_label("Iteration 2") contour = ax[1].contour(evolution[7], [0.5], colors='y') contour.collections[0].set_label("Iteration 7") contour = ax[1].contour(evolution[-1], [0.5], colors='r') contour.collections[0].set_label("Iteration 35") ax[1].legend(loc="upper right") title = "Morphological ACWE evolution" ax[1].set_title(title, fontsize=12) # Morphological GAC image = img_as_float(data.coins()) gimage = inverse_gaussian_gradient(image) # Initial level set init_ls = np.zeros(image.shape, dtype=np.int8) init_ls[10:-10, 10:-10] = 1 # List with intermediate results for plotting the evolution evolution = [] callback = store_evolution_in(evolution) ls = morphological_geodesic_active_contour(gimage, 230, init_ls, smoothing=1, balloon=-1, threshold=0.69, iter_callback=callback) ax[2].imshow(image, cmap="gray") ax[2].set_axis_off() ax[2].contour(ls, [0.5], colors='r')
def morphSnakes(fp, frame, alph, sig, thresh): """{ ****************************************************************** * Fnc: read_arf() * Desc: reads an arf file and returns dictionary of parsed info * Inputs: fp - full path to arf file * Outputs: ****************************************************************** }""" ############################ Read Public Release Data ################################################## # print('Reading data...') _, fn = os.path.split(fp) basename, _ext = os.path.splitext(fn) df = pd.read_csv(f"{DATA_DIR}/Metric/{basename}.bbox_met", header=None, names=[ "site", "unknown1", "unknown2", "sensor", "scenario", "frame", "ply_id", "unknown3", "unknown4", "upperx", "uppery", "unknown5", "unknown6", "unknown7", "unknown8", "unknown9", "unknown10", "unknown11" ]) agt = read_agt(f"{DATA_DIR}/cegr/agt/{basename}.agt") f = open(fp, "rb") header = f.read(8 * 4) header = list(struct.iter_unpack(">I", header)) fptr = np.memmap(fp, dtype="uint16", mode='r', shape=(header[5][0], header[2][0], header[3][0]), offset=32) frames, cols, rows = fptr.shape # print('Data loaded!') im = fptr[frame].T.byteswap() tgtx, tgty = map( int, agt['Agt']['TgtSect'][f'TgtUpd.{frame}'][f'Tgt.{frame}'] ['PixLoc'].split()) upper_left_x, upper_left_y = df[df['frame'] == frame + 1][['upperx', 'uppery']].iloc[0] tgt_width = 2 * (tgtx - upper_left_x) tgt_height = 2 * (tgty - upper_left_y) ######################################### Find BB with GAC ################################################ def store_evolution_in(lst): """Returns a callback function to store the evolution of the level sets in the given list. """ def _store(x): lst.append(np.copy(x)) return _store plt.ioff() fig, axes = plt.subplots(2, 2, figsize=(8, 8)) ax = axes.flatten() # Morphological GAC image = img_as_float(im.T) gimage = inverse_gaussian_gradient(image, alpha=alph, sigma=sig) ax[0].imshow(image, cmap="gray") ax[0].set_axis_off() ax[0].set_title("MWIR", fontsize=12) ax[1].imshow(gimage, cmap="gray") ax[1].set_axis_off() ax[1].set_title("Inverse Gaussian Gradient", fontsize=12) ######################################## Set Initial Contour ########################################### ## Here you will want to set it as the bounding box, then you can set the morph snake to shrink instead ## of dialate. ######################################################################################################## # Initial level set init_ls = circle_level_set(image.shape, center=(tgty, tgtx), radius=5) # init_ls[10:-10, 10:-10] = 1 # List with intermediate results for plotting the evolution evolution = [] callback = store_evolution_in(evolution) ## Initialize the Morph Snake, you will want it to shrink (balloon=-1) ls = morphological_geodesic_active_contour(gimage, 230, init_ls, smoothing=1, balloon=1, threshold=thresh, iter_callback=callback) ax[2].imshow(image, cmap="gray") ax[2].set_axis_off() ax[2].contour(ls, [0.5], colors='r') ax[2].set_title("Center Point GAC Segmentation", fontsize=12) ax[3].imshow(ls, cmap="gray") ax[3].set_axis_off() contour = ax[3].contour(evolution[0], [0.5], colors='g') contour.collections[0].set_label("Iteration 0") contour = ax[3].contour(evolution[100], [0.5], colors='y') contour.collections[0].set_label("Iteration 100") contour = ax[3].contour(evolution[-1], [0.5], colors='r') contour.collections[0].set_label("Iteration 230") ax[3].legend(loc="upper right") title = "Center Point GAC Evolution" ax[3].set_title(title, fontsize=12) fig.tight_layout() fig.tight_layout(rect=[0, 0.03, 1, 0.95]) plt.suptitle( f'Morph Snakes, alpha={alph}, sigma={sig}, threshold={thresh}') # plt.savefig(f"{DATA_DIR}\\morphSnakes\\{basename}_{alph}_{sig}_{thresh}.png") # plt.close(fig) plt.show()
ax[1].imshow(ls, cmap="gray") ax[1].set_axis_off() contour = ax[1].contour(evolution[2], [0.5], colors='g') contour.collections[0].set_label("Iteration 2") contour = ax[1].contour(evolution[7], [0.5], colors='y') contour.collections[0].set_label("Iteration 7") contour = ax[1].contour(evolution[-1], [0.5], colors='r') contour.collections[0].set_label("Iteration 35") ax[1].legend(loc="upper right") title = "Morphological ACWE evolution" ax[1].set_title(title, fontsize=12) # Morphological GAC image = img_as_float(data.coins()) gimage = inverse_gaussian_gradient(image) # Initial level set init_ls = np.zeros(image.shape, dtype=np.int8) init_ls[10:-10, 10:-10] = 1 # List with intermediate results for plotting the evolution evolution2 = [] callback = store_evolution_in(evolution2) ls = morphological_geodesic_active_contour(gimage, 230, init_ls, smoothing=1, balloon=-1, threshold=0.69, iter_callback=callback)
def main(): filePath = '../Img/' fileList = os.listdir(filePath) # name = '13.png' for i in range(len(fileList)): # len(fileList) Image = cv2.imread(os.path.join(filePath, fileList[i]), 1) # 读入原图 image = cv2.cvtColor(Image, cv2.COLOR_BGR2GRAY) image = img_as_float(image) # image = np.array(image, dtype=np.float64) # 读入到np的array中,并转化浮点类型 # Initial level set init_ls = checkerboard_level_set(image.shape, 6) # List with intermediate results for plotting the evolution ls = morphological_chan_vese(image, 35, init_level_set=init_ls, smoothing=0) fig, axes = plt.subplots(2, 2, figsize=(8, 8)) ax = axes.flatten() ax[0].imshow(image, cmap="gray") ax[0].set_axis_off() ax[0].contour(ls, [0.5], colors='r') ax[0].set_title(fileList[i] + 'MAC', fontsize=12) # Morphological GAC gimage = inverse_gaussian_gradient(image) # Initial level set init_ls = np.zeros(image.shape, dtype=np.int8) init_ls[10:-10, 10:-10] = 1 # List with intermediate results for plotting the evolution ls = morphological_geodesic_active_contour(gimage, 230, init_ls, smoothing=1, balloon=-1, threshold=0.69) ax[1].imshow(image, cmap="gray") ax[1].set_axis_off() ax[1].contour(ls, [0.5], colors='r') ax[1].set_title('MGAC', fontsize=12) #CV cv = chan_vese(image, mu=0.25, lambda1=1, lambda2=1, tol=1e-3, max_iter=200, dt=0.5, init_level_set="checkerboard", extended_output=True) ax[2].imshow(image, cmap="gray") ax[2].set_axis_off() ax[2].contour(cv[0], [0.5], colors='r') ax[2].set_title('AC', fontsize=12) #My CV from MyCV import my_chan_vese # CV cv = my_chan_vese(image, mu=0.25, lambda1=1, lambda2=1, tol=1e-3, max_iter=200, dt=0.5, init_level_set="checkerboard", extended_output=True) ax[3].imshow(image, cmap="gray") ax[3].set_axis_off() ax[3].contour(cv[0], [0.5], colors='r') ax[3].set_title('MyAC', fontsize=12) fig.tight_layout() plt.savefig('./MCVSeg2/' + fileList[i] + '.png') plt.show(block=False)
def main(): current_path = os.path.abspath(os.path.dirname(__file__)) dice_results = [] hausdorff_results = [] # Final report text file initialization summary_file = open('contour_report.txt', 'w+') summary_file.write('Script run: {a}\n'.format( a=datetime.now().strftime('%Y-%m-%d %H:%M:%S'))) for image_number in range(1, 110): image_path = os.path.join(current_path, 'input_images', '{}_no_contour.jpg'.format(image_number)) image = io.imread(image_path) image = color.rgb2gray(image) # Displaying the image to get the clicks coordinates fig = plt.figure() plt.imshow(image, cmap='gray') plt.axis('Off') cid = fig.canvas.mpl_connect('button_press_event', onclick) plt.show() # Calculating the radius, used to initialize the level set algorithm radius = np.sqrt( np.square(coords[1][0] - coords[0][0]) + np.square(coords[1][1] - coords[0][1])) # Main part of the script - image processing and creating the contour: # 1. Histogram equalization # 2. Gaussian filtration # 3. Anisotropic diffusion filtration # 4. Inverse Gaussian Gradient # 5. Unsharp Masking # 6. Morphological snakes # Hyperparameter optimization were performed using grid search for every method. equalized_image = equalize_hist(image) filtered_image = nd.gaussian_filter(equalized_image, sigma=5) diff_image = anisodiff(filtered_image, niter=50) gimage = inverse_gaussian_gradient(diff_image, alpha=50) sharpened_image = unsharp_mask(gimage, radius=100, amount=1.0) init_level_set = circle_level_set(gimage.shape, coords[0], radius) level_set = morphological_geodesic_active_contour(sharpened_image, 250, init_level_set, smoothing=4, balloon=1) level_set = nd.morphology.binary_fill_holes(level_set).astype(int) contour_access = os.path.join('input_images', '{}_contour.jpg'.format(image_number)) given_contour = contour_to_binary_mask(contour_access, level_set.shape) dice_result = dice(given_contour, level_set) hausdorff_result = hausdorff(given_contour, level_set) print('Dice =', dice_result) print('Hausdorff =', hausdorff_result) # Updating the report with new coefficients. summary_file.write('\n{a}:\nDice: {b}\nHausdorff: {c}\n'.format( a=image_number, b=format(dice_result, '.2f'), c=format(hausdorff_result, '.2f'))) dice_results.append(dice_result) hausdorff_results.append(hausdorff_result) # Displaying the result plt.figure() plt.imshow(image, cmap="gray") plt.axis('Off') plt.contour(level_set, [0.5], colors='r') plt.show() # Calculating and appending mean and standard deviation of the test to the end of the report summary_file.write('\n\nDICE:\nMEAN: {d}\nSTD DEV: {e}'.format( d=format(mean(dice_results), '.2f'), e=format(stddev(dice_results), '.2f'))) summary_file.write('\n\nHAUSDORFF:\nMEAN: {d}\nSTD DEV: {e}'.format( d=format(mean(hausdorff_results), '.2f'), e=format(stddev(hausdorff_results), '.2f'))) summary_file.close()
def active_contour(image): def store_evolution_in(lst): def _store(x): lst.append(np.copy(x)) return _store image = img_as_float(data.camera()) init_ls = checkerboard_level_set(image.shape, 6) evolution = [] callback = store_evolution_in(evolution) ls = morphological_chan_vese(image, 35, init_level_set=init_ls, smoothing=3, iter_callback=callback) fig, axes = plt.subplots(2, 2, figsize=(8, 8)) ax = axes.flatten() ax[0].imshow(image, cmap="gray") ax[0].set_axis_off() ax[0].contour(ls, [0.5], colors='r') ax[0].set_title("Morphological ACWE segmentation", fontsize=12) ax[1].imshow(ls, cmap="gray") ax[1].set_axis_off() contour = ax[1].contour(evolution[2], [0.5], colors='g') contour.collections[0].set_label("Iteration 2") contour = ax[1].contour(evolution[7], [0.5], colors='y') contour.collections[0].set_label("Iteration 7") contour = ax[1].contour(evolution[-1], [0.5], colors='r') contour.collections[0].set_label("Iteration 35") ax[1].legend(loc="upper right") title = "Morphological ACWE evolution" ax[1].set_title(title, fontsize=12) image = img_as_float(data.coins()) gimage = inverse_gaussian_gradient(image) init_ls = np.zeros(image.shape, dtype=np.int8) init_ls[10:-10, 10:-10] = 1 evolution = [] callback = store_evolution_in(evolution) ls = morphological_geodesic_active_contour(gimage, 230, init_ls, smoothing=1, balloon=-1, threshold=0.69, iter_callback=callback) ax[2].imshow(image, cmap="gray") ax[2].set_axis_off() ax[2].contour(ls, [0.5], colors='r') ax[2].set_title("Morphological GAC segmentation", fontsize=12) ax[3].imshow(ls, cmap="gray") ax[3].set_axis_off() contour = ax[3].contour(evolution[0], [0.5], colors='g') contour.collections[0].set_label("Iteration 0") contour = ax[3].contour(evolution[100], [0.5], colors='y') contour.collections[0].set_label("Iteration 100") contour = ax[3].contour(evolution[-1], [0.5], colors='r') contour.collections[0].set_label("Iteration 230") ax[3].legend(loc="upper right") title = "Morphological GAC evolution" ax[3].set_title(title, fontsize=12) fig.tight_layout() plt.show()
def level_set3D(data, seed3D, resol, lambda1=1, lambda2=4, smoothing=0, iterations=100, rad=3, method='ACWE', alpha=100, sigma=2, balloon=1): ## init res_fac = resol[1] / resol[ 0] # resolution factor to scale chunk to real dimensions N = 60 # approximately the chunk size (in mm) around nodule num_slices = int(round(N / res_fac)) # number of slices before reg = 30 # window of interest centered around seed point s = seed3D[1:] # 2D seed point for (x,y)-plane num = seed3D[0] # slice number seed point is selected from # apply lungmask on each slice of interest around seed point tmp_data = np.zeros((num_slices, data.shape[1], data.shape[2])) ii = 0 for i in range(data.shape[0]): if (i >= num - int(round(num_slices / 2)) and i <= num + int(round(num_slices / 2)) - 1): mask = lungmask_pro(data[i, :, :].copy()) tmp = data[i, :, :].copy() tmp[mask == 0] = np.amin( tmp ) # OBS: -1024 maybe not far away enough from lung intensities tmp_data[ii, :, :] = tmp.copy() ii += 1 # only apply level set on small volume around seed point -> increases speed and accuracy for fixed number of iterations tmp = tmp_data.copy() tmp = tmp[:, s[0] - reg:s[0] + reg, s[1] - reg:s[1] + reg] # transform chunk to true size (in mm) by stretching the slice-axis relevant to a resolution factor tmp = zoom(tmp.copy(), zoom=[res_fac, 1, 1], order=1) # apply 3D level set from single seed point from initial 3D blob around current seed point inits = circle_level_set(tmp.shape, center=(int(num_slices / 2 * res_fac), reg, reg), radius=rad) # choose between two types of level set methods if method == 'ACWE': tmp = morphological_chan_vese(tmp.copy(), iterations=iterations, init_level_set=inits, smoothing=smoothing, lambda1=lambda1, lambda2=lambda2).astype(int) elif method == 'GAC': tmp = tmp.astype(np.float32) tmp = inverse_gaussian_gradient(tmp, alpha=alpha, sigma=alpha) tmp = morphological_geodesic_active_contour(tmp, iterations=iterations, init_level_set=inits, smoothing=smoothing, threshold='auto', balloon=1) else: print('Please choose a valid method!') return None # if no nodule was segmented, break if (len(np.unique(tmp)) == 1): #print('No nodule was segmented. Try changing parameters...') return None # check if leakage has occured #if ((tmp[0,0,0] > 0) or (tmp[0,0,-1] > 0) or (tmp[0,-1,0] > 0) or (tmp[0,-1,-1] > 0) or (tmp[-1,0,0] > 0) or (tmp[-1,-1,0] > 0) or (tmp[-1,0,-1] > 0) or (tmp[-1,-1,-1] > 0)): # if ((len(np.unique(tmp[0,:,:])) > 1) or (len(np.unique(tmp[:,0,:])) > 1) or (len(np.unique(tmp[:,:,0])) > 1) or # (len(np.unique(tmp[-1,:,:])) > 1) or (len(np.unique(tmp[:,-1,:])) > 1) or (len(np.unique(tmp[:,:,-1])) > 1)): # print("Leakage problems? Growing reached boundaries... Discards segmentation") # return None # only keep segments connected to seed point (blood vessels will hopefully not be connected with nodule after level set, if leakage has occured) labels_tmp = label(tmp.copy()) res = np.zeros(tmp.shape) if (labels_tmp[int(num_slices / 2 * res_fac), reg, reg] > 0): res[labels_tmp == labels_tmp[int(num_slices / 2 * res_fac), reg, reg]] = 1 # need to transform chunk back to original size res = zoom(res.copy(), zoom=[1 / res_fac, 1, 1], order=1) # # just in case some parts are not connected anymore after interpolation -> remove not connected components # labels_tmp = label(res.copy()) # res = np.zeros(res.shape) # if (labels_tmp[int(num_slices/2), reg, reg] > 0): # res[labels_tmp == labels_tmp[int(num_slices/2), reg, reg]] = 1 # get the final nodule mask to the original image stack shape # but handle cases where seed point is selected at ends of image stack, and window is outside of range new_res = np.zeros(data.shape) if (num + int(num_slices / 2) > new_res.shape[0]): new_res[num - int(num_slices / 2):num + int(num_slices / 2), s[0] - reg:s[0] + reg, s[1] - reg:s[1] + reg] = res[:num + int(num_slices / 2) - new_res.shape[0]] elif (num - int(num_slices / 2) < 0): new_res[0:num + int(num_slices / 2), s[0] - reg:s[0] + reg, s[1] - reg:s[1] + reg] = res[:num + int(num_slices / 2)] else: new_res[num - int(np.floor(num_slices / 2)):num + int(np.ceil(num_slices / 2)), s[0] - reg:s[0] + reg, s[1] - reg:s[1] + reg] = res return new_res