def set_default_features(self, images=None): if images is not None: self.images = images # Functions to apply to the pixels of an arc self.features["length"] = lambda pixels: len(pixels) self.features["min"] = lambda pixels: np.min(pixels) self.features["max"] = lambda pixels: np.max(pixels) self.features["median"] = lambda pixels: np.median(pixels) self.features["mode"] = lambda pixels: scipy.stats.mode( np.round(pixels, 2))[0][0] self.features["mean"] = lambda pixels: gaussian_fit(pixels)[0] self.features["std"] = lambda pixels: gaussian_fit(pixels)[1] self.features["var"] = lambda pixels: gaussian_fit(pixels)[2] self.features["skew"] = lambda pixels: scipy.stats.skew(pixels) self.features["kurtosis"] = lambda pixels: scipy.stats.kurtosis(pixels) self.features["range"] = lambda pixels: np.max(pixels) - np.min(pixels) # The input for these is fundamentally different, so for now # we will key off the fact that the name will always start with # "neighbor" in order to pass the right pixels to them. # Alternatively, we can send all of the pixels, and in the # methods above, just operate on the first row which could be # guaranteeed to be the pixels for the arc being operated on. self.features["neighbor_degree"] = lambda connected_pixels: len( connected_pixels) self.features["neighbor_min"] = lambda connected_pixels: np.min( [np.min(pixels) for pixels in connected_pixels]) self.features["neighbor_max"] = lambda connected_pixels: np.max( [np.max(pixels) for pixels in connected_pixels]) self.features["neighbor_mean"] = lambda connected_pixels: np.mean( [np.mean(pixels) for pixels in connected_pixels]) self.features["neighbor_std"] = lambda connected_pixels: np.std( [np.mean(pixels) for pixels in connected_pixels]) # Pixel values to use for the aforementioned functions: self.images["identity"] = self.image self.images["sobel"] = sobel_filter(self.image) self.images["laplacian"] = laplacian_filter(self.image) for i in range(1, 5): pow1 = 2**(i - 1) pow2 = 2**i self.images["mean_{}".format(i)] = mean_filter(self.image, i) self.images["variance_{}".format(i)] = variance_filter( self.image, i) self.images["median_{}".format(i)] = median_filter(self.image, i) self.images["min_{}".format(i)] = minimum_filter(self.image, i) self.images["max_{}".format(i)] = maximum_filter(self.image, i) self.images["gauss_{}".format(pow2)] = gaussian_blur_filter( self.image, pow2) self.images["delta_gauss_{}_{}".format( pow1, pow2)] = difference_of_gaussians_filter( self.image, pow1, pow2) for i, neighbor_image in enumerate(neighbor_filter(self.image, 3)): self.images["shift_{}".format(i)] = neighbor_image
def classify_msc(image, classifier, persistence=8.5, show_pruned=False): predicted_classification = np.copy(image) / 1.1 # np.zeros(image.shape) # Compute the morse smale complex of all blurred images and filter # arcs of interest based on mu from gaussian fit to pixel histogram # for each image blurred_image, fname = blur_and_save(image, "classify_msc") msc = build_msc( fname, blurred_image.shape[1], blurred_image.shape[0], persistence ) arc_set_pixels = [] # gauss_arcs = [] pruned_cord = [] for arc in msc.arcs: arc_pixels = [] gauss_arc = [] points = np.array(arc.line) # arc_points.append(tuple((point[1], point[0]))) for point in points: arc_pixels.append(image[int(point[1]), int(point[0])]) gauss_arc.append(gaussian_fit(np.array(arc_pixels))) arc_set_pixels.append(arc_pixels) # predict given obsereved arc attributes arc_classification = classifier.predict(gauss_arc) for point in points: if not show_pruned: predicted_classification[int(point[1]), int(point[0])] = ( arc_classification if arc_classification == 1 else predicted_classification[int(point[1]), int(point[0])] ) else: predicted_classification[int(point[1]), int(point[0])] = ( arc_classification if arc_classification == 1 else predicted_classification[int(point[1]), int(point[0])] ) if arc_classification != 1: pruned_cord.append([int(point[1]), int(point[0])]) show_image(predicted_classification) if show_pruned: pruned = np.vstack(pruned_cord) plt.scatter( pruned[:, 1], pruned[:, 0], facecolor=blue, edgecolor="none", s=1, marker=",", zorder=2, alpha=0.03, )
def mapped_msc_filtered_training_set( original_image, filtered_images, msc, filter_msc=False, bg_pixels=False ): # , image_set = filtered_images): pos_pixels = [] neg_pixels = [] gauss_msc_pos = [] gauss_msc_neg = [] # compute morse smale complex of original, blurred image, to project # onto filtered images original_image = filtered_images[:, :, 0] # If the msc of original image is to be filtered if filter_msc: # mu, sigma, var = gaussian_fit(original_image) mu, _, _ = gaussian_fit(original_image) filtered_msc = msc_filtration(original_image, msc, mu) msc = filtered_msc else: # no filtration just sorted msc mu = 0 msc = msc_filtration(original_image, msc, mu) filtered_images = np.dstack((filtered_images, original_image)) kernel_size = filtered_images.shape[2] # print("kernel size: ", kernel_size) for i in range(kernel_size): # Cover filtered MSC with closed balls to select negative space # as background and arcs as positive samples # Using msc obtained from original image pos_samples, neg_samples = collect_training_from_filtered( filtered_images[:, :, i], msc ) # get pixel values under arc for positives for arc_pos in pos_samples: for point_pos in arc_pos: pos_pixels.append( [filtered_images[int(point_pos[0]), int(point_pos[1]), i]] ) # get negative pixel values if bg_pixels: for bg_group in neg_samples: for point_neg in bg_group: neg_pixels.append( [ filtered_images[ int(point_neg[0]), int(point_neg[1]), i ] ] ) # fit gaussian to negative pixel values in background and # take mean, standard deviation, variance for arc_neg in neg_samples: filtered_negatives = [] for point_neg in arc_neg: filtered_negatives.append( [ filtered_images[ int(point_neg[0]), int(point_neg[1]), i ] ] ) # fit gaussian to negative sample pixels in background mu_neg, sigma_neg, var_neg = gaussian_fit( np.array(filtered_negatives) ) # max_pix = np.max(np.array(filtered_negatives)) # min_pix = np.min(np.array(filtered_negatives)) gauss_msc_neg.append([mu_neg, sigma_neg, var_neg]) # fit gaussian to positive pixel values under arcs of MSC and # take mean, standard deviation, and variance for arc in pos_samples: filtered_positives = [] for point in arc: filtered_positives.append( [filtered_images[int(point[0]), int(point[1]), i]] ) # fit gaussian to positive pixel values under arc and take # mean, standard deviation, variance # NOTE! can filter based on arc length, currently doing # three bc three degrees of freedom in gaussian fit. if len(filtered_positives) >= 3: mu_pos, sigma_pos, var_pos = gaussian_fit( np.array(filtered_positives) ) # max_pix = np.max(np.array(filtered_positives)) # min_pix = np.min(np.array(filtered_positives)) gauss_msc_pos.append([mu_pos, sigma_pos, var_pos]) train_x = np.vstack((pos_pixels, neg_pixels)) train_y = np.hstack( ( np.ones(np.array(pos_pixels).shape[0]), np.zeros(np.array(neg_pixels).shape[0]), ) ) gaussian_msc_arc_X = np.vstack((gauss_msc_pos, gauss_msc_neg)) gaussian_msc_arc_Y = np.hstack( ( np.ones(np.array(gauss_msc_pos).shape[0]), np.zeros(np.array(gauss_msc_neg).shape[0]), ) ) return train_x, train_y, gaussian_msc_arc_X, gaussian_msc_arc_Y
def filtered_msc_training_set(filtered_images, kernel_size, persistence=8.5): pos_pixels = [] neg_pixels = [] gauss_msc_pos = [] gauss_msc_neg = [] for i in range(kernel_size): # Compute the morse smale complex of all blurred images and # filter arcs of interest based on mu from gaussian fit to pixel # histogram for each image filtered_smooth, fname = blur_and_save( filtered_images[:, :, i], "filtered_msc_training_set_{}".format(i) ) full_msc = build_msc( fname, filtered_smooth.shape[1], filtered_smooth.shape[0], persistence, ) mu, sigma, var = gaussian_fit(filtered_images[:, :, i]) filtered_msc = msc_filtration(filtered_images[:, :, i], full_msc, mu) # Cover filtered MSC with closed balls to select negative space # as background and arcs as positive samples pos_samples, neg_samples = collect_training_from_filtered( filtered_images[:, :, i], filtered_msc ) # a = np.array(neg_samples) # get pixel values under arc for positives for arc_pos in pos_samples: for point_pos in arc_pos: pos_pixels.append( [filtered_images[int(point_pos[0]), int(point_pos[1]), i]] ) # get negative pixel values for bg_group in neg_samples: for point_neg in bg_group: neg_pixels.append( [filtered_images[int(point_neg[0]), int(point_neg[1]), i]] ) # fit gaussian to negative pixel values in background and take # mean, standard deviation, variance for arc_neg in neg_samples: filtered_negatives = [] for point_neg in arc_neg: filtered_negatives.append( [filtered_images[int(point_neg[0]), int(point_neg[1]), i]] ) # fit gaussian to negative sample pixels in background mu_neg, sigma_neg, var_neg = gaussian_fit( np.array(filtered_negatives) ) gauss_msc_neg.append([mu_neg, sigma_neg, var_neg]) # fit gaussian to positive pixel values under arcs of MSC and # take mean, standard deviation, and variance for arc in pos_samples: filtered_positives = [] for point in arc: filtered_positives.append( [filtered_images[int(point[0]), int(point[1]), i]] ) # fit gaussian to positive pixel values under arc and take # mean, standard deviation, and variance # NOTE! can filter based on arc length, currently doing # three bc three degrees of freedom in gaussian fit. if len(filtered_positives) >= 3: mu_pos, sigma_pos, var_pos = gaussian_fit( np.array(filtered_positives) ) gauss_msc_pos.append([mu_pos, sigma_pos, var_pos]) train_x = np.vstack((pos_pixels, neg_pixels)) train_y = np.hstack( ( np.ones(np.array(pos_pixels).shape[0]), np.zeros(np.array(neg_pixels).shape[0]), ) ) gaussian_msc_arc_X = np.vstack((gauss_msc_pos, gauss_msc_neg)) gaussian_msc_arc_Y = np.hstack( ( np.ones(np.array(gauss_msc_pos).shape[0]), np.zeros(np.array(gauss_msc_neg).shape[0]), ) ) return train_x, train_y, gaussian_msc_arc_X, gaussian_msc_arc_Y
def filtered_msc_training_kernel(image, persistence=8.5): pos_pixels = [] neg_pixels = [] gauss_msc_pos = [] gauss_msc_neg = [] # Compute the morse smale complex of all blurred images and filter # arcs of interest based on mu from gaussian fit to pixel histogram # for each image blurred_image, fname = blur_and_save(image, "filtered_msc_training_kernel") full_msc = build_msc( fname, blurred_image.shape[1], blurred_image.shape[0], persistence ) # mu, sigma, var = gaussian_fit(blurred_image) mu, _, _ = gaussian_fit(blurred_image) filtered_msc = msc_filtration(blurred_image, full_msc, mu) # Cover filtered MSC with closed balls to select negative space as # background and arcs as positive samples pos_samples, neg_samples = collect_training_from_filtered( blurred_image, filtered_msc, plot=True ) # a = np.array(neg_samples) # get pixel values under arc for positives for arc_pos in pos_samples: for point_pos in arc_pos: pos_pixels.append([image[int(point_pos[0]), int(point_pos[1])]]) # get negative pixel values for bg_group in neg_samples: for point_neg in bg_group: neg_pixels.append([image[int(point_neg[0]), int(point_neg[1])]]) # fit gaussian to negative pixel values in background and take mean, # deviation, variation for arc_neg in neg_samples: filtered_negatives = [] for point_neg in arc_neg: filtered_negatives.append( [image[int(point_neg[0]), int(point_neg[1])]] ) # fit gaussian to negative sample pixels in background mu_neg, sigma_neg, var_neg = gaussian_fit(np.array(filtered_negatives)) gauss_msc_neg.append([mu_neg, sigma_neg, var_neg]) # fit gaussian to positive pixel values under arcs of MSC and take # mean, standard deviation, and variances for arc in pos_samples: filtered_positives = [] for point in arc: filtered_positives.append([image[int(point[0]), int(point[1])]]) # fit gaussian to positive pixel values under arc and take mean, # standard deviation, and variance # NOTE! can filter based on arc length, currently doing three bc # three degrees of freedom in gaussian fit. if len(filtered_positives) >= 3: mu_pos, sigma_pos, var_pos = gaussian_fit( np.array(filtered_positives) ) gauss_msc_pos.append([mu_pos, sigma_pos, var_pos]) train_x = np.vstack((pos_pixels, neg_pixels)) train_y = np.hstack( ( np.ones(np.array(pos_pixels).shape[0]), np.zeros(np.array(neg_pixels).shape[0]), ) ) gaussian_msc_arc_X = np.vstack((gauss_msc_pos, gauss_msc_neg)) gaussian_msc_arc_Y = np.hstack( ( np.ones(np.array(gauss_msc_pos).shape[0]), np.zeros(np.array(gauss_msc_neg).shape[0]), ) ) return train_x, train_y, gaussian_msc_arc_X, gaussian_msc_arc_Y