File size: 4,115 Bytes
f272af0
0e6ebc7
 
 
f272af0
 
1ba3c27
e2ed139
f272af0
 
 
 
0e6ebc7
 
1ba3c27
 
0e6ebc7
 
 
f4170ee
0e6ebc7
 
1ba3c27
 
 
 
eab7c24
 
0e6ebc7
 
 
 
 
 
 
 
eab7c24
 
 
 
 
0e6ebc7
 
 
7bcce0f
0e6ebc7
 
 
 
 
7bcce0f
 
0e6ebc7
 
 
 
7bcce0f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
---
title: Image Cleanup
emoji: πŸ§‘β€πŸ”¬
colorFrom: pink
colorTo: yellow
sdk: gradio
sdk_version: 6.22.0
python_version: "3.12"
app_file: app.py
pinned: false
---

# Image cleanup

Script for detecting dark, low-saturation debris in IHC images and creating
exclusion masks plus OpenCV-inpainted QC previews.

```bash
uv sync
uv run python main.py data/example.png
```

PNG, JPEG, TIFF, and TIF inputs are supported. Inpainted QC images are written
to `out/cleaned/` with `_cleaned` added before the original extension, and
debris-exclusion masks are written to `out/masks/` as PNG files. Preserve the
original image and exclude masked pixels when quantifying DAB; do not quantify
the synthetic pixels in the inpainted QC image. TIFF outputs use lossless LZW
compression.

An optional Gradio interface is also available:

```bash
uv run python app.py
```

Open the local URL printed in the terminal, upload an input image, and select
**Create mask and QC preview**. TIFF previews and cleaned QC downloads use a
full-range 8-bit conversion, matching the notebook's display conversion. Debris
detection retains its separate processing conversion. A conservative background
fit corrects the cleaned QC image only when it detects meaningful edge falloff;
the uploaded source image and debris mask remain unchanged.

For batch processing, open the **Image directory** tab and select a folder.
The app processes all uploaded images, including `.tif` and `.tiff` files, and
returns a ZIP archive containing only the cleaned images.

Project layout:

- `main.py` β€” primary image-cleaning script
- `cleaning.py` β€” reusable cleaning operations
- `ihc_quantification_simplified.py` β€” per-spheroid DAB quantification
- `ihc_qc.py` β€” reusable segmentation, debris, and DAB QC drawing
- `app.py` β€” optional Gradio interface
- `data/` β€” source and example images
- `out/` β€” generated cleaned images and masks
- `test.ipynb` β€” image-cleaning experiments

## DAB quantification

`ihc_quantification_simplified.py` segments individual spheroids, excludes the
debris mask, separates H-DAB stains from the original image values, and writes
one CSV row per spheroid. Image metadata such as treatment, image number, and
an optional image note is extracted from the filename.

```bash
uv run python ihc_quantification_simplified.py data/dab_quantification_test
```

The input can be one TIFF image or a directory. Directories are searched
recursively. Results from all discovered images are combined in
`out/quantification/ihc_quantification.csv` by default. Each spheroid is one
row, so the table can be filtered or grouped by treatment in Excel or pandas.
One two-panel QC image per source image is saved in
`out/quantification/qc/`, showing the segmented spheroids, excluded debris,
and measured DAB signal. The DAB heatmap uses the same fixed `0-0.3` scale for
every image so its colors can be compared directly across the dataset.

Use `--output` to choose another CSV location:

```bash
uv run python ihc_quantification_simplified.py data/treatment_images \
  --output out/my_results.csv
```

With a custom output path, QC images are placed in a `qc/` directory beside
the CSV.

Experiment-sensitive boundary and watershed settings can be changed without
editing the script:

```bash
uv run python ihc_quantification_simplified.py data/treatment_images \
  --max-boundary-contact-ratio 0.3 \
  --watershed-marker-core-fraction 0.55 \
  --watershed-minimum-relative-region-area 0.3
```

A larger boundary-contact ratio tolerates more image-edge contact. Lowering
the minimum relative watershed-region area permits more uneven splits, such as
a complete spheroid touching a partially visible spheroid. The marker-core
fraction controls which distance-transform cores seed the watershed.

The QC image can also be created directly from a notebook:

```python
from ihc_qc import create_qc_image

qc = create_qc_image(preview, labels, debris_mask, dab)
```

Pass `dab_vmax` to use another fixed upper limit for a particular analysis:

```python
qc = create_qc_image(preview, labels, debris_mask, dab, dab_vmax=1.0)
```