Example #1
0
def test_downsampling_image_produces_correct_resolution_and_data_shape(
        from_resolution, to_resolution):
    image = Image(channels=np.arange(24).reshape(1, 6, 4),
                  resolution_um=from_resolution)
    image2 = image.resample(resolution_um=to_resolution)
    assert image2.resolution_um == to_resolution
    assert image2.num_channels == image.num_channels  # don't want to lose original channels

    scale_ratio = from_resolution / to_resolution
    assert approx(image.width * scale_ratio == image2.width, abs=1)
    assert approx(image.height * scale_ratio == image2.height, abs=1)
Example #2
0
def test_resolution_matrix_matches_resolution(r):
    image = Image(channels=np.empty((2, 11, 13)), resolution_um=r)
    expected = np.array([
        [r, 0, 0, 0],
        [0, r, 0, 0],
        [0, 0, 1, 0],
        [0, 0, 0, 1],
    ])
    npt.assert_almost_equal(image.resolution_matrix, expected)
Example #3
0
def test_full_shift_matrix_is_height_and_width_of_image(width, height):
    image = Image(channels=np.empty(shape=(2, height, width)))
    expected = np.array([
        [1, 0, 0, height],
        [0, 1, 0, width],
        [0, 0, 1, 0],
        [0, 0, 0, 1],
    ])
    npt.assert_equal(image.full_shift_matrix, expected)
Example #4
0
def test_inds_homog_example():
    image = Image(channels=np.empty(shape=(3, 2, 3)))
    expected = np.array([
        [0, 0, 0, 1, 1, 1],
        [0, 1, 2, 0, 1, 2],
        [0, 0, 0, 0, 0, 0],
        [1, 1, 1, 1, 1, 1],
    ])
    npt.assert_equal(image.inds_homog, expected)
Example #5
0
 def slice_atlas(self) -> Image:
     """The Image that results from a slice through the Atlas with Section's transforms and dimensions."""
     si = self.section.image
     width, height = si.width, si.height
     inds = si.inds_homog.astype(float)
     atlas_inds = self.image_to_volume_transform @ inds
     atlas_inds = atlas_inds[:3, :]  # grab just ijk coords
     atlas_inds = atlas_inds.astype(np.int32)  # round to nearest integer, for indexing
     brightness_3d = _fancy_index_3d_numba(volume=self.atlas.volume, inds=atlas_inds.T)
     atlas_slice = Image(channels=brightness_3d.reshape(1, height, width), resolution_um=self.section.image.resolution_um)
     return atlas_slice
Example #6
0
def test_shift_matrix_is_ij_ordered_and_in_pixel_coordinate_space(width, height, j_shift, i_shift, theta):
    section = Section.create(
        image=Image(channels=np.empty((2, height, width)), resolution_um=99,),
        image_transform=ImageTransformer(i_shift=i_shift, j_shift=j_shift, theta=theta)
    )
    expected_shift_matrix = np.array([
        [1, 0, 0, i_shift * height],
        [0, 1, 0, j_shift * width],
        [0, 0, 1, 0],
        [0, 0, 0, 1]
    ])
    expected_image_transform = section.image_transform.rot_matrix @ expected_shift_matrix
    npt.assert_almost_equal(section._image_transform_matrix, expected_image_transform)
Example #7
0
def test_section_registration_cuts_correctly_with_diff_resolutions(case):
    volume = np.zeros((3, 3, 3))
    volume[1, 1, 1] = 1
    registration = Registration(section=Section.create(
        image=Image(channels=np.empty((1, 3, 3)),
                    resolution_um=case["section_res"]),
        physical_transform=PhysicalTransformer(**case["pos"]),
    ),
                                atlas=Atlas(
                                    volume=volume,
                                    resolution_um=case['atlas_res'],
                                ))
    atlas_slice = registration.slice_atlas()
    npt.assert_almost_equal(atlas_slice.channels[0], case['expected'])
Example #8
0
    def __call__(self, filename: str, resolution: Optional[float] = None) -> Result[LoadImageData, str]:

        image_filename = read_quicknii_xml(filename).image_path if Path(filename).suffix == '.xml' else filename

        image_data = self._image_reader.read(filename=image_filename)
        if image_data is None:
            return Err("Image failed to load.")

        resolution = resolution if isinstance((resolution := image_data.resolution_um), float) else 1.
        image = Image(channels=image_data.channels, resolution_um=resolution)
        image = image.resample(resolution_um=10)

        section = Section.create(
            image=image,
            image_transform=ImageTransformer(i_shift=-0.5, j_shift=-0.5)
        )

        self._repo.save_section(section=section)
        return Ok(LoadImageData(
            section_id=section.id,
            section_image=section.image.channels[0],
            resolution_um=image.resolution_um,
            num_channels=image.num_channels,
        ))
Example #9
0
def test_section_registration_to_an_atlas_gets_an_image_with_same_image_parameters(
):
    registration = Registration(
        section=Section.create(
            image=Image(channels=np.empty((3, 4, 5)), resolution_um=10),
            image_transform=ImageTransformer(i_shift=3, j_shift=5, theta=20),
            physical_transform=PhysicalTransformer(x=10,
                                                   y=-5,
                                                   z=10,
                                                   rx=20,
                                                   ry=0,
                                                   rz=-5),
        ),
        atlas=Atlas(volume=np.empty((5, 5, 5)), resolution_um=20),
    )

    atlas_slice = registration.slice_atlas()
    assert type(atlas_slice) is Image
    assert atlas_slice.width == 5 and atlas_slice.height == 4
Example #10
0
def test_can_get_3d_position_from_2d_pixel_coordinate_in_section(i, j, i_shift, j_shift, theta, x, y, z, res):
    section = Section.create(
        image=Image(channels=np.empty((2, 3, 4)), resolution_um=res),
        image_transform=ImageTransformer(i_shift=i_shift, j_shift=j_shift, theta=theta),
        physical_transform=PhysicalTransformer(x=x, y=y, z=z),
    )

    t = -radians(theta)  # image is left-handed, so flip rotation
    xyz = section.map_ij_to_xyz(i=i, j=j)  # observed 3D positions

    # do shift first, to make final 2d rotation calculation easier https://academo.org/demos/rotation-about-point/
    j2 = (j + (j_shift * section.image.width))
    i2 = (-i - (i_shift * section.image.height))

    expected = (
        (j2 * cos(t) + i2 * sin(t)) * res + x,
        (i2 * cos(t) - j2 * sin(t)) * res + y,
        z,
    )
    assert approx(xyz == expected)
Example #11
0
def test_section_creates_an_identical_registration_image_from_the_original_upon_construction():
    section = Section.create(image=Image(np.empty((2, 10, 10)), resolution_um=10))
    assert section.image == section.registration_image
Example #12
0
def test_downsampling_beyond_dimensions_produces_valueerror(to_resolution):
    image = Image(channels=np.arange(24).reshape(1, 4, 6), resolution_um=12)
    with pytest.raises(ValueError, match=r".* positive.*"):
        image.resample(resolution_um=to_resolution)
Example #13
0
def test_inds_homog_has_correct_shape(chans, height, width):
    image = Image(channels=np.random.random(size=(chans, height, width)))
    assert image.inds_homog.shape == (4, height * width)
Example #14
0
def test_image_reports_correct_dimensions(chans, height, width):
    image = Image(channels=np.random.random(size=(chans, height, width)))
    assert image.num_channels == chans
    assert image.height == height
    assert image.width == width