Esempio n. 1
0
    def run_svm(self, score):
        """
        Trains and uses an SVM classifier.

        Trains an SVM classifier to distinguish between noise and particle projections based on
        mean intensity and variance. Every possible window in the micrograph is then classified
        as either noise or particle, resulting in a segmentation of the micrograph.

        Args:

            score: Matrix containing a score for each query image.

        Returns:
            Segmentation of the micrograph into noise and particle projections.
        """

        micro_img = xp.asarray(self.im)
        particle_windows = np.floor(self.tau1)
        non_noise_windows = np.ceil(self.tau2)
        bw_mask_p, bw_mask_n = Picker.get_maps(self, score, micro_img,
                                               particle_windows,
                                               non_noise_windows)

        x, y = PickerHelper.get_training_set(micro_img, bw_mask_p, bw_mask_n,
                                             self.query_size)
        x = xp.asnumpy(x)
        y = xp.asnumpy(y)

        scaler = preprocessing.StandardScaler()
        scaler.fit(x)
        x = scaler.transform(x)
        classifier = self.model
        classifier.fit(x, y)

        mean_all, std_all = PickerHelper.moments(micro_img, self.query_size)
        mean_all = xp.asnumpy(mean_all)
        std_all = xp.asnumpy(std_all)

        mean_all = mean_all[self.query_size - 1:-(self.query_size - 1),
                            self.query_size - 1:-(self.query_size - 1)]

        std_all = std_all[self.query_size - 1:-(self.query_size - 1),
                          self.query_size - 1:-(self.query_size - 1)]

        mean_all = np.reshape(mean_all, (np.prod(mean_all.shape), 1), 'F')
        std_all = np.reshape(std_all, (np.prod(std_all.shape), 1), 'F')
        cls_input = np.concatenate((mean_all, std_all), axis=1)
        cls_input = scaler.transform(cls_input)

        # compute classification for all possible windows in micrograph
        segmentation = classifier.predict(cls_input)

        _segmentation_shape = int(np.sqrt(segmentation.shape[0]))
        segmentation = np.reshape(segmentation,
                                  (_segmentation_shape, _segmentation_shape),
                                  'F')

        return segmentation.copy()
Esempio n. 2
0
    def query_score(self, show_progress=True):
        """Calculates score for each query image.

        Extracts query images and reference windows. Computes the cross-correlation between these
        windows, and applies a threshold to compute a score for each query image.

        Args:
            show_progress: Whether to show a progress bar

        Returns:
            Matrix containing a score for each query image.
        """

        micro_img = xp.asarray(self.im)
        logger.info('Extracting query images')
        query_box = PickerHelper.extract_query(micro_img, self.query_size // 2)
        logger.info('Extracting query images complete')

        query_box = xp.conj(xp.fft2(query_box, axes=(2, 3)))

        reference_box = PickerHelper.extract_references(micro_img, self.query_size, self.container_size)

        reference_size = PickerHelper.reference_size(micro_img, self.container_size)
        conv_map = xp.zeros((reference_size, query_box.shape[0], query_box.shape[1]))

        def _work(index):
            reference_box_i = xp.fft2(reference_box[index], axes=(0, 1))
            window_t = xp.multiply(reference_box_i, query_box)
            cc = xp.ifft2(window_t, axes=(2, 3))
            return index, cc.real.max((2, 3)) - cc.real.mean((2, 3))

        n_works = reference_size
        n_threads = config.apple.conv_map_nthreads
        pbar = tqdm(total=reference_size, disable=not show_progress)

        # Ideally we'd like something like 'SerialExecutor' to enable easy debugging
        # but for now do an if-else
        if n_threads > 1:
            with futures.ThreadPoolExecutor(n_threads) as executor:
                to_do = [executor.submit(_work, i) for i in range(n_works)]

                for future in futures.as_completed(to_do):
                    i, res = future.result()
                    conv_map[i, :, :] = res
                    pbar.update(1)
        else:
            for i in range(n_works):
                _, conv_map[i, :, :] = _work(i)
                pbar.update(1)

        pbar.close()

        conv_map = xp.transpose(conv_map, (1, 2, 0))

        min_val = xp.min(conv_map)
        max_val = xp.max(conv_map)
        thresh = min_val + (max_val - min_val) / config.apple.response_thresh_norm_factor
        return xp.asnumpy(xp.sum(conv_map >= thresh, axis=2))
Esempio n. 3
0
    def gaussian_filter(cls, size_filter, std):
        """Computes low-pass filter.

        Args:
            size_filter: Size of filter (size_filter x size_filter).
            std: sigma value in filter.
        """

        y, x = xp.mgrid[-(size_filter - 1) // 2: (size_filter - 1) // 2 + 1,
               -(size_filter - 1) // 2: (size_filter - 1) // 2 + 1]

        response = xp.exp(-xp.square(x) - xp.square(y) / (2 * (std ** 2))) / (xp.sqrt(2 * xp.pi) * std)
        response[response < xp.finfo('float').eps] = 0

        return xp.asnumpy(response / response.sum())  # Normalize so sum is 1