Пример #1
0
    def extract_windows(cls, img, block_size):
        """Extracts blocks of size (block_size x block_size) from the micrograph. Blocks are 
        extracted with steps of size (block_size)
        
        Args:
            img: Micrograph image.
            block_size: required block size.
            
        Returns:
            3D Matrix of blocks. For example, img[0] is the first block.
        """

        # keep only the portion of the image that can be split into blocks with no remainder
        img = xp.asarray(
            img[:-(img.shape[0] % block_size), :-(img.shape[1] % block_size)])

        dim3_size = np.sqrt(np.prod(img.shape) // (block_size**2)).astype(int)

        img = xp.reshape(img, (block_size, dim3_size, block_size, dim3_size),
                         'F')

        img = xp.transpose(img, (0, 2, 1, 3))
        img = xp.reshape(
            img, (img.shape[0] * img.shape[1], img.shape[2] * img.shape[3]),
            'F')

        return img
Пример #2
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()
Пример #3
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))
Пример #4
0
    def extract_query(cls, img, block_size):
        """Extract all query images from the micrograph. windows are 
        extracted with steps of size (block_size/2)
        
        Args:
            img: Micrograph image.
            block_size: Query images must be of size (block_size x block_size).
            
        Returns:
            4D Matrix of query images. 
        """

        # keep only the portion of the image that can be split into blocks with no remainder
        blocks = xp.asarray(
            img[:-(img.shape[0] % block_size), :-(img.shape[1] % block_size)])

        dim3_size = np.sqrt(np.prod(blocks.shape) //
                            (block_size**2)).astype(int)
        blocks = xp.reshape(blocks,
                            (block_size, dim3_size, block_size, dim3_size),
                            'F')

        blocks = xp.transpose(blocks, (0, 2, 1, 3))

        blocks = xp.reshape(blocks, (blocks.shape[0], blocks.shape[1], -1),
                            'F')

        blocks = xp.concatenate(
            (blocks,
             xp.concatenate(
                 (blocks[:, :, 1:],
                  xp.reshape(blocks[:, :, 0],
                             (blocks.shape[0], blocks.shape[1], 1), 'F')),
                 axis=2)),
            axis=0)

        temp = xp.concatenate(
            (blocks[:, :,
                    int(np.floor(2 * img.shape[1] / 2 / block_size)):],
             blocks[:, :, 0:int(np.floor(2 * img.shape[1] / 2 / block_size))]),
            axis=2)

        blocks = xp.concatenate((blocks, temp), axis=1)

        blocks = xp.reshape(blocks,
                            (2 * block_size, 2 * block_size,
                             int(np.floor(2 * img.shape[0] / 2 / block_size)),
                             int(np.floor(2 * img.shape[1] / 2 / block_size))),
                            'F')

        blocks = blocks[:, :, 0:blocks.shape[2] - 1, 0:blocks.shape[3] - 1]

        blocks = xp.transpose(blocks, (2, 3, 0, 1))

        return blocks
Пример #5
0
    def extract_references(cls, img, query_size, container_size):
        """Chooses and extracts reference images from the micrograph. 
        
        Args:
            img: Micrograph image.
            query_size: Reference images must be of the same size of query images, i.e. (query_size x query_size).
            container_size: Containers are large regions used to select reference images. The size of each 
            region is (container_size x container_size)
            
        Returns:
            3D Matrix of reference images.  windows[0] is the first reference window.
        """

        img = xp.asarray(img)
        num_containers_row = img.shape[0] // container_size
        num_containers_col = img.shape[1] // container_size

        windows = xp.zeros(
            (cls.reference_size(img, container_size), query_size, query_size))
        win_idx = 0

        mean_all, std_all = cls.moments(img, query_size)

        for y_contain in range(num_containers_row):
            for x_contain in range(num_containers_col):
                temp = img[y_contain *
                           container_size:min(img.shape[0], (y_contain + 1) *
                                              container_size), x_contain *
                           container_size:min(img.shape[1], (x_contain + 1) *
                                              container_size)]

                y_start = y_contain * container_size + query_size - 1
                y_end = min(mean_all.shape[0] - query_size,
                            (y_contain + 1) * container_size)

                x_start = x_contain * container_size + query_size - 1
                x_end = min(mean_all.shape[1] - query_size,
                            (x_contain + 1) * container_size)

                mean_contain = mean_all[y_start:y_end, x_start:x_end]
                std_contain = std_all[y_start:y_end, x_start:x_end]

                ind = xp.argmax(mean_contain)
                if ind.size == 1:
                    y, x = xp.unravel_index(ind, mean_contain.shape)
                    windows[win_idx, :, :] = temp[y:y + query_size,
                                                  x:x + query_size]
                    win_idx += 1

                ind = xp.argmin(mean_contain)
                if ind.size == 1:
                    y, x = xp.unravel_index(ind, mean_contain.shape)
                    windows[win_idx, :, :] = temp[y:y + query_size,
                                                  x:x + query_size]
                    win_idx += 1

                ind = xp.argmax(std_contain)
                if ind.size == 1:
                    y, x = xp.unravel_index(ind, std_contain.shape)
                    windows[win_idx, :, :] = temp[y:y + query_size,
                                                  x:x + query_size]
                    win_idx += 1

                ind = xp.argmin(std_contain)
                if ind.size == 1:
                    y, x = xp.unravel_index(ind, std_contain.shape)
                    windows[win_idx, :, :] = temp[y:y + query_size,
                                                  x:x + query_size]
                    win_idx += 1

        return windows