diff --git a/src/napari_imagej/_napari_converters.py b/src/napari_imagej/_napari_converters.py index 02ba4ed6..3b26e048 100644 --- a/src/napari_imagej/_napari_converters.py +++ b/src/napari_imagej/_napari_converters.py @@ -260,11 +260,11 @@ def _napari_to_java_converters(ij) -> List[Converter]: ] -def _java_to_napari_converters() -> List[Converter]: +def _java_to_napari_converters(ij) -> List[Converter]: return [ Converter( predicate=lambda obj: isinstance(obj, ImgLabeling), - converter=_imglabeling_to_layer, + converter=lambda obj: _imglabeling_to_layer(ij, obj), priority=Priority.VERY_HIGH ), Converter( @@ -382,5 +382,5 @@ def init_napari_converters(ij): add_java_converter(converter) # Add Java -> napari converters - for converter in _java_to_napari_converters(): + for converter in _java_to_napari_converters(ij): add_py_converter(converter) diff --git a/src/napari_imagej/_ntypes.py b/src/napari_imagej/_ntypes.py index d948dae6..97d8a562 100644 --- a/src/napari_imagej/_ntypes.py +++ b/src/napari_imagej/_ntypes.py @@ -18,5 +18,5 @@ def _layer_to_labeling(layer: Labels): labeling.metadata = metadata["metadata"] return labeling else : - return Labeling.fromValues(layer.data, layer.data.shape) + return Labeling.fromValues(layer.data) \ No newline at end of file diff --git a/src/napari_imagej/_tests/test_ntypes.py b/src/napari_imagej/_tests/test_ntypes.py index 6b46971c..206d53c4 100644 --- a/src/napari_imagej/_tests/test_ntypes.py +++ b/src/napari_imagej/_tests/test_ntypes.py @@ -8,7 +8,7 @@ from labeling.Labeling import Labeling from napari.layers import Labels, Shapes -@pytest.fixture() +@pytest.fixture(scope="module") def ij_fixture(): return imagej.init() @@ -42,10 +42,31 @@ def py_labeling() -> Labeling: return merger @pytest.fixture(scope="module") -def labels_layer(py_labeling: Labeling) -> Labels: +def labels_with_metadata(py_labeling: Labeling) -> Labels: + img, data = py_labeling.get_result() + return Labels(img, metadata={"pyLabelingData": data}) + +@pytest.fixture(scope="module") +def labels_without_metadata(py_labeling: Labeling) -> Labels: img, _ = py_labeling.get_result() return Labels(img) +@pytest.fixture(scope="module") +def imgLabeling(ij_fixture): + img = np.zeros((4, 4), dtype=np.int32) + img[:2, :2] = 6 + img[:2, 2:] = 3 + img[2:, :2] = 7 + img[2:, 2:] = 4 + img_java = ij_fixture.py.to_java(img) + sets = [[], [1], [2], [1, 2], [2, 3], [3], [1, 4], [3, 4]] + sets = [set(l) for l in sets] + sets_java = ij_fixture.py.to_java(sets) + + ImgLabeling = jimport("net.imglib2.roi.labeling.ImgLabeling") + return ImgLabeling.fromImageAndLabelSets(img_java, sets_java) + + def test_labeling_circular_equality(py_labeling): expected: Labeling = py_labeling actual: Labeling = _layer_to_labeling(_labeling_to_layer(py_labeling)) @@ -80,15 +101,77 @@ def test_labels_to_labeling(py_labeling): act_img, _ = labeling.get_result() assert np.array_equal(exp_img, act_img) -def test_labels_to_imgLabeling(ij_fixture, labels_layer): +def test_labels_with_metadata_to_imgLabeling(ij_fixture, labels_with_metadata): ImgLabeling = jimport('net.imglib2.roi.labeling.ImgLabeling') - converted: ImgLabeling = ij_fixture.py.to_java(labels_layer) - exp_img: np.ndarray= labels_layer.data + converted: ImgLabeling = ij_fixture.py.to_java(labels_with_metadata) + exp_img: np.ndarray= labels_with_metadata.data act_img: np.ndarray = ij_fixture.py.from_java(converted.getIndexImg()) - breakpoint() assert np.array_equal(exp_img, act_img) +def test_labels_with_metadata_circular(ij_fixture, labels_with_metadata): + ImgLabeling = jimport('net.imglib2.roi.labeling.ImgLabeling') + converted: ImgLabeling = ij_fixture.py.to_java(labels_with_metadata) + converted_back: Labels = ij_fixture.py.from_java(converted) + exp_img: np.ndarray = labels_with_metadata.data + act_img: np.ndarray = converted_back.data + assert np.array_equal(exp_img, act_img) + + +def _assert_image_mapping(exp_img: np.ndarray, act_img: np.ndarray) -> Dict[int, int]: + """ + Asserts a CONSISTENT mapping between values in exp_img and act_img. + + i.e. if + exp_img[x, y] = a and act_img[x, y] = b for any x,y + then + np.where(exp_img == a) == np.where(act_img == b) + + :param exp_img: the first image + :param act_img: the second image + :return: the mappings of a -> b + """ + mapping: Dict[int, int] = {} + for e_x, a_x in zip(exp_img, act_img): + for e, a in zip(e_x, a_x): + if e in mapping: + assert mapping[e] == a + else: + mapping[e] = a + return mapping + + +def test_labels_without_metadata_to_imgLabeling(ij_fixture, labels_without_metadata): + ImgLabeling = jimport('net.imglib2.roi.labeling.ImgLabeling') + converted: ImgLabeling = ij_fixture.py.to_java(labels_without_metadata) + exp_img: np.ndarray= labels_without_metadata.data + act_img: np.ndarray = ij_fixture.py.from_java(converted.getIndexImg()) + # We cannot assert image equality due to https://github.com/Labelings/Labeling/issues/16 + # So we do the next best thing + _assert_image_mapping(exp_img, act_img) + + +def test_labels_without_metadata_circular(ij_fixture, labels_without_metadata): + ImgLabeling = jimport('net.imglib2.roi.labeling.ImgLabeling') + converted: ImgLabeling = ij_fixture.py.to_java(labels_without_metadata) + converted_back: Labels = ij_fixture.py.from_java(converted) + exp_img: np.ndarray = labels_without_metadata.data + act_img: np.ndarray = converted_back.data + # We cannot assert image equality due to https://github.com/Labelings/Labeling/issues/16 + # So we do the next best thing + _assert_image_mapping(exp_img, act_img) + + +def test_imgLabeling_to_labels(ij_fixture, imgLabeling): + converted: Labels = ij_fixture.py.from_java(imgLabeling) + exp_img: np.ndarray = ij_fixture.py.from_java(imgLabeling.getIndexImg()) + act_img: np.ndarray= converted.data + # We cannot assert image equality due to https://github.com/Labelings/Labeling/issues/16 + # So we do the next best thing + _assert_image_mapping(exp_img, act_img) + + + # -- SHAPES / ROIS -- #