Skip to content

Commit 4a9437f

Browse files
Merge branch 'main' into development
2 parents 6db513b + 204354f commit 4a9437f

File tree

28 files changed

+666
-42
lines changed

28 files changed

+666
-42
lines changed
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
---
2+
name: Bug report
3+
about: Create a report to help us improve
4+
title: ''
5+
labels: ''
6+
assignees: ''
7+
8+
---
9+
10+
**Describe the bug**
11+
A clear and concise description of what the bug is.
12+
13+
**To Reproduce**
14+
Steps to reproduce the behavior. Ideally a gist but a simple code example is also fine.
15+
16+
**Expected behavior**
17+
A clear and concise description of what you expected to happen.
18+
19+
**Logs**
20+
If applicable, add sufficient logs to assist in debugging the problem.
21+
22+
**Screenshots**
23+
If applicable, add screenshots to help explain your problem.
24+
25+
**Desktop (please complete the following information):**
26+
- OS: [e.g. Ubuntu, Windows, macOS]
27+
- Version [e.g. 20.04, 10, Catalina]
28+
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
---
2+
name: Feature request
3+
about: Suggest an idea for this project
4+
title: ''
5+
labels: ''
6+
assignees: ''
7+
8+
---
9+
10+
**Is your feature request related to a problem? Please describe.**
11+
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12+
13+
**Describe the solution you'd like**
14+
A clear and concise description of what you want to happen.
15+
16+
**Describe alternatives you've considered**
17+
A clear and concise description of any alternative solutions or features you've considered.
18+
19+
**Additional context**
20+
Add any other context or screenshots about the feature request here.

.github/workflows/build.yaml

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@ jobs:
1515
python-version: '3.x'
1616

1717
- name: Install deps
18-
run: |
19-
pip install setuptools wheel
18+
run: pip install setuptools wheel
2019

2120
- name: Build wheels
2221
run: python setup.py sdist bdist_wheel
@@ -37,8 +36,8 @@ jobs:
3736
name: artifact
3837
path: dist
3938

40-
- uses: pypa/gh-action-pypi-publish@v1.5.0
39+
- uses: pypa/gh-action-pypi-publish@release/v1.12
4140
with:
4241
user: __token__
4342
password: ${{ secrets.torchstain_deploy_token }}
44-
43+

.github/workflows/tests_full.yml

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ jobs:
3939
runs-on: ${{ matrix.os }}
4040
strategy:
4141
matrix:
42-
os: [ windows-2019, ubuntu-20.04, macos-11 ]
42+
os: [ windows-2019, ubuntu-20.04, macos-12 ]
4343
python-version: [ 3.7, 3.8, 3.9 ]
4444
tf-version: [2.7.0, 2.8.0, 2.9.0]
4545

@@ -51,17 +51,16 @@ jobs:
5151
python-version: ${{ matrix.python-version }}
5252

5353
- name: Download artifact
54-
uses: actions/download-artifact@master
54+
uses: actions/download-artifact@v3
5555
with:
5656
name: "Python wheel"
5757

5858
- name: Install dependencies
59-
run: |
60-
pip install tensorflow==${{ matrix.tf-version }} protobuf==3.20.* opencv-python-headless scikit-image
61-
pip install pytest
59+
run: pip install tensorflow==${{ matrix.tf-version }} protobuf==3.20.* opencv-python-headless scikit-image pytest
6260

6361
- name: Install wheel
64-
run: pip install --find-links=${{github.workspace}} torchstain
62+
run: pip install --find-links=${{github.workspace}} torchstain-*
63+
shell: bash
6564

6665
- name: Run tests
6766
run: pytest -vs tests/test_tf.py
@@ -71,7 +70,7 @@ jobs:
7170
runs-on: ${{ matrix.os }}
7271
strategy:
7372
matrix:
74-
os: [ windows-2019, ubuntu-20.04, macos-11 ]
73+
os: [ windows-2019, ubuntu-20.04, macos-12 ]
7574
python-version: [ 3.6, 3.7, 3.8, 3.9 ]
7675
pytorch-version: [1.8.0, 1.9.0, 1.10.0, 1.11.0, 1.12.0, 1.13.0]
7776
exclude:
@@ -90,17 +89,16 @@ jobs:
9089
python-version: ${{ matrix.python-version }}
9190

