55import tensorflow as tf
66import numpy as np
77
8+
89def test_cov ():
910 x = np .random .randn (10 , 10 )
1011 cov_np = np .cov (x )
1112 cov_t = torchstain .tf .utils .cov (x )
1213
1314 np .testing .assert_almost_equal (cov_np , cov_t .numpy ())
1415
16+
1517def test_percentile ():
1618 x = np .random .randn (10 , 10 )
1719 p = 20
@@ -20,6 +22,7 @@ def test_percentile():
2022
2123 np .testing .assert_almost_equal (p_np , p_t )
2224
25+
2326def test_macenko_tf ():
2427 size = 1024
2528 curr_file_path = os .path .dirname (os .path .realpath (__file__ ))
@@ -48,6 +51,7 @@ def test_macenko_tf():
4851 # assess whether the normalized images are identical across backends
4952 np .testing .assert_almost_equal (result_numpy .flatten (), result_tf .flatten (), decimal = 2 , verbose = True )
5053
54+
5155def test_reinhard_tf ():
5256 size = 1024
5357 curr_file_path = os .path .dirname (os .path .realpath (__file__ ))
@@ -75,3 +79,37 @@ def test_reinhard_tf():
7579
7680 # assess whether the normalized images are identical across backends
7781 np .testing .assert_almost_equal (result_numpy .flatten (), result_tf .flatten (), decimal = 2 , verbose = True )
82+
83+
84+ def test_multistain_tf ():
85+ size = 1024
86+ curr_file_path = os .path .dirname (os .path .realpath (__file__ ))
87+ target = cv2 .resize (cv2 .cvtColor (cv2 .imread (os .path .join (curr_file_path , "../data/target.png" )), cv2 .COLOR_BGR2RGB ), (size , size ))
88+ to_transform = cv2 .resize (cv2 .cvtColor (cv2 .imread (os .path .join (curr_file_path , "../data/source.png" )), cv2 .COLOR_BGR2RGB ), (size , size ))
89+
90+ # setup preprocessing and preprocess image to be normalized
91+ T = lambda x : tf .convert_to_tensor (np .moveaxis (x , - 1 , 0 ).astype ("float32" )) # * 255
92+ t_to_transform = T (to_transform )
93+ target_transformed = T (target )
94+
95+ # move channel to first
96+ target_numpy = np .moveaxis (target , - 1 , 0 )
97+ to_transform_numpy = np .moveaxis (to_transform , - 1 , 0 )
98+
99+ # initialize normalizers for each backend and fit to target image
100+ normalizer = torchstain .normalizers .MultiMacenkoNormalizer (backend = 'numpy' )
101+ normalizer .fit ([target_numpy , target_numpy , target_numpy ])
102+
103+ tf_normalizer = torchstain .normalizers .MultiMacenkoNormalizer (backend = 'tensorflow' )
104+ tf_normalizer .fit ([target_transformed , target_transformed , target_transformed ])
105+
106+ # transform
107+ result_numpy , _ , _ = normalizer .normalize (I = to_transform_numpy , stains = True )
108+ result_tf , _ , _ = tf_normalizer .normalize (I = t_to_transform , stains = True )
109+
110+ # convert to numpy and set dtype
111+ result_numpy = result_numpy .astype ("float32" ) / 255.
112+ result_tf = result_tf .numpy ().astype ("float32" ) / 255.
113+
114+ # assess whether the normalized images are identical across backends
115+ np .testing .assert_almost_equal (result_numpy .flatten (), result_tf .flatten (), decimal = 2 , verbose = True )
0 commit comments