Esempio n. 1
0
    def _resample_relative(
        self, inside: np.ndarray, outside: np.ndarray, bb: Roi
    ) -> Optional[np.ndarray]:
        offset = outside - inside
        with np.errstate(divide="ignore", invalid="ignore"):
            # bb_crossings will be 0 if inside is on the bb, 1 if outside is on the bb
            bb_x = np.asarray(
                [
                    (np.asarray(bb.get_begin()) - inside) / offset,
                    (np.asarray(bb.get_end() - Coordinate([1, 1, 1])) - inside)
                    / offset,
                ]
            )

            if np.sum(np.logical_and((bb_x > 0), (bb_x <= 1))) > 0:
                # all values of bb_x between 0, 1 represent a crossing of a bounding plane
                # the minimum of which is the (normalized) distance to the closest bounding plane
                s = np.min(bb_x[np.logical_and((bb_x > 0), (bb_x <= 1))])
                return Coordinate(np.floor(np.array(inside) + s * offset))
            else:
                logging.debug(
                    (
                        "Could not create a node on the bounding box {} "
                        + "given points (inside:{}, ouside:{})"
                    ).format(bb, inside, outside)
                )
                return None
Esempio n. 2
0
    def process(self, batch, request):

        points = batch.points[self.points]
        mask = self.settings.mask
        voxel_size = self.spec[self.array].voxel_size

        # get roi used for creating the new array (points_roi does no
        # necessarily align with voxel size)
        enlarged_vol_roi = points.spec.roi.snap_to_grid(voxel_size)
        offset = enlarged_vol_roi.get_begin() / voxel_size
        shape = enlarged_vol_roi.get_shape() / voxel_size
        data_roi = Roi(offset, shape)

        logger.debug("Points in %s", points.spec.roi)
        for i, point in points.data.items():
            logger.debug("%d, %s", i, point.location)
        logger.debug("Data roi in voxels: %s", data_roi)
        logger.debug("Data roi in world units: %s", data_roi*voxel_size)

        if len(points.data.items()) == 0:
            # If there are no points at all, just create an empty matrix.
            rasterized_points_data = np.zeros(data_roi.get_shape(),
                                              dtype=self.spec[self.array].dtype)
        elif mask is not None:

            mask_array = batch.arrays[mask].crop(enlarged_vol_roi)
            # get those component labels in the mask, that contain points
            labels = []
            for i, point in points.data.items():
                v = Coordinate(point.location / voxel_size)
                v -= data_roi.get_begin()
                labels.append(mask_array.data[v])
            # Make list unique
            labels = list(set(labels))

            # zero label should be ignored
            if 0 in labels:
                labels.remove(0)

            if len(labels) == 0:
                logger.debug("Points and provided object mask do not overlap. No points to rasterize.")
                rasterized_points_data = np.zeros(data_roi.get_shape(),
                                                  dtype=self.spec[self.array].dtype)
            else:
                # create data for the whole points ROI, "or"ed together over
                # individual object masks
                rasterized_points_data = np.sum(
                    [
                        self.__rasterize(
                            points,
                            data_roi,
                            voxel_size,
                            self.spec[self.array].dtype,
                            self.settings,
                            Array(data=mask_array.data==label, spec=mask_array.spec))

                        for label in labels
                    ],
                    axis=0)

        else:

            # create data for the whole points ROI without mask
            rasterized_points_data = self.__rasterize(
                points,
                data_roi,
                voxel_size,
                self.spec[self.array].dtype,
                self.settings)

        # fix bg/fg labelling if requested
        if (self.settings.bg_value != 0 or
            self.settings.fg_value != 1):

            replaced = replace(
                rasterized_points_data,
                [0, 1],
                [self.settings.bg_value, self.settings.fg_value])
            rasterized_points_data = replaced.astype(self.spec[self.array].dtype)

        # create array and crop it to requested roi
        spec = self.spec[self.array].copy()
        spec.roi = data_roi*voxel_size
        rasterized_points = Array(
            data=rasterized_points_data,
            spec=spec)
        batch.arrays[self.array] = rasterized_points.crop(request[self.array].roi)

        # restore requested ROI of points
        if self.points in request:
            request_roi = request[self.points].roi
            points.spec.roi = request_roi
            points.data = {i: p for i, p in points.data.items() if request_roi.contains(p.location)}

        # restore requested mask
        if mask is not None:
            batch.arrays[mask] = batch.arrays[mask].crop(request[mask].roi)