9291
- name: Download artifact
93-
uses: actions/download-artifact@master
92+
uses: actions/download-artifact@v3
9493
with:
9594
name: "Python wheel"
9695

9796
- name: Install dependencies
98-
run: |
99-
pip install torch==${{ matrix.pytorch-version }} torchvision opencv-python-headless scikit-image
100-
pip install pytest
97+
run: pip install torch==${{ matrix.pytorch-version }} torchvision opencv-python-headless scikit-image pytest
10198

10299
- name: Install wheel
103-
run: pip install --find-links=${{github.workspace}} torchstain
100+
run: pip install --find-links=${{github.workspace}} torchstain-*
101+
shell: bash
104102

105103
- name: Run tests
106104
run: pytest -vs tests/test_torch.py

.github/workflows/tests_quick.yml

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -43,24 +43,23 @@ jobs:
4343
python-version: 3.8
4444

4545
- name: Download artifact
46-
uses: actions/download-artifact@master
46+
uses: actions/download-artifact@v3
4747
with:
4848
name: "Python wheel"
4949

5050
- name: Install dependencies
51-
run: |
52-
pip install tensorflow protobuf==3.20.* opencv-python-headless scikit-image
53-
pip install pytest
51+
run: pip install tensorflow protobuf==3.20.* opencv-python-headless scikit-image pytest
5452

5553
- name: Install wheel
56-
run: pip install --find-links=${{github.workspace}} torchstain
54+
run: pip install --find-links=${{github.workspace}} torchstain-*
55+
shell: bash
5756

5857
- name: Run tests
5958
run: pytest -vs tests/test_tf.py
6059

6160
test-torch:
6261
needs: build
63-
runs-on: ubuntu-18.04
62+
runs-on: ubuntu-20.04
6463

6564
steps:
6665
- uses: actions/checkout@v1
@@ -70,17 +69,16 @@ jobs:
7069
python-version: 3.8
7170

7271
- name: Download artifact
73-
uses: actions/download-artifact@master
72+
uses: actions/download-artifact@v3
7473
with:
7574
name: "Python wheel"
7675

7776
- name: Install dependencies
78-
run: |
79-
pip install torch torchvision opencv-python-headless scikit-image
80-
pip install pytest
77+
run: pip install torch torchvision opencv-python-headless scikit-image pytest
8178

8279
- name: Install wheel
83-
run: pip install --find-links=${{github.workspace}} torchstain
80+
run: pip install --find-links=${{github.workspace}} torchstain-*
81+
shell: bash
8482

