Blind, palette-constrained color correction for print-scan degraded color barcodes. acePC estimates a 3×3 color-correction matrix (CCM) and offset directly from a single scanned image — no reference tiles, no device calibration, no multi-illuminant training — by exploiting the known discrete color palette as an implicit reference.
This repository contains the core evaluation code used to test acePC against seven classical enhancement baselines on a large-scale print-scan color barcode dataset.
acepc.py— core acePC implementation: center-crop tile-color estimation, LAB clustering, Hungarian centroid-to-palette matching, dynamically-regularized Ridge CCM fitting, and CCM inversion.enhancement.py— the 9 evaluated methods (Standard + 7 baselines- acePC), the single source of truth for method names and functions.
run_versions.py— the main evaluation engine: runs all 9 methods across print-scan cycles and synthetic shift levels, computing classification accuracy, SNR/PSNR/MSE, pixel-level and tile-level Delta E, per-color accuracy, confusion matrices, and CCM diagnostics.lambda_sensitivity.py— hyperparameter sweep for acePC's dynamic Ridge regularization strength.verify_nonnegativity_ablation.py— empirical verification of the CCM non-negativity constraint's effect on accuracy and fit quality.
| Method | Description |
|---|---|
| Standard | No enhancement, raw scan |
| acePC | Proposed: blind palette-constrained CCM estimation |
| GHE_PC | Per-channel global histogram equalization |
| GHE_gray | Grayscale-based global histogram equalization |
| GHE_y | YCrCb luma-channel histogram equalization |
| CLAHE | Contrast-limited adaptive histogram equalization (Lab space) |
| Gamma | Gamma correction (γ=1.5) |
| UniformHSV | Fixed HSV saturation/value gain |
| GrayWorld | Gray-world white balance |
Each barcode is a 6×6 grid of 36 color tiles drawn from an 8-color palette. acePC:
- Extracts the center-crop mean color of each tile.
- Clusters tile colors in perceptual LAB space (k = palette size).
- Matches cluster centroids to palette entries via the Hungarian algorithm on mean-centered RGB distances.
- Fits a 3×3 CCM + offset via non-negative Ridge regression, with a penalty that scales dynamically with fit quality:
lambda_ridge = lambda_0 * (1 - mean_R^2) ^ exponent
- Applies the inverse CCM to every pixel, correcting the acquisition shift before downstream color classification.
All classification, SNR/PSNR, and Delta-E metrics are computed over the full 36-tile grid.
Pixel-level Delta E compares each method's full-resolution enhanced output against a fixed, unenhanced reference. Because the original and scanned source images can have different native resolutions, both sides are resized to a common 360×360 canvas (60×60 pixels per tile) before comparison — the same canvas size acePC's own preprocessing assumes. This keeps every method on equal footing and additionally captures intra-tile effects (e.g. boundary color bleeding) that tile-mean comparisons wash out.
numpy
opencv-python
scikit-learn
scipy
pandas
The dataset accompanying this code — 10,010 print-scan color barcode images across three cumulative print-scan cycles, ground-truth labels, and a pre-computed tile-color cache — is published separately on Zenodo and Kaggle:
- Zenodo: https://doi.org/10.5281/zenodo.21791460
- Kaggle: https://www.kaggle.com/datasets/ozancmert62/acepc-dataset-color-barcode-images
Each barcode is a 6×6 grid of 36 color tiles drawn from an 8-color palette. The dataset starts from 2,002 original barcode images, each printed and scanned across 5 different devices, with the scanned output itself re-printed and re-scanned across the same 5 devices for two further cycles — three cumulative print-scan degradation cycles in total.
If you use this code, please cite:
Adaptive Color Enhancement via Palette-Constrained CCM Estimation for Robust Color Classification, 2026.
This code is released under the MIT License. See LICENSE for details.
The accompanying dataset (Zenodo/Kaggle) is released separately under CC BY 4.0.