ColorCast
ColorCast is a Python toolkit for color and style transfer between images. It provides histogram matching, mean/std transfer, LUT-based curves (linear, S-curve, contrast), and selective regional color transfer across shadows, midtones, and highlights. Color-vision-deficiency simulation covers deuteranopia, protanopia, and tritanopia; the Daltonization pipeline re-encodes the chromatic information these deficiencies would otherwise hide, shifting it into a channel the affected observer can still perceive.
Features
Core Capabilities
- 9 Transfer Methods - Choose from multiple algorithms for different effects
- Intensity Control - Smooth slider (0-100%) to blend between original and styled images
- Selective Regional Transfer - Target shadows, midtones, or highlights specifically
- Modular Package - Use as Python API or run GUI/CLI
- Performance Optimized - LRU caching and batch processing support
- Tested - 75% test coverage with 361 passing tests
- Documented - API documentation and examples
- Plugin Architecture - Easy to add custom transfer methods
Transfer Methods
- Histogram Matching - Classic histogram equalization, preserves local contrast
- Mean/Std Transfer - Statistical color matching using mean and standard deviation
- Lab Color Transfer (Reinhard) - Industry-standard perceptually uniform color transfer in Lab* space
- LUT + Linear Curve - Histogram matching with linear tone mapping
- LUT + S-Curve - Adds smooth contrast enhancement to histogram matching
- LUT + Contrast - Increases overall contrast with power curve
- Selective: Shadows - Transfers colors only in dark regions (luminance < 0.3)
- Selective: Midtones - Transfers colors only in mid-tones (0.3 to 0.7)
- Selective: Highlights - Transfers colors only in bright regions (luminance > 0.7)
Interface
The ColorCast interface: content image, style image, and result panels
Daltonize (P) mode correcting an image for protanopia, with correction intensity control
CVD Accessibility Dashboard: side-by-side simulations and error maps for all three deficiency types
Method comparison: ranked results across multiple metrics and transfer algorithms
Full dashboard report summarizing simulation results and Daltonization efficacy
Installation
From PyPI (Recommended)
Install ColorCast using pip:
pip install colorcast
For GPU support (requires CUDA):
pip install colorcast[gpu]
From Source
# Clone the repository
git clone https://github.com/MichailSemoglou/ColorCast.git
cd ColorCast
# Create a virtual environment (recommended)
python -m venv .venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
# Install the package
pip install -e .
# For development with all dependencies
pip install -e ".[dev]"
# For GPU support (requires CUDA)
pip install -e ".[gpu]"
Requirements
- Python 3.10+
- NumPy >= 1.20.0
- scikit-image >= 0.19.0
- PyQt5 >= 5.15.0 (for GUI)
- scipy >= 1.7.0
See pyproject.toml for complete dependency specifications.
Usage
1. GUI Application
Run the graphical interface:
colorcast-gui
Or use the package entry point:
python -m colorcast
Step-by-step:
- Select Transfer Method: Choose from 15 methods at the top: 9 transfer algorithms, 3 color-vision-deficiency simulators, and 3 Daltonization corrections
- Load Content Image: Click to select your base image
- Load Style Image: Click to select the image whose style you want to copy (not required for simulator and correction modes)
- Apply Style Transfer: Click to process the images
- Adjust Intensity: Use the slider to control effect strength (0-100%)
- Save Result: Export your final image in your preferred format
- Clear Images: Reset and start over with new images
2. Command-Line Interface
Basic color transfer:
colorcast transfer content.jpg style.jpg -o output.jpg
With method and intensity:
colorcast transfer content.jpg style.jpg -o output.jpg -m meanstd -i 0.7
Simulate a color-vision deficiency (no style image needed):
colorcast transfer content.jpg -m simulate_protanopia -o output.png
Batch process directory:
colorcast batch ./content_dir style.jpg -o ./output_dir
List available methods:
colorcast list-methods
Get package information:
colorcast info --version
CLI Options:
-m, --method: Transfer method (histogram, meanstd, lab_reinhard, lut_linear, lut_scurve, lut_contrast, selective_shadows, selective_midtones, selective_highlights, simulate_protanopia, simulate_deuteranopia, simulate_tritanopia, daltonize_protanopia, daltonize_deuteranopia, daltonize_tritanopia)-i, --intensity: Blend intensity 0.0-1.0-w, --workers: Number of parallel workers (default: 4)-p, --pattern: File pattern to match (default: *.jpg)
3. Python API
from colorcast import load_image, match_histograms_multichannel, save_image
# Load images
content = load_image("content.jpg")
style = load_image("style.jpg")
# Apply histogram matching
result = match_histograms_multichannel(content, style)
# Save result
save_image(result, "output.jpg")
Using Different Methods
from colorcast import (
load_image,
color_transfer_meanstd,
color_transfer_lab,
lut_transfer_with_curve,
selective_color_transfer,
blend_images,
save_image,
)
content = load_image("content.jpg")
style = load_image("style.jpg")
# Mean/Std transfer
result1 = color_transfer_meanstd(content, style)
# Lab color transfer (Reinhard method)
result_lab = color_transfer_lab(content, style, alpha=0.8)
# LUT with S-curve
result2 = lut_transfer_with_curve(content, style, "s-curve")
# Selective shadows transfer
result3 = selective_color_transfer(content, style, mode="shadows")
# Blend with 70% intensity
final = blend_images(content, result2, intensity=0.7)
save_image(final, "output.jpg")
Using the Plugin Registry
from colorcast import load_image, registry
# List available methods
methods = registry.list_methods()
print(f"Available methods: {methods}")
# Get method and use it
content = load_image("content.jpg")
style = load_image("style.jpg")
method = registry.get_method("histogram")
result = method.transfer(content, style)
Batch Processing
from colorcast.processing.batch import BatchProcessor
from colorcast import match_histograms_multichannel
# Create batch processor
processor = BatchProcessor(
transfer_method=match_histograms_multichannel,
max_workers=4,
)
# Process directory
results = processor.process_directory(
content_dir="./content_images",
style_image="style.jpg",
output_dir="./output",
pattern="*.jpg",
)
# Check for failed files
if processor.failed_files:
print(f"Failed to process {len(processor.failed_files)} files")
Using Caching
from colorcast.processing.cache import StyleTransferCache
# Create cache
cache = StyleTransferCache(max_size=100)
# Use cache for expensive operations
result = cache.get_or_compute(
key="transfer_key",
compute_func=lambda: match_histograms_multichannel(content, style),
)
# Get cache statistics
stats = cache.stats()
print(f"Cache hits: {stats['hits']}, misses: {stats['misses']}")
Tips for Best Results
Choosing the Right Method
- Histogram Matching: Best for artistic effects and dramatic color shifts
- Mean/Std Transfer: Better for subtle, natural-looking color grading
- Lab Color Transfer (Reinhard): Industry-standard method for professional color grading with perceptually uniform results
- LUT Curves: Experiment with different curves for varied contrast effects
- Linear: Standard transfer
- S-Curve: Enhanced midtones
- Contrast: Punchier overall look
- Selective Transfer: Target specific tonal ranges for precise control
- Shadows: Affect only dark areas
- Midtones: Affect only mid-tones (most natural for skin tones)
- Highlights: Affect only bright areas
Intensity Blending
- 0-30%: Very subtle color correction
- 30-60%: Natural color grading
- 60-80%: Noticeable style transfer
- 80-100%: Full style application
Image Preparation
- Use images with similar aspect ratios for best results
- Higher resolution images produce better quality transfers
- For selective transfer, ensure good dynamic range in both images
Testing
Run the test suite:
# Run all tests
pytest
# Run with coverage
pytest --cov=colorcast --cov-report=html
# Run specific test file
pytest tests/test_transfer_methods.py
# Run with verbose output
pytest -v
Test Coverage: 75% (361 passing, 1 skipped)
- Core transfer methods: 100% coverage
- Full test suite including integration, performance, and property-based tests
- Property-based tests require the optional
hypothesisdependency
Technical Details
Algorithms Implemented
1. Histogram Matching
matched = exposure.match_histograms(source, reference)
- Per-channel histogram equalization
- Preserves complete color distribution
- Best for dramatic color transformations
2. Mean/Standard Deviation Transfer
result = ((source - μ_source) × (σ_ref / σ_source)) + μ_ref
- Matches statistical properties per channel
- Better color balance for photographic work
3. Lab Color Space Transfer (Reinhard)
result_lab = ((source_lab - μ_source) × (σ_ref / σ_source)) + μ_ref
- Operates in perceptually uniform Lab* color space
- Industry-standard in professional color grading
- Preserves color relationships better than RGB methods
- More natural-looking results
4. LUT with Curves
- Linear: Standard histogram matching
- S-Curve:
0.5 + 0.5 × sin(π(x - 0.5))- smooth midtone enhancement - Contrast:
x^0.8- power curve for increased punch
5. Selective Color Transfer
A smoothstep mask feathered over a ±0.05 luminance band blends the matched result into the source only within the targeted tonal range (shadows, midtones, or highlights), producing a seamless transition without hard edges.
- Region-based masking using luminance
- Precise tonal range targeting
Performance Features
- LRU Cache: 10-20x speedup for repeated operations
- Batch Processing: Parallel processing with ThreadPoolExecutor
- Memory Efficient: Processes images in-place where possible
- Debounced Updates: 50ms delay prevents UI blocking
- Automatic Format Conversion: Grayscale → RGB, RGBA → RGB (alpha composited onto a white background)
Use Cases
- Film color grading across different shooting conditions
- Photography: applying vintage or cinematic looks
- Style transfer for game assets and art creation
- Consistent color themes for social media content
- Academic research in color transfer
Contributing
Contributions are welcome! Please feel free to:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
For development:
# Install development dependencies
pip install -e ".[dev]"
# Run tests
pytest
# Run linting
black colorcast/ tests/
isort colorcast/ tests/
ruff check colorcast/ tests/
# Run type checking
mypy colorcast/
Citing ColorCast
If you use ColorCast in academic work, please cite it as:
@software{Semoglou_ColorCast,
author = {Semoglou, Michail},
title = {ColorCast: Color Transfer Toolkit for Python},
doi = {10.5281/zenodo.18550038},
url = {https://github.com/MichailSemoglou/ColorCast},
version = {2.5.0},
year = {2026},
}
A CITATION.cff file is included in the repository for GitHub's citation
tooling.
License
Released under the MIT License.
Author
Michail Semoglou
- Email: m.semoglou@tongji.edu.cn
Acknowledgments
- Built with scikit-image for image processing
- GUI powered by PyQt5
- Performance optimized with NumPy
Support
For issues, questions, or suggestions:
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file colorcast-2.5.0.tar.gz.
File metadata
- Download URL: colorcast-2.5.0.tar.gz
- Upload date:
- Size: 6.3 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f92125ccb76543177e359650cb386d79fe0b5fa2c6abcc54956dbbc236cb3a8a
|
|
| MD5 |
2132bc61da2f3ec4fa23685e358f48bc
|
|
| BLAKE2b-256 |
771cff8937efdb09f9d842817f75aa25d7e58b52e52182d2c78fd2838bd605ec
|
Provenance
The following attestation bundles were made for colorcast-2.5.0.tar.gz:
Publisher:
publish.yml on MichailSemoglou/ColorCast
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
colorcast-2.5.0.tar.gz -
Subject digest:
f92125ccb76543177e359650cb386d79fe0b5fa2c6abcc54956dbbc236cb3a8a - Sigstore transparency entry: 2321780479
- Sigstore integration time:
-
Permalink:
MichailSemoglou/ColorCast@62dfa5d2cd675d3d9b1c72914829397583f39c6a -
Branch / Tag:
refs/tags/v2.5.0 - Owner: https://github.com/MichailSemoglou
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@62dfa5d2cd675d3d9b1c72914829397583f39c6a -
Trigger Event:
release
-
Statement type:
File details
Details for the file colorcast-2.5.0-py3-none-any.whl.
File metadata
- Download URL: colorcast-2.5.0-py3-none-any.whl
- Upload date:
- Size: 6.2 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b31d2203f5a697220c0a1fc500c88912e1b3f54f3b5d7c8e8a343486c2ba5efe
|
|
| MD5 |
6539ba53a7c33ec1edfe90875ebef38f
|
|
| BLAKE2b-256 |
472c1c4498ba1b2aee1f275550d1f265749bb951b2031f9e5a81d430585ccca8
|
Provenance
The following attestation bundles were made for colorcast-2.5.0-py3-none-any.whl:
Publisher:
publish.yml on MichailSemoglou/ColorCast
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
colorcast-2.5.0-py3-none-any.whl -
Subject digest:
b31d2203f5a697220c0a1fc500c88912e1b3f54f3b5d7c8e8a343486c2ba5efe - Sigstore transparency entry: 2321780678
- Sigstore integration time:
-
Permalink:
MichailSemoglou/ColorCast@62dfa5d2cd675d3d9b1c72914829397583f39c6a -
Branch / Tag:
refs/tags/v2.5.0 - Owner: https://github.com/MichailSemoglou
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@62dfa5d2cd675d3d9b1c72914829397583f39c6a -
Trigger Event:
release
-
Statement type: