Exemple #1
0
def test_allocation():
    arr = Array5D.allocate(Slice5D.zero(x=slice(100, 200), y=slice(200, 300)), numpy.uint8)
    assert arr.shape == Shape5D(x=100, y=100)
    assert arr.location == Point5D.zero(x=100, y=200)

    arr = Array5D.allocate(Slice5D.zero(x=slice(-100, 200), y=slice(200, 300)), numpy.uint8)
    assert arr.shape == Shape5D(x=300, y=100)
    assert arr.location == Point5D.zero(x=-100, y=200)
Exemple #2
0
    def to_z_slice_pngs(self) -> Iterator[io.BytesIO]:
        for z_slice in self.split(self.shape.updated(z=1)):
            print(f"\nz_slice: {z_slice}")
            rendered_rgb = Array5D.allocate(z_slice.shape.updated(c=3),
                                            dtype=np.dtype("float32"),
                                            value=0)
            rendered_rgb_yxc = rendered_rgb.raw("yxc")

            for prediction_channel, color in zip(
                    z_slice.split(z_slice.shape.updated(c=1)),
                    self.channel_colors):
                print(f"\nprediction_channel: {prediction_channel}")

                class_rgb = Array5D(np.ones(
                    prediction_channel.shape.updated(c=3).to_tuple("yxc")),
                                    axiskeys="yxc")
                class_rgb.raw("yxc")[...] *= np.asarray(
                    [color.r, color.g, color.b]) * (color.a / 255)
                class_rgb.raw("cyx")[...] *= prediction_channel.raw("yx")

                rendered_rgb_yxc += class_rgb.raw("yxc")

            out_image = PIL.Image.fromarray(
                rendered_rgb.raw("yxc").astype(np.uint8))  # type: ignore
            out_file = io.BytesIO()
            out_image.save(out_file, "png")
            out_file.seek(0)
            yield out_file
Exemple #3
0
    def from_json_value(cls, data: JsonValue) -> "Annotation":
        data_dict = ensureJsonObject(data)
        raw_voxels = ensureJsonArray(data_dict.get("voxels"))
        voxels: Sequence[Point5D] = [
            Point5D.from_json_value(raw_voxel) for raw_voxel in raw_voxels
        ]

        color = Color.from_json_data(data_dict.get("color"))
        raw_data = DataSource.from_json_value(data_dict.get("raw_data"))

        start = Point5D.min_coords(voxels)
        stop = Point5D.max_coords(
            voxels
        ) + 1  # +1 because slice.stop is exclusive, but max_point isinclusive
        scribbling_roi = Interval5D.create_from_start_stop(start=start,
                                                           stop=stop)
        if scribbling_roi.shape.c != 1:
            raise ValueError(
                f"Annotations must not span multiple channels: {voxels}")
        scribblings = Array5D.allocate(scribbling_roi,
                                       dtype=np.dtype(bool),
                                       value=False)

        for voxel in voxels:
            scribblings.paint_point(point=voxel, value=True)

        return cls(scribblings._data,
                   axiskeys=scribblings.axiskeys,
                   color=color,
                   raw_data=raw_data,
                   location=start)
Exemple #4
0
    def _do_predict(self, roi: DataRoi) -> Predictions:
        feature_data = self.feature_extractor.compute(roi)

        predictions = Array5D.allocate(
            interval=self.get_expected_roi(roi),
            dtype=np.dtype('float32'),
            value=0,
        )
        assert predictions.interval == self.get_expected_roi(roi)
        raw_linear_predictions: np.ndarray = predictions.linear_raw()

        def do_predict(forest: VigraRandomForest):
            return forest.predictProbabilities(
                feature_data.linear_raw()) * forest.treeCount()

        with ThreadPoolExecutor(max_workers=len(self.forests),
                                thread_name_prefix="predictor") as executor:
            for forest_predictions in executor.map(do_predict, self.forests):
                raw_linear_predictions += forest_predictions

        raw_linear_predictions /= self.num_trees
        predictions.setflags(write=False)

        return Predictions(
            arr=predictions.raw(predictions.axiskeys),
            axiskeys=predictions.axiskeys,
            location=predictions.location,
            channel_colors=Color.sort(self.color_map.keys()),
        )
Exemple #5
0
    def interpolate_from_points(cls, color: Color, voxels: Sequence[Point5D],
                                raw_data: DataSource):
        start = Point5D.min_coords(voxels)
        stop = Point5D.max_coords(
            voxels
        ) + 1  # +1 because slice.stop is exclusive, but max_point isinclusive
        scribbling_roi = Interval5D.create_from_start_stop(start=start,
                                                           stop=stop)
        if scribbling_roi.shape.c != 1:
            raise ValueError(
                f"Annotations must not span multiple channels: {voxels}")
        scribblings = Array5D.allocate(scribbling_roi,
                                       dtype=np.dtype(bool),
                                       value=False)

        anchor = voxels[0]
        for voxel in voxels:
            for interp_voxel in anchor.interpolate_until(voxel):
                scribblings.paint_point(point=interp_voxel, value=True)
            anchor = voxel

        return cls(scribblings._data,
                   axiskeys=scribblings.axiskeys,
                   color=color,
                   raw_data=raw_data,
                   location=start)
Exemple #6
0
 def merge(annotations: Sequence["Annotation"],
           color_map: Optional[Dict[Color, np.uint8]] = None) -> Array5D:
     out_roi = Interval5D.enclosing(annot.interval for annot in annotations)
     out = Array5D.allocate(interval=out_roi,
                            value=0,
                            dtype=np.dtype('uint8'))
     color_map = color_map or Color.create_color_map(
         annot.color for annot in annotations)
     for annot in annotations:
         out.set(annot.colored(color_map[annot.color]), mask_value=0)
     return out