8583
- name: Run tests
8684
run: pytest -vs tests/test_torch.py

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
[![License](https://img.shields.io/badge/License-MIT-green.svg)](https://opensource.org/licenses/MIT)
44
[![tests](https://github.com/EIDOSLAB/torchstain/workflows/tests/badge.svg)](https://github.com/EIDOSLAB/torchstain/actions)
55
[![Pip Downloads](https://img.shields.io/pypi/dm/torchstain?label=pip%20downloads&logo=python)](https://pypi.org/project/torchstain/)
6-
[![DOI](https://zenodo.org/badge/323590093.svg)](https://zenodo.org/badge/latestdoi/323590093)
6+
[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.7692014.svg)](https://doi.org/10.5281/zenodo.7692014)
77

88
GPU-accelerated stain normalization tools for histopathological images. Compatible with PyTorch, TensorFlow, and Numpy.
99
Normalization algorithms currently implemented:
@@ -38,8 +38,8 @@ T = transforms.Compose([
3838
transforms.Lambda(lambda x: x*255)
3939
])
4040

41-
torch_normalizer = torchstain.normalizers.MacenkoNormalizer(backend='torch')
42-
torch_normalizer.fit(T(target))
41+
normalizer = torchstain.normalizers.MacenkoNormalizer(backend='torch')
42+
normalizer.fit(T(target))
4343

4444
t_to_transform = T(to_transform)
4545
norm, H, E = normalizer.normalize(I=t_to_transform, stains=True)

apps/example_aug.py

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
import cv2
2+
import matplotlib.pyplot as plt
3+
import torchstain
4+
import torch
5+
from torchvision import transforms
6+
import time
7+
import os
8+
9+
10+
size = 1024
11+
dir_path = os.path.dirname(os.path.abspath(__file__))
12+
target = cv2.resize(cv2.cvtColor(cv2.imread(dir_path + "/../data/target.png"), cv2.COLOR_BGR2RGB), (size, size))
13+
to_transform = cv2.resize(cv2.cvtColor(cv2.imread(dir_path + "/../data/source.png"), cv2.COLOR_BGR2RGB), (size, size))
14+
15+
T = transforms.Compose([
16+
transforms.ToTensor(),
17+
transforms.Lambda(lambda x: x*255)
18+
])
19+
20+
t_to_transform = T(to_transform)
21+
22+
# setup augmentors for the different backends
23+
augmentor = torchstain.augmentors.MacenkoAugmentor(backend='numpy')
24+
augmentor.fit(to_transform)
25+
26+
tf_augmentor = torchstain.augmentors.MacenkoAugmentor(backend='tensorflow')
27+
tf_augmentor.fit(t_to_transform)
28+
29+
torch_augmentor = torchstain.augmentors.MacenkoAugmentor(backend='torch')
30+
torch_augmentor.fit(t_to_transform)
31+
32+
33+
print("NUMPY" + "-"*20)
34+
35+
plt.figure()
36+
plt.suptitle('numpy augmentor')
37+
plt.subplot(4, 4, 1)
38+
plt.title('Original')
39+
plt.axis('off')
40+
plt.imshow(to_transform)
41+
42+
for i in range(16):
43+
# generate augmented sample
44+
result = augmentor.augment()
45+
46+
plt.subplot(4, 4, i + 1)
47+
if i == 1:
48+
plt.title('Augmented ->')
49+
plt.axis('off')
50+
plt.imshow(result)
51+
52+
plt.show()
53+
54+
55+
print("TensorFlow (TF)" + "-"*20)
56+
57+
plt.figure()
58+
plt.suptitle('tf augmentor')
59+
plt.subplot(4, 4, 1)
60+
plt.title('Original')
61+
plt.axis('off')
62+
plt.imshow(to_transform)
63+
64+
for i in range(16):
65+
# generate augmented sample
66+
result = tf_augmentor.augment()
67+
68+
plt.subplot(4, 4, i + 1)
69+
if i == 1:
70+
plt.title('Augmented ->')
71+
plt.axis('off')
72+
plt.imshow(result)
73+
74+
plt.show()
75+
76+
77+
print("Torch" + "-"*20)
78+
79+
plt.figure()
80+
plt.suptitle('torch augmentor')
81+
plt.subplot(4, 4, 1)
82+
plt.title('Original')
83+
plt.axis('off')
84+
plt.imshow(to_transform)
85+
86+
for i in range(16):
87+
# generate augmented sample
88+
result = torch_augmentor.augment()
89+
90+
plt.subplot(4, 4, i + 1)
91+
if i == 1:
92+
plt.title('Augmented ->')
93+
plt.axis('off')
94+
plt.imshow(result)
95+
96+
plt.show()

example.py renamed to apps/example_norm.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@
44
import torch
55
from torchvision import transforms
66
import time
7+
import os
78

89
size = 1024
9-
target = cv2.resize(cv2.cvtColor(cv2.imread("./data/target.png"), cv2.COLOR_BGR2RGB), (size, size))
10-
to_transform = cv2.resize(cv2.cvtColor(cv2.imread("./data/source.png"), cv2.COLOR_BGR2RGB), (size, size))
10+
dir_path = os.path.dirname(os.path.abspath(__file__))
11+
target = cv2.resize(cv2.cvtColor(cv2.imread(dir_path + "/../data/target.png"), cv2.COLOR_BGR2RGB), (size, size))
12+
to_transform = cv2.resize(cv2.cvtColor(cv2.imread(dir_path + "/../data/source.png"), cv2.COLOR_BGR2RGB), (size, size))
1113

1214
normalizer = torchstain.normalizers.MacenkoNormalizer(backend='numpy')
1315
normalizer.fit(target)

torchstain/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
__version__ = '1.3.0'
22

3-
from torchstain.base import normalizers
3+
from torchstain.base import augmentors, normalizers

torchstain/base/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
from torchstain.base import normalizers
1+
from torchstain.base import augmentors, normalizers

0 commit comments

Comments
 (0)