Example #1
0
    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