Skip to main content

Advanced color and style transfer toolkit for images

Project description

ColorCast

Python Version License Code Coverage Tests

ColorCast is a sophisticated toolkit for advanced color and style transfer between images. It offers multiple algorithms including histogram matching, mean/std transfer, LUT-based curves, and selective regional color transfer.

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
  • Fully Tested - 88% test coverage with 117+ tests
  • Well Documented - Comprehensive API documentation and examples
  • Plugin Architecture - Easy to add custom transfer methods

Transfer Methods

  1. Histogram Matching - Classic histogram equalization, preserves local contrast
  2. Mean/Std Transfer - Statistical color matching using mean and standard deviation
  3. Lab Color Transfer (Reinhard) - Industry-standard perceptually uniform color transfer in Lab* space
  4. LUT + Linear Curve - Histogram matching with linear tone mapping
  5. LUT + S-Curve - Adds smooth contrast enhancement to histogram matching
  6. LUT + Contrast - Increases overall contrast with power curve
  7. Selective: Shadows - Transfers colors only in dark regions (luminance < 0.3)
  8. Selective: Midtones - Transfers colors only in mid-tones (0.3 to 0.7)
  9. Selective: Highlights - Transfers colors only in bright regions (luminance > 0.7)

Interface

ColorCast Interface

ColorCast's intuitive interface showing content image, style image, and result panels

Installation

From PyPI (Recommended)

Once published, 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.18.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:

python colorcast.py

Or use the package entry point:

python -m colorcast

Step-by-step:

  1. Select Transfer Method: Choose from 8 different algorithms at the top
  2. Load Content Image: Click to select your base image
  3. Load Style Image: Click to select the image whose style you want to copy
  4. Apply Style Transfer: Click to process the images
  5. Adjust Intensity: Use the slider to control effect strength (0-100%)
  6. Save Result: Export your final image in your preferred format
  7. 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

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)
  • -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 LRUCache

# Create cache
cache = LRUCache(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

Project Structure

colorcast/
├── colorcast/                    # Main package
│   ├── __init__.py               # Package exports
│   ├── __main__.py               # CLI entry point
│   ├── processing/               # Processing modules
│   │   ├── image_loader.py       # Image I/O
│   │   ├── transfer_methods.py   # Color transfer algorithms
│   │   ├── blending.py           # Intensity blending
│   │   ├── curves.py             # Tone curves
│   │   ├── registry.py           # Plugin system
│   │   ├── cache.py              # LRU cache
│   │   └── batch.py              # Batch processing
│   └── utils/                    # Utility modules
│       ├── config.py             # Configuration
│       ├── exceptions.py         # Custom exceptions
│       └── validators.py         # Input validation
├── tests/                        # Test suite (117+ tests)
│   ├── test_image_loading.py
│   ├── test_transfer_methods.py
│   ├── test_blending.py
│   ├── test_cache.py
│   ├── test_batch.py
│   ├── test_integration.py
│   └── test_performance.py
├── colorcast.py                  # Production-ready monolithic version
├── pyproject.toml                # Modern Python packaging
├── requirements.txt              # Legacy requirements
└── README.md                     # This file

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:

Component Coverage
Image Loading 95%
Transfer Methods 90%
Blending 95%
Caching 90%
Batch Processing 85%
Integration 80%
Lab Transfer 100%
Total 88%

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

3. 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

4. Selective Color Transfer

luminance = 0.299R + 0.587G + 0.114B
mask = (luminance >= shadow_threshold) & (luminance <= highlight_threshold)
result = source × (1 - mask) + matched × mask
  • 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

Documentation

Additional documentation is available:

Use Cases

ColorCast is perfect for:

  • Film Color Grading - Matching scenes shot at different times
  • Photography - Applying vintage or cinematic looks
  • Art Creation - Transferring painting styles to photos
  • Social Media Content - Creating consistent color themes
  • Game Development - Style transfer for game assets
  • Research - Academic research in color transfer

Contributing

Contributions are welcome! Please feel free to:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

For development:

# Install development dependencies
pip install -e ".[dev]"

# Run tests
pytest

# Run linting
black colorcast/
isort colorcast/
mypy colorcast/

# Run type checking
mypy colorcast/

License

This project is open source and available under the MIT License.

Author

Michail Semoglou

Acknowledgments

Support

For issues, questions, or suggestions:


Version: 2.0.0
Last Updated: February 2026

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

colorcast-2.0.0.tar.gz (54.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

colorcast-2.0.0-py3-none-any.whl (37.2 kB view details)

Uploaded Python 3

File details

Details for the file colorcast-2.0.0.tar.gz.

File metadata

  • Download URL: colorcast-2.0.0.tar.gz
  • Upload date:
  • Size: 54.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for colorcast-2.0.0.tar.gz
Algorithm Hash digest
SHA256 63892eb8886382179f38939deb268462934bc0943607b7c9a6efa7f50ff87305
MD5 a551ec0ffa04e8e0735b1c47b335259a
BLAKE2b-256 f553d64f436de067b864987535174f7b916b71dda169291ed71596653b2f75f9

See more details on using hashes here.

File details

Details for the file colorcast-2.0.0-py3-none-any.whl.

File metadata

  • Download URL: colorcast-2.0.0-py3-none-any.whl
  • Upload date:
  • Size: 37.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for colorcast-2.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d6efab38a2d2dd0fdefcdfc931cc72190a757c924bc87ee7d75500489fe97caf
MD5 1ea141859fcbea08ec2126e6411a6c68
BLAKE2b-256 6edee1c38582411c3c7fc916a757562c8ac51928aedd765448fbf93164c2d40b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page