torchstain icon indicating copy to clipboard operation
torchstain copied to clipboard

MultiMacenkoNormalizer

Open yuvfried opened this issue 1 year ago • 8 comments

Hi,

I came across the following reference to MultiMacenkoNormalizer in the paper "MULTI-TARGET STAIN NORMALIZATION FOR HISTOLOGY SLIDES":

SOFTWARE IMPLEMENTATION We make our implementation available in the torchstain2 normalization library. Our method is contained in the MultiMacenkoNormalizer class. A code snippet is presented below.

from torchstain.normalizers import *

# Sample random images
ref_images = sample_random_images(dataset, N)

# Initialize and fit the normalizer
normalizer = MultiMacenkoNormalizer('avg-post')
normalizer.fit(ref_images)

# Normalize an image
img = next(iter(dataset))
norm, _, _ = normalizer.normalize(img)

Could you please direct me to the location of the implementation of the MultiMacenkoNormalizer class within the repository? I would appreciate any guidance on where I can find the corresponding code.

Thank you!

yuvfried avatar Dec 29 '24 11:12 yuvfried

@carloalbertobarbano

andreped avatar Dec 29 '24 13:12 andreped

Just merged here https://github.com/EIDOSLAB/torchstain/blob/main/torchstain/torch/normalizers/multitarget.py should work with torch :)

carloalbertobarbano avatar Jan 07 '25 21:01 carloalbertobarbano

@carloalbertobarbano Unfortunately, there seems to be a bug making it challenging for me to use it. I opened a PR to make it working, at least similarly to the other methods. See PR https://github.com/EIDOSLAB/torchstain/pull/64.

andreped avatar Jan 13 '25 12:01 andreped

Should be fixed in the development branch in commit https://github.com/EIDOSLAB/torchstain/commit/7c2a95f87fd5f61c4647e271af7d0cbcaa80e813 you should be able to install it with

pip3 install git+https://github.com/EIDOSLAB/torchstain.git@development

Example usage:

target = cv2.resize(cv2.cvtColor(cv2.imread(os.path.join(curr_file_path, "../data/target.png")), cv2.COLOR_BGR2RGB), (size, size))
to_transform = cv2.resize(cv2.cvtColor(cv2.imread(os.path.join(curr_file_path, "../data/source.png")), cv2.COLOR_BGR2RGB), (size, size))

# setup preprocessing and preprocess image to be normalized
T = transforms.Compose([
    transforms.ToTensor(),
    transforms.Lambda(lambda x: x * 255)
])
target = T(target)
t_to_transform = T(to_transform)

multi_normalizer = torchstain.normalizers.MultiMacenkoNormalizer(backend="torch", norm_mode="avg-post")
multi_normalizer.fit([target, target, target])

result_multi, _, _ = multi_normalizer.normalize(I=t_to_transform, stains=True)

of course instead of [target, target, target] you are supposed to open multiple reference images

carloalbertobarbano avatar Jan 13 '25 12:01 carloalbertobarbano

@carloalbertobarbano Oh, this fit([target, target, target]) was new to me.

Why don't we just do .fit(target) and move this special case handling inside the specific MultiMacenkoNormalizer.fit()?

I argue that it should be as easy as possible for the user to use this method, and that it should follow the same API, as much as possible, for all normalizers.

andreped avatar Jan 13 '25 13:01 andreped

Because it is supposed to work with multiple different reference images, so .fit should take an array

carloalbertobarbano avatar Jan 13 '25 13:01 carloalbertobarbano

Because it is supposed to work with multiple different reference images, so .fit should take an array

Aaah, makes sense. Thanks for the clarification. But then after this is merged, I will make a PR to extend this to the different backends, and add the appropriate tests.

andreped avatar Jan 13 '25 13:01 andreped

@carloalbertobarbano Created PR https://github.com/EIDOSLAB/torchstain/pull/66 to add support for the missing NumPy and TensorFlow backends :]

Seems to work! At least new tests pass, indicating that we reach the same result as for PyTorch backend.

andreped avatar Jan 14 '25 12:01 andreped