skills/cv/dicom-voi-lut-preprocessing/SKILL.md
Read DICOM X-ray files with VOI LUT transformation and MONOCHROME1 inversion for correct pixel intensity rendering
npx skillsauth add wenmin-wu/ds-skills cv-dicom-voi-lut-preprocessingInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
X-ray DICOM files use Value of Interest (VOI) Lookup Tables to map stored pixel values to display-ready intensities. Some scanners store images as MONOCHROME1 (inverted — bright=air, dark=tissue), which must be flipped. Apply VOI LUT first, then fix photometric interpretation, then normalize to 0-255.
import numpy as np
import pydicom
from pydicom.pixel_data_handlers.util import apply_voi_lut
def read_xray(path, voi_lut=True, fix_monochrome=True):
"""Read and preprocess a DICOM X-ray image.
Args:
path: path to .dcm file
voi_lut: apply VOI LUT transform (recommended)
fix_monochrome: invert MONOCHROME1 images
Returns:
uint8 image array (0-255)
"""
dicom = pydicom.dcmread(path)
if voi_lut:
data = apply_voi_lut(dicom.pixel_array, dicom)
else:
data = dicom.pixel_array
if fix_monochrome and dicom.PhotometricInterpretation == "MONOCHROME1":
data = np.amax(data) - data
data = data - np.min(data)
data = data / np.max(data)
data = (data * 255).astype(np.uint8)
return data
img = read_xray("patient001.dcm")
data-ai
Scaled Pinball Loss (SPL) metric for evaluating quantile forecasts, normalized by mean absolute successive differences of training data
data-ai
Walk backward through a time series and multiplicatively rescale segments when jumps exceed a fraction of the running mean to correct data collection anomalies
testing
Transform forecasting target to next/current ratio minus one so that optimizing MAE or squared error implicitly minimizes SMAPE
tools
Convert point forecasts to prediction intervals by scaling with logit-transformed quantile ratios passed through a Normal CDF