Computer Vision / Reproducible Research

Does brightening a dark photo help a model see it?

A course project once concluded that low-light enhancement gave barely any improvement. This rebuild shows that the answer was correct, yet it had been measured with a broken ruler. With a corrected evaluator and a sweep across six detector architectures, a clearer and more honest picture emerges.

00 / in motion

The pipeline, running

A fifty-second pass through the whole system, rendered by the project itself.

Low-light frames are enhanced in a before-and-after wipe, a detector draws its predictions box by box across a sped-up montage, and the run ends by printing the pooled COCO-style metrics. Nothing is mocked: the boxes and the numbers come from the real model and the real evaluator, computed on the exact images shown.

Stage one enhances the image, stage two draws the detector's predictions, stage three prints the metrics. Generated with python scripts/06_showcase.py.
01 / the problem

The original result could not be trusted

Not because the conclusion was wrong, but because the measurement was.

The starting point was a student project on the ExDark low-light dataset. It reported one precision, recall, and average precision triple per enhancement method. The numbers were nearly identical, so the takeaway became "enhancement does not help."

The deeper issue was that the evaluation could not have shown a difference either way. Three independent flaws made the experiment impossible to interpret, and a fourth quietly distorted the geometry of every image.

Four flaws, four fixes

The original conclusion happened to match reality, but it was a guess dressed as a result. The contribution here is making that conclusion trustworthy, and then discovering what the broken metric had hidden.
02 / approach

A research-grade benchmark

One reproducible pipeline that runs on any machine, choosing a GPU, Apple silicon, or the CPU automatically.

The framework rests on a correct evaluator that reports mAP at an IoU of 0.5, mAP averaged from 0.5 to 0.95, per-class average precision, and bootstrap confidence intervals. It is cross-checked against the Ultralytics validation routine. Six detectors run through a single adapter, spanning four generations of the YOLO family alongside the transformer-based RT-DETR. Twelve enhancement methods sit behind one interface, covering gamma, brightness and contrast, histogram methods, the Retinex family, white balance, and a dark channel prior.

Every result is deterministic. A seed-fixed, class-stratified split is committed to the repository, so each experiment draws from the identical partition.

One low-light frame under several enhancement methods
The same low-light frame under several enhancement methods. Some look far brighter to a person, yet looking better and detecting better turn out to be only loosely related.
Perceptual image quality plotted against detection accuracy
Perceptual quality plotted against detection accuracy. The weak relationship is the point. Enhancement tuned for the human eye is the wrong objective for a detector.
03 / finding one

On a frozen detector, enhancement is neutral

Every detector against every enhancement, on the same images, through the same evaluator.

The table reports mAP at an IoU of 0.5 for a detector that was never adapted to the enhanced images. The best value in each row is shown in green.

Detectororiginalgammaadapt-gbr/con hist-eqCLAHE-HSVCLAHE-LABgray-worldDCP
YOLOv8n0.5810.5470.5040.5400.4870.5740.5750.4910.530
YOLOv8s0.6520.6300.5810.6310.5450.6550.6640.5850.603
YOLO11n0.6320.6050.5500.6170.5210.6300.6340.5400.555
YOLOv5nu0.5480.5330.4770.5350.4750.5500.5520.4650.476
mAP at IoU 0.5, zero-shot COCO detectors, ExDark test subset, 15 images per class. These numbers reproduce on any device. Only throughput changes.

Averaged across all detectors

CLAHE on the LAB color space is the only method that beats doing nothing, and it wins by three thousandths of a point, which sits inside the bootstrap confidence interval. Everything else is neutral or harmful. Aggressive global brightening, such as histogram equalization and gray-world balancing, pushes the image away from the natural-photo statistics the detector expects, and accuracy falls.

Enhancementmean mAPchange vs original
CLAHE-LAB0.606+0.003
original0.6030.000
CLAHE-HSV0.602-0.001
brightness/contrast0.581-0.023
gamma0.579-0.025
DCP0.541-0.062
adaptive-gamma0.528-0.076
gray-world0.520-0.083
hist-eq0.507-0.096
Mean across the four detectors above.
Heatmap of detector against enhancement
The full detector against enhancement matrix as a heatmap. The original and CLAHE columns dominate, and the verdict holds across four architectures from three YOLO generations.
The conclusion is robust precisely because it holds across different kinds of model. It is not an artifact of one network. On a detector that never adapted to the enhanced domain, classical enhancement does not help.
finding two

The per-class wins were noise

A single model made enhancement look helpful for specific classes. It did not replicate.

On YOLOv8s alone, CLAHE on LAB appeared to lift several classes, with Bottle, Cat, and Dog each rising by a noticeable margin. It was tempting to call that a result.

Averaging each class across all four detectors tells a different story. Only Motorbike improves on every model. Every other class is mixed. Bottle rises on two detectors and falls on the other two, and Dog swings from a clear gain to a larger loss. That pattern is the fingerprint of sampling noise at fifteen images per class, not a real effect.

A correct evaluator does more than hand you the right number. It lets you tell a real effect from a lucky one. Checking a single-model finding against the other models is what turned a false positive into an honest null result.
Per-class average precision heatmap
Per-class average precision across enhancement methods. The recovered Cup and Boat rows now carry real signal, yet no enhancement consistently lifts any single class.
Ground truth boxes against predicted boxes
Ground-truth boxes in green against predicted boxes in orange, on held-out low-light images. Predictions are shown at a confidence of 0.25, the display threshold, rather than the much lower threshold used for scoring.
04 / what is next

The decisive experiment

Everything so far tests a frozen detector, which is the setting where enhancement is expected to be neutral. The real question needs the detector to learn the enhanced domain.

A model pretrained on ordinary photographs has never seen CLAHE-processed pixels, so feeding it enhanced images is an out-of-distribution test. The published literature shows enhancement pays off only when the detector is fine-tuned on the enhanced domain. The project ships a controlled comparison. It fine-tunes the same base model on original images and on enhanced images, holding the epochs, the split, and the seed identical, and changing only the pixels. It then evaluates a grid of training domain against test domain. The matched diagonal of that grid is the fair answer, and it runs on a GPU machine.

Context from the published record

MethodmAP at 0.5
Zero-shot COCO YOLOv30.21
Fine-tuned YOLOv3 baseline0.764
Zero-DCE plus YOLOv30.769
MAET, 20210.777
IAT-YOLO, 20220.778
PE-YOLO, 20230.780
Canonical ExDark numbers on the official split.

The entire four-year span of published results covers roughly 1.6 points of mAP, while fine-tuning alone is worth about 0.55. That ratio is the thesis. Adapt the detector, rather than polish the pixels.

Zero-shot against fine-tuned accuracy
Zero-shot against fine-tuned accuracy, illustrating the dominant lever. A clean GPU run replaces the earlier CPU placeholder.
05 / reproduce

One command, any platform

It runs on macOS, Windows, and Linux. The device is detected automatically, and the benchmark needs no GPU.

# environment
python -m venv venv
source venv/bin/activate      # windows: venv\Scripts\activate
pip install -r requirements.txt

# run the whole study
python run.py                 # full benchmark and report
python run.py --quick         # fast smoke test
python run.py --full          # six detectors, all twelve enhancers

# the decisive comparison, on a GPU machine
python run.py --stages domain report --domain --device auto \
  --domain-enhancers original clahe_lab --ft-epochs 100 --ft-fraction 1.0