Skip to content

About

On-device colorization of black-and-white photographs with DDColor — the photo keeps its own lightness, only colour is added.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

1 Commit

Folders and files

Repository files navigation

swift-image-colorizer

On-device colorization of black-and-white photographs with DDColor. The photograph keeps its own lightness at full resolution; only colour is added, so no edge, face or grain of film moves. Nothing is uploaded.

import ImageColorizer

let colorizer = try Colorizer(modelURL: ddcolorURL)          // load once
if !Colorizer.isColour(photo) {                                // leave colour photos alone
    let colour = try colorizer.colorize(photo)                 // reuse for a batch
}
let gentle = try colorizer.colorize(photo, options: ColorizeOptions(strength: 0.6, saturation: 1.2))

How it works

DDColor (Kang et al., ICCV 2023, piddnad/DDColor, Apache-2.0) is shown the photograph as neutral grey at 512×512 — each pixel's CIELAB lightness with a = b = 0, which is exactly its training input — and predicts CIELAB a/b. The prediction is sampled bilinearly back up to the photograph's size and laid over the photograph's own L channel. Strength blends the prediction with the picture's own a/b; saturation scales the prediction.

The model

The paper_tiny (ConvNeXt-T) checkpoint as a Core ML package, 245 MB, from arraypress/colorize-ddcolor-tiny (ColorizerModel.repository / .revision) — the conversion by mlboydaisuke/DDColor-Tiny-CoreML, byte for byte, re-hosted with DDColor's licence so tools pin the commit it was measured on. Not bundled: a tool downloads it (img colorize does on first use). The .mlpackage is compiled once and cached in Caches/swift-image-colorizer.

Is it already in colour?

Colorizer.isColour(_:) (and CGImage.chromaStats) answer before the model runs. Mean chroma alone cannot: a sepia print or a yellowed scan has plenty, all of one hue. The measure is the spread of a/b within lightness bands, sampled at 256 px — a toned print's colour depends on its lightness, so inside a band it barely varies; a photograph has many hues at the same lightness.

Measured on 100 pictures: the 3 black-and-white photographs below, plus grey, sepia, yellowed-and-faded and cyanotype versions of 20 colour photographs (the macOS stock animals and desktop pictures): at most 1.6. The 17 colour photographs themselves — misty, dusk and night ones included: at least 3.0. The threshold is 2.3. The plain (unbanded) spread could not separate them: a cyanotype scored 9.0 and a misty sunset 6.0. A picture made of flat colours that differ in lightness (a logo, a chart) can read as black and white; this is for photographs.

Measured

On an M3 Max, release build:

Photo Per photo
1 MP 0.07 s
12 MP 0.36 s
24 MP 0.67 s

Loading takes about 1 s, and the first prediction after a cold start about 3.5 s (Core ML specialising the model); every one after costs the times above. Peak memory 0.8 GB at 24 MP.

Against ground truth. Ten colour photographs (5 stock animals, 5 landscape desktop pictures; the Sonoma illustration left out as not a photograph) were turned grey, colorized, and compared with the originals: mean CIE76 ΔE 17.5, against 20.4 for the grey picture itself (the five animals: 13.9 against 21.5). ΔE punishes a plausible colour that is not the true one — a red car painted blue is "wrong" — so read it as "closer to the truth than grey", not as an error rate. Where it did worse than grey, it was scenes lit by unusual light (a dusk sky, a lit dome) that it coloured as daylight. Faces came out natural; the Library of Congress portrait in the tests had a lavender cast on a child's sleeve.

Requirements

  • macOS 26+ / iOS 26+ (Core ML), Swift 6.2
  • The model files keep DDColor's licence: Apache-2.0.

License

MIT — see LICENSE.

About

On-device colorization of black-and-white photographs with DDColor — the photo keeps its own lightness, only colour is added.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages