--- 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 ![Main app overview](screenshots/demo_overview.gif) ## 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).