| --- |
| title: Image Quantization and CT Windowing Explorer |
| emoji: 🩻 |
| colorFrom: blue |
| colorTo: gray |
| sdk: docker |
| app_port: 8501 |
| pinned: false |
| --- |
| |
| # Image Quantization and CT Windowing Explorer |
|
|
| An interactive Streamlit app for exploring how quantization and CT-style windowing change grayscale medical image display. |
|
|
| ## Screenshots / GIF |
|
|
| ### Main app overview |
|
|
|  |
|
|
|
|
| ## Project Summary |
|
|
| This app compares two related but different operations on grayscale medical images: |
|
|
| 1. Quantization reduces the number of stored gray levels and can introduce banding or reconstruction error. |
| 2. Windowing changes only how a chosen intensity range is displayed and clips values outside that range. |
|
|
| The interface lets users adjust bit depth and window bounds, then compare four image states, a histogram, an error map, and summary metrics side by side. |
|
|
| ## Local Run |
|
|
| ```bash |
| cd medical-quantization-windowing-explorer |
| make setup |
| source .venv/bin/activate |
| make run |
| ``` |
|
|
| Or run without activating: |
|
|
| ```bash |
| uv run streamlit run app.py |
| ``` |
|
|
| ## Hugging Face Space URL |
|
|
| For the most stable viewing experience, use the direct app URL: |
| https://huggingkatze-ct-windowing-quantization-demo.hf.space |
|
|
| The Hugging Face project page is: |
| https://huggingface.co/spaces/HuggingKatze/ct-windowing-quantization-demo |
|
|
| ## Repository Structure |
|
|
| ```text |
| app.py |
| processing.py |
| metrics.py |
| utils.py |
| sample_images/ |
| sample_images/builtin_samples/ |
| docs/ |
| requirements.txt |
| Makefile |
| Dockerfile |
| ``` |
|
|
| ## Features |
|
|
| - Built-in CT-oriented examples from CT-RATE, LDCT-and-Projection-data, and RSNA PE |
| - Upload support for `PNG`, `JPG`, `JPEG`, and single-slice `DICOM` |
| - Automatic handling of grayscale images, including 3-channel grayscale copies |
| - Adjustable quantization bit depth and CT-style window bounds |
| - Slice selection for volumetric built-in samples |
| - Rotation control for uploaded DICOM slices |
| - Four synchronized views: original, windowed, quantized, and quantized + windowed |
| - Histogram, squared-error map, and summary metrics (`MSE`, `PSNR`, gray levels, entropy) |
| - Clickable comparison arrows synchronized with the metrics selector |
| - In-app explanatory notes for each main control |
|
|
| ## Known Limitations |
|
|
| - The app is educational and not intended for clinical interpretation. |
| - Uploaded PNG/JPG images may already be restricted to 8-bit precision. |
| - The current version works on one 2D slice at a time. |
| - Uploaded files are limited to PNG/JPG and single-slice DICOM in the current app; NIfTI upload is not enabled in the active UI. |
| - The CT-RATE built-in sample is rotated 90 degrees clockwise in the app to match the expected viewing orientation. |
| - Public deployment should still respect the original dataset licenses and redistribution terms for bundled sample content. |
|
|
| ## Interface Guide |
|
|
| - **Input source** switches between prepared built-in examples and your own uploaded data. |
| - **Built-in sample** lets you compare different CT-oriented datasets quickly. |
| - **Slice index** appears for volumetric built-in inputs and chooses the active axial slice. |
| - **Rotate uploaded image** appears for uploaded DICOM data when the slice orientation needs correction. |
| - **Quantization bit depth** controls how many gray levels remain after uniform quantization. |
| - The app initializes the quantization display at 4 bits by default, unless the loaded image has a lower maximum bit depth. |
| - **CT window preset** applies common lower/upper bound pairs such as lung or mediastinal ranges. |
| - **Window lower / upper bounds** and the numeric bound inputs define the exact displayed intensity interval. |
| - **Histogram** uses the selected window bounds as reference lines and is meant to show how quantization changes the intensity distribution, rather than to faithfully plot the post-windowed display mapping. |
| - **Visualization arrows** can be clicked to choose which pair of panels should be compared. |
| - **Metrics → Compare** is synchronized with the arrow graph and updates all downstream plots. |
|
|
| ## Design Notes |
|
|
| See [docs/design_choices.md](docs/design_choices.md). |
|
|