Spaces:
Running
A newer version of the Gradio SDK is available: 6.25.0
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.
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:
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 scriptcleaning.pyβ reusable cleaning operationsihc_quantification_simplified.pyβ per-spheroid DAB quantificationihc_qc.pyβ reusable segmentation, debris, and DAB QC drawingapp.pyβ optional Gradio interfacedata/β source and example imagesout/β generated cleaned images and maskstest.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.
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:
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:
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:
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:
qc = create_qc_image(preview, labels, debris_mask, dab, dab_vmax=1.0)