pdnl-process 0.4__tar.gz → 0.6__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pdnl_process-0.4 → pdnl_process-0.6}/PKG-INFO +2 -2
- {pdnl_process-0.4 → pdnl_process-0.6}/pdnl_process/main.py +39 -53
- {pdnl_process-0.4 → pdnl_process-0.6}/pyproject.toml +2 -2
- {pdnl_process-0.4 → pdnl_process-0.6}/.github/workflows/publish.yml +0 -0
- {pdnl_process-0.4 → pdnl_process-0.6}/.gitignore +0 -0
- {pdnl_process-0.4 → pdnl_process-0.6}/README.md +0 -0
- {pdnl_process-0.4 → pdnl_process-0.6}/pdnl_process/__init__.py +0 -0
|
@@ -23,6 +23,7 @@ def main():
|
|
|
23
23
|
parser.add_argument('-o', '--output_path', help="path to write outputs to", required=True)
|
|
24
24
|
parser.add_argument('-s', '--staining_code', help="stain protocol used to stain the input image", default='H-DAB')
|
|
25
25
|
parser.add_argument('-p', '--parameters_file', help=".json file containing processing parameters", default=None)
|
|
26
|
+
parser.add_argument('--debug_level', help="outputs extra files", default='normal')
|
|
26
27
|
args = parser.parse_args()
|
|
27
28
|
|
|
28
29
|
if args.parameters_file:
|
|
@@ -31,72 +32,51 @@ def main():
|
|
|
31
32
|
params = {}
|
|
32
33
|
|
|
33
34
|
os.makedirs(args.output_path, exist_ok=True)
|
|
34
|
-
|
|
35
|
-
# preprocess the chunks
|
|
36
|
-
# TODO: move all pdnl_sana.process code into here, then other scripts import these functions
|
|
37
|
-
print('Preprocessing chunks...', flush=True)
|
|
38
|
-
histogram = None
|
|
39
|
-
for d in tqdm(os.listdir(args.input_path)):
|
|
40
|
-
if not os.path.isdir(os.path.join(args.input_path, d)):
|
|
41
|
-
continue
|
|
42
|
-
|
|
43
|
-
i, j = list(map(int, d.split('_')))
|
|
44
35
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
36
|
+
# get the background image
|
|
37
|
+
# TODO: test how big the concatenated frame will be, and move to big roi mode if too big
|
|
38
|
+
rois = pdnl_sana.slide.concatenate_chunks(args.input_path)
|
|
39
|
+
for roi_name in rois:
|
|
40
|
+
frame, mask, frame_loc = rois[roi_name]
|
|
48
41
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
converter = pdnl_sana.geo.Converter(mpp, ds)
|
|
54
|
-
frame = pdnl_sana.image.Frame(os.path.join(in_d, 'frame.png'), level=level, converter=converter)
|
|
55
|
-
mask = pdnl_sana.image.Frame(os.path.join(in_d, 'mask.png'), level=level, converter=converter)
|
|
42
|
+
# TODO: move all pdnl_sana.process code into here, then other scripts import these functions
|
|
43
|
+
out_d = os.path.join(args.output_path, roi_name)
|
|
44
|
+
os.makedirs(out_d, exist_ok=True)
|
|
45
|
+
logger = pdnl_sana.logging.Logger(args.debug_level, os.path.join(out_d, 'log.pkl'))
|
|
56
46
|
|
|
57
|
-
|
|
47
|
+
# TODO: shouldn't be omitting the mask here, but leaving it here so all data is generated in the same way for now.
|
|
48
|
+
# this was a fix for the background code, but that code is solved now
|
|
58
49
|
if args.staining_code == 'H-DAB':
|
|
59
50
|
processor = pdnl_sana.process.HDABProcessor(
|
|
60
|
-
logger, frame,
|
|
51
|
+
logger, frame,
|
|
52
|
+
#main_mask=mask,
|
|
61
53
|
apply_smoothing=params.get('apply_smoothing', False),
|
|
62
54
|
normalize_background=params.get('normalize_background', False),
|
|
63
|
-
stain_vector=params.get('stain_vector', None)
|
|
55
|
+
stain_vector=params.get('stain_vector', None),
|
|
56
|
+
radius=200, overlap=0.5,
|
|
64
57
|
)
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
58
|
+
if args.staining_code == 'CV-DAB':
|
|
59
|
+
processor = pdnl_sana.process.CVDABProcessor(
|
|
60
|
+
logger, frame,
|
|
61
|
+
#main_mask=mask,
|
|
62
|
+
apply_smoothing=params.get('apply_smoothing', False),
|
|
63
|
+
normalize_background=params.get('normalize_background', False),
|
|
64
|
+
stain_vector=params.get('stain_vector', None)
|
|
65
|
+
)
|
|
66
|
+
hist = processor.dab.get_histogram(mask=processor.main_mask)
|
|
67
|
+
stain = processor.dab.copy()
|
|
68
|
+
stain.save(os.path.join(out_d, 'stain.npy'))
|
|
71
69
|
|
|
72
|
-
|
|
73
|
-
if not histogram is None:
|
|
70
|
+
# calculate the threshold
|
|
74
71
|
triangular_strictness = params.get('triangular_strictness', 0.0)
|
|
75
72
|
threshold = pdnl_sana.threshold.triangular_method(
|
|
76
|
-
|
|
73
|
+
hist,
|
|
77
74
|
strictness=triangular_strictness,
|
|
78
|
-
debug=True
|
|
79
75
|
)
|
|
80
|
-
else:
|
|
81
|
-
threshold = 0
|
|
82
|
-
|
|
83
|
-
minimum_threshold = params.get('minimum_threshold', 0)
|
|
84
|
-
if threshold < minimum_threshold:
|
|
85
|
-
threshold = minimum_threshold
|
|
86
76
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
if not os.path.isdir(os.path.join(args.input_path, d)):
|
|
91
|
-
continue
|
|
92
|
-
|
|
93
|
-
i, j = list(map(int, d.split('_')))
|
|
94
|
-
|
|
95
|
-
in_d = os.path.join(args.input_path, f'{i}_{j}')
|
|
96
|
-
out_d = os.path.join(args.output_path, f'{i}_{j}')
|
|
97
|
-
|
|
98
|
-
mask = pdnl_sana.image.Frame(os.path.join(in_d, 'mask.png'))
|
|
99
|
-
stain = pdnl_sana.image.Frame(os.path.join(out_d, 'stain.npy'))
|
|
77
|
+
minimum_threshold = params.get('minimum_threshold', 0)
|
|
78
|
+
if threshold < minimum_threshold:
|
|
79
|
+
threshold = minimum_threshold
|
|
100
80
|
|
|
101
81
|
stain.mask(mask)
|
|
102
82
|
stain.threshold(threshold)
|
|
@@ -105,12 +85,18 @@ def main():
|
|
|
105
85
|
for filt in morphology_filters:
|
|
106
86
|
stain.apply_morphology_filter(filt)
|
|
107
87
|
|
|
88
|
+
if args.debug_level in ['debug', 'full']:
|
|
89
|
+
frame.save(os.path.join(out_d, 'frame.png'))
|
|
90
|
+
|
|
91
|
+
if args.debug_level == 'full':
|
|
92
|
+
plt.show()
|
|
108
93
|
stain.save(os.path.join(out_d, 'pos.png'))
|
|
109
|
-
|
|
94
|
+
mask.save(os.path.join(out_d, 'mask.png'))
|
|
110
95
|
logger.data['triangular_strictness'] = triangular_strictness
|
|
111
96
|
logger.data['minimum_threshold'] = minimum_threshold
|
|
112
97
|
logger.data['morphology_filter'] = morphology_filters
|
|
113
98
|
logger.data['threshold'] = threshold
|
|
99
|
+
logger.data['frame_loc'] = frame_loc
|
|
114
100
|
logger.write_data()
|
|
115
101
|
|
|
116
102
|
if __name__ == "__main__":
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "pdnl_process"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.6"
|
|
8
8
|
authors = [
|
|
9
9
|
{ name="Noah Capp", email="noahmcapp@gmail.com" },
|
|
10
10
|
]
|
|
@@ -28,4 +28,4 @@ classifiers = [
|
|
|
28
28
|
Homepage = "https://github.com/PennCompPathology/pdnl_process"
|
|
29
29
|
|
|
30
30
|
[project.scripts]
|
|
31
|
-
pdnl_process = "pdnl_process:main"
|
|
31
|
+
pdnl_process = "pdnl_process:main"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|