Exemple #7
0
 def _allocate(self, roi: Union[Shape5D, Slice5D], fill_value: int) -> Array5D:
     return Array5D.allocate(roi, dtype=self.dtype, value=fill_value)
Exemple #8
0
 def _allocate(self, interval: Union[Shape5D, Interval5D],
               fill_value: int) -> Array5D:
     return Array5D.allocate(interval, dtype=self.dtype, value=fill_value)
Exemple #9
0
def test_sequence_datasource():
    # fmt: off
    img1_data = Array5D(np.asarray([[[100, 101, 102, 103, 104],
                                     [105, 106, 107, 108, 109],
                                     [110, 111, 112, 113, 114],
                                     [115, 116, 117, 118, 119]],
                                    [[120, 121, 122, 123, 124],
                                     [125, 126, 127, 128, 129],
                                     [130, 131, 132, 133, 134],
                                     [135, 136, 137, 138, 139]],
                                    [[140, 141, 142, 143, 144],
                                     [145, 146, 147, 148, 149],
                                     [150, 151, 152, 153, 154],
                                     [155, 156, 157, 158, 159]]]),
                        axiskeys="cyx")

    img2_data = Array5D(np.asarray([[[200, 201, 202, 203, 204],
                                     [205, 206, 207, 208, 209],
                                     [210, 211, 212, 213, 214],
                                     [215, 216, 217, 218, 219]],
                                    [[220, 221, 222, 223, 224],
                                     [225, 226, 227, 228, 229],
                                     [230, 231, 232, 233, 234],
                                     [235, 236, 237, 238, 239]],
                                    [[240, 241, 242, 243, 244],
                                     [245, 246, 247, 248, 249],
                                     [250, 251, 252, 253, 254],
                                     [255, 256, 257, 258, 259]]]),
                        axiskeys="cyx")

    img3_data = Array5D(np.asarray([[[300, 301, 302, 303, 304],
                                     [305, 306, 307, 308, 309],
                                     [310, 311, 312, 313, 314],
                                     [315, 316, 317, 318, 319]],
                                    [[320, 321, 322, 323, 324],
                                     [325, 326, 327, 328, 329],
                                     [330, 331, 332, 333, 334],
                                     [335, 336, 337, 338, 339]],
                                    [[340, 341, 342, 343, 344],
                                     [345, 346, 347, 348, 349],
                                     [350, 351, 352, 353, 354],
                                     [355, 356, 357, 358, 359]]]),
                        axiskeys="cyx")

    expected_x_2_4__y_1_3 = Array5D(np.asarray([
        [[[107, 108], [112, 113]], [[127, 128], [132, 133]],
         [[147, 148], [152, 153]]],
        [[[207, 208], [212, 213]], [[227, 228], [232, 233]],
         [[247, 248], [252, 253]]],
        [[[307, 308], [312, 313]], [[327, 328], [332, 333]],
         [[347, 348], [352, 353]]],
    ]),
                                    axiskeys="zcyx")
    # fmt: on
    slice_x_2_4__y_1_3 = Slice5D(x=slice(2, 4), y=slice(1, 3))

    urls = [
        # create_n5(img1_data, axiskeys="cyx"),
        create_h5(img1_data, axiskeys_style="dims", axiskeys="cyx"),
        # create_n5(img2_data, axiskeys="cyx"),
        create_h5(img2_data, axiskeys_style="dims", axiskeys="cyx"),
        # create_n5(img3_data, axiskeys="cyx"),
        create_h5(img3_data, axiskeys_style="dims", axiskeys="cyx"),
    ]

    seq_ds = SequenceDataSource(urls, stack_axis="z")
    assert seq_ds.shape == Shape5D(x=5, y=4, c=3, z=3)
    data = seq_ds.retrieve(slice_x_2_4__y_1_3)
    assert (expected_x_2_4__y_1_3.raw("xyzc") == data.raw("xyzc")).all()

    seq_ds = SequenceDataSource(urls, stack_axis="z")
    data = seq_ds.retrieve(slice_x_2_4__y_1_3)
    assert (expected_x_2_4__y_1_3.raw("xyzc") == data.raw("xyzc")).all()

    seq_ds = SequenceDataSource(urls, stack_axis="c")
    expected_c = sum([img1_data.shape.c, img2_data.shape.c, img3_data.shape.c])
    assert seq_ds.shape == img1_data.shape.with_coord(c=expected_c)

    cstack_data = Array5D.allocate(Shape5D(x=5, y=4, c=expected_c),
                                   dtype=img1_data.dtype)
    cstack_data.set(img1_data.translated(Point5D.zero(c=0)))
    cstack_data.set(img2_data.translated(Point5D.zero(c=3)))
    cstack_data.set(img3_data.translated(Point5D.zero(c=6)))
    assert seq_ds.shape == cstack_data.shape

    expected_data = cstack_data.cut(slice_x_2_4__y_1_3)
    data = seq_ds.retrieve(slice_x_2_4__y_1_3)
    assert (expected_data.raw("cxy") == data.raw("cxy")).all()
Exemple #10
0
 def enlarged(self, radius: Point5D, limits: Interval5D) -> "ConnectedComponents":
     """Enlarges the array by 'radius', and fills this halo with zero"""
     haloed_roi = self.interval.enlarged(radius).clamped(limits)
     haloed_data = Array5D.allocate(haloed_roi, value=0, dtype=self.dtype)
     haloed_data.set(self)
     return ConnectedComponents.from_array5d(haloed_data, labels=self.labels)