Files
filmsim/README-filmcolor.md

102 lines
4.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# `filmcolor` - Film Stock Color Emulation
`filmcolor` is a Python script that transforms digital color positive images (like those from a digital camera) into simulated film negatives. It bases its transformations on datasheet parameters for specific film stocks, focusing on color response, H&D curves, spatial effects like halation and diffusion, and saturation.
## Features
* Applies film stock characteristics based on a JSON datasheet.
* Converts linear RGB input to log exposure.
* Applies H&D (HurterDriffield) curves for tonal mapping.
* Simulates dye coupler diffusion and interlayer effects.
* Applies halation effects.
* Adjusts saturation based on coupler properties.
* Supports RAW (Sony ARW, DNG), TIFF, PNG, and JPG inputs.
* Outputs TIFF (16-bit uncompressed), PNG (8-bit), or JPG (8-bit).
## Usage
The script is designed to be run with `uv`, which handles dependency management.
### Direct Execution with `uv` (Recommended)
You can run `filmcolor` directly from its Git repository URL:
```bash
uv run https://git.dws.rip/dubey/filmsim/raw/branch/main/filmcolor -- <input_image> <datasheet_json> <output_image>
```
**Example:**
```bash
# Ensure input.jpg and sim_data/portra_400.json are in your current directory or provide full paths
# Output will be output_negative.tiff
uv run https://git.dws.rip/dubey/filmsim/raw/branch/main/filmcolor -- input.jpg sim_data/portra_400.json output_negative.tiff
```
### Local Execution
If you have cloned the repository or downloaded the script:
1. Navigate to the script's directory or ensure it's in your PATH.
2. Run the script:
```bash
uv run ./filmcolor -- <input_image> <datasheet_json> <output_image>
```
Or, if `filmcolor` is in the current directory and executable:
```bash
./filmcolor <input_image> <datasheet_json> <output_image>
```
## Arguments
### Positional Arguments:
* `input_image`: Path to the input RGB image.
* Supported formats: TIFF, PNG, JPG, Sony ARW, DNG.
* Non-RAW images are assumed to be sRGB and will be linearized. RAW files are processed to sRGB.
* `datasheet_json`: Path to the film datasheet JSON file (e.g., `sim_data/portra_400.json`).
* `output_image`: Path to save the output emulated film negative.
* Output format is determined by the file extension:
* `.tiff` / `.tif`: 16-bit uncompressed TIFF.
* `.png`: 8-bit PNG.
* `.jpg` / `.jpeg`: 8-bit JPG (quality 95).
### Options:
The script currently does not have additional command-line options beyond the positional arguments. Configuration is primarily driven by the content of the `datasheet_json` file.
## Input Image Preparation
* **Linear RGB:** The script internally works with linear RGB data.
* If an 8-bit or 16-bit integer image (PNG, JPG, TIFF) is provided, it's assumed to be sRGB encoded and will be automatically linearized.
* If a float32/float64 image is provided, it's assumed to be already in linear RGB.
* RAW files (ARW, DNG) are demosaiced, white-balanced (using camera WB), and converted to linear sRGB.
* **Alpha Channel:** If an alpha channel is present, it will be discarded.
## Datasheet Format
The `datasheet_json` file contains detailed parameters for the film stock being simulated. This includes:
* Information (name, format, version)
* Processing parameters (gamma, balance)
* Physical properties (halation strength and size, coupler diffusion, interlayer diffusion)
* H&D curves
* Calibration data (ISO, middle gray log exposure)
An example datasheet (`sim_data/portra_400.json`) is provided in the repository.
## Workflow
1. **Load Image:** Reads the input image. RAW files are processed using `rawpy`. sRGB images are linearized.
2. **Load Datasheet:** Parses the specified JSON film datasheet.
3. **Convert to Log Exposure:** Transforms linear RGB pixel values to log exposure (LogE) space, anchored by the `middle_gray_logE` from the datasheet.
4. **Apply H&D Curves:** Maps LogE values to densities for each color channel (R, G, B) using the H&D curves from the datasheet. This step also incorporates processing gamma and balance shifts.
5. **Convert Density to Transmittance:** Converts the resulting densities back to linear transmittance values (0-1 range).
6. **Apply Spatial Effects:**
* **Diffusion Blur:** Simulates dye coupler and interlayer diffusion by applying a Gaussian blur. The blur radius is derived from `diffusion_um` values in the datasheet and the image dimensions/film format.
* **Halation:** Simulates light scattering within the film base by applying channel-specific Gaussian blurs, controlled by `halation.strength` and `halation.size_um`.
7. **Apply Saturation:** Adjusts image saturation based on the `couplers.amount` parameter.
8. **Save Output:** The processed image (now a simulated film negative) is saved to the specified output file, converting to 16-bit for TIFF or 8-bit for PNG/JPG.