Why

When I started painting, mixing my colors was a huge pain. Color mixing is how painters make the colors they need: a set of paints holds only a dozen or so tubes, so nearly every color in a painting is blended from them.

It's a slow guess-and-check process: start with a little bit of this and that. It looks wrong, so you add a color and well, that just made it look more wrong. Time to try something new. Eventually you do mix yourself to a color that looks right (or good enough).

Then comes the next challenge: you have to remember how you made it. Did that take two drops of red or three? Once you've worked it out, you mix a big batch and squirrel it away in a cup. You'll need that color again and don't want to repeat the struggle. Worse, you might never get it right a second time.

The problem here is the guesswork. If you had a guide, something to follow, something approximately correct—you would be able to play around with colors without worrying about ruining your precious little swatch. You could also stop stressing about paint storage. Don't have a color you need? Just make it again!

Directionless struggling isn't a helpful way to learn. Guessing doesn't help you. There are enough challenges with painting; agonizing over color mixing needn't be one. Thus, paintrecipe.com was born.

How it works

To figure out how to mix your paints, you need to answer two questions:

  1. What colors do I need?
  2. How do I make them?

Part I.What colors do I need?

A photo has tens of thousands of distinct colors. A painting needs a palette; we use 16 colors by default. The goal is to split the photo into regions and choose a small set of colors so that, painting each region with one of them, the result still looks like the photo. That takes three steps.

Quickshift splits it into 925 regions.

Quickshift splits it into 925 regions.

1. Split the photo into regions

The first step groups neighboring pixels of similar color into regions called superpixels; we aim for about a thousand by default. Working with regions rather than single pixels keeps the outline readable. Each pixel is described by its color in Lab (more on that below) and its position. The studio offers three main approaches:

  • Quickshift (the default, Vedaldi & Soatto, 2008) estimates how crowded each pixel's neighborhood is with similar colors, then links every pixel to the nearest pixel that is more crowded than itself, as long as it's within a maximum distance τ\tau:
    Pi=∑jexp⁡ ⁣(−d(i,j)22σ2),parent⁡(i)=arg min⁡j : Pj>Pid(i,j)if d(i,j)<τP_i = \sum_j \exp\!\Big(-\frac{d(i,j)^2}{2\sigma^2}\Big), \qquad \operatorname{parent}(i) = \operatorname*{arg\,min}_{j \,:\, P_j > P_i} d(i,j) \quad \text{if } d(i,j) < \tau
    Following the links uphill, pixels that reach the same peak form a region. Regions follow the photo's edges and can be long and thin, so they stay faithful to detail, but grouping them into colors leaves more specks too small to paint. The defaults (σ=5, τ=11.5\sigma = 5,\ \tau = 11.5) give 925 regions for the slug.
  • SLIC (Achanta et al., 2012) is k-means clustering on those five numbers per pixel, starting from a grid of centers SS pixels apart, with a distance that weighs color against position:
    D=dcolor2+(dpositionS)2m2D = \sqrt{d_{\text{color}}^2 + \Big(\frac{d_{\text{position}}}{S}\Big)^2 m^2}
    The compactness mm keeps regions compact and roughly even in size, with no specks; long, thin things like a twig can get absorbed into their neighbors. The default asks for 1,150 regions and gets 1,018 for the slug.
  • No superpixels skips regions altogether: k-means groups the pixels themselves by color. The painting looks closest to the photo (for the slug, an average color difference of 7.6 against about 10 with regions) but it's a weak guide. Nothing decides where paint goes, so the colors scatter into over 15,000 specks too small to paint.

Compared at the same number of regions, neither SLIC nor Quickshift wins outright: Quickshift follows edges better and is often a little more faithful on busy photos, while SLIC is tidier and easier to paint.

2. Give each region its average color

Each region rr is reduced to the average color of its pixels pp:

cˉr=1∣r∣∑p∈rLab⁡(p)\bar c_r = \frac{1}{|r|} \sum_{p \in r} \operatorname{Lab}(p)

The average is taken in CIELAB ("Lab"), a color space built so that straight-line distances roughly match how different two colors look to people: LL is lightness, aa runs green to red, and bb runs blue to yellow. Averaging the raw RGB numbers instead gives subtly wrong, often muddier colors.

3. Group the regions into colors

Now k-means runs again, on color alone. It looks for kk group colors μ1,…,μk\mu_1, \dots, \mu_k (kk will be the size of your pallete) and an assignment g(r)g(r) of regions to groups that keep every region close to its group's color:

min⁡μ, g  ∑r∥cˉr−μg(r)∥2\min_{\mu,\, g} \; \sum_{r} \big\lVert \bar c_r - \mu_{g(r)} \big\rVert^2

It starts from kk guesses spread out on purpose (k-means++), then repeats two moves (the studio runs 10 rounds): every region joins its nearest group (g(r)=arg min⁡j∥cˉr−μj∥g(r) = \operatorname*{arg\,min}_j \lVert \bar c_r - \mu_j \rVert) and every group color moves to the average of its regions. Each group's final color is the average of all its pixels. Every region takes its group's number. That's the color guide.

After 10 of 10 rounds
Drag the plot to turn it in 3D
k-means grouping the slug's region colors
The slug photo

Each dot is one of the slug's 925 Quickshift regions, placed by its color and sized by its area; each square is a group's color, joined to the regions nearest it. Hover a dot, a square, or the photo to see which is which. Flat views show two of color's three directions at once, so some lines cross; 3D shows all three (drag to turn it). In the grouping every region counts once, whatever its size.

Finally, we have our palette. We have reduced the original picture to a small number of distinct colors. Time to figure out how to mix them.

Part II.How do I make them?

First, the forward problem

Finding which paints make a color is an inverse problem. Often, it is easier to solve the forward direction. It is easier to figure out If I mix these paints, what color will I get? than to answer What paints do I need to mix this particular color?

For light, mixing is simple addition. Paint is different: pigments absorb and scatter light (the Kubelka–Munk model), so blue and yellow paint make green, while averaging their RGB numbers gives a dull olive.

Mixing Cerulean Blue Hue with Yellow Medium AzoAverage the numberslike light on a screenMixboxlike paintWhat Mixbox storesamounts of four base pigments(plus a small correction)Cerulean Blue Hue70%13%15%Mix (50% / 50%)35%53%10%Yellow Medium Azo94%

Mixbox: where paint mixing is a straight line

paintrecipe uses Mixbox (Sochorová & Jamriška, 2021), a pigment mixing model built on Kubelka–Munk. Mixbox maps each color to seven numbers, the amounts of four base pigments plus a small correction, z=φ(rgb)∈R7z = \varphi(\text{rgb}) \in \mathbb{R}^7, chosen so that mixing paint is just a weighted average of those numbers:

mix⁡(w)=φ−1(∑iwi zi),wi≥0,  ∑iwi=1\operatorname{mix}(w) = \varphi^{-1}\Big(\sum_{i} w_i\, z_i\Big), \qquad w_i \ge 0,\; \sum_i w_i = 1

The physics stays inside Mixbox. What's left is linear algebra.

Turning the problem around

Mixbox hands us the forward direction: pick amounts of each paint, average their seven numbers and convert back. In math terms, the mix is a linear function of the amounts. Double one tube's share and its contribution to the mix doubles; combine two recipes and their numbers simply add.

That's what makes the inverse easy. If mixing were a tangled, nonlinear process, the only way to find a recipe would be to search: try some amounts, mix, compare, adjust, repeat. That's guess and check again, just done by a computer. A linear forward direction turns the question into a system of linear equations, one of the most thoroughly solved problems in mathematics. There's no searching: the standard tools go straight to the answer. They can also tell us when it's the best one possible.

Now bring in your paints. Each tube in your set has its own seven numbers; stack them as the columns of a matrix CC. How much of each tube goes into a mix is a vector ww:

C=[∣∣∣z1z2⋯z12∣∣∣]∈R7×12,C w=ztC = \begin{bmatrix} | & | & & | \\ z_1 & z_2 & \cdots & z_{12} \\ | & | & & | \end{bmatrix} \in \mathbb{R}^{7 \times 12}, \qquad C\,w = z_t
CYellow Medium AzoQuinacridone CrimsonUltramarine Blue Red ShadeNaphthol Red LightYellow OxideTransparent Burnt SiennaTransparent Raw UmberPhthalocyanine Green Blue ShadeCerulean Blue HueDioxazine PurpleTitanium WhiteIvory Black
pigment 10.000.100.790.000.080.270.480.730.700.780.000.50
pigment 20.940.000.010.160.750.040.250.230.130.060.000.26
pigment 30.010.880.200.830.170.690.280.040.010.170.000.24
pigment 40.050.010.000.010.000.00-0.00-0.000.15-0.001.000.00
correction 10.05-0.010.010.05-0.00-0.06-0.04-0.010.000.030.00-0.13
correction 20.02-0.09-0.01-0.10-0.00-0.03-0.07-0.00-0.00-0.030.00-0.14
correction 3-0.05-0.01-0.02-0.02-0.07-0.12-0.17-0.030.00-0.080.00-0.15

12 tubes · rank 7 of 7: full rank, with 5 spare directions, so exact recipes are never unique. Each column is one tube's seven Mixbox numbers: four base-pigment amounts, then three small corrections.

Finding a recipe means solving C w=ztC\,w = z_t for ww, where zt=φ(target)z_t = \varphi(\text{target}). Each tube is a point in seven dimensions. Any eight or more such points are linearly dependent: some tube can always be written as a combination of the others (using positive and negative amounts). What matters is the rank of CC, the number of independent directions its columns span. Seven or more tubes of different colors almost always give full rank, 7, so C w=ztC\,w = z_t has an exact solution for any target. Our default set's 12 tubes leave 12 − 7 = 5 spare directions, so there are endlessly many exact answers. So have we done it? Can we make any color we desire? Not quite…

Why some colors are out of reach

Real paint follows two rules: no negative amounts and amounts that add up to the whole mix. In symbols, ww must lie on the simplex Δ={ w:w≥0, 1⊤w=1 }\Delta = \{\, w : w \ge 0,\ \mathbf{1}^\top w = 1 \,\}. So mixing is averaging. The mixes your paints can make form the convex hull of their latents:

{ C w:w∈Δ }=conv⁡{z1,…,z12}\{\, C\,w : w \in \Delta \,\} = \operatorname{conv}\{ z_1, \dots, z_{12} \}

No mix is lighter than your lightest paint or more vivid than your most vivid one.

You'll never make white without white.

Target colors and the closest mixes

Each square is a target; the patch inside is the closest mix these paints make. 37 of 72 are very close (ΔE under 5); 16 are out of reach (crossed out). Click a paint to take it out of the set: without Titanium White, the light rows and the light grays go.

Solving within the rules

So the question becomes: what's the closest mix the rules allow? Below, four methods go from ignoring the rules to respecting both.

Target:
A recipe and how it was solvedTarget#87ceebOn paper#87ceebAmounts add up to100%Paints used11Impossible amounts40100%Yellow Medium AzoQuinacridone Crimson5%Ultramarine Blue Red Shade12%Naphthol Red Light−24%Yellow Oxide8%Transparent Burnt Sienna28%Transparent Raw Umber−14%Phthalocyanine Green Blue Shade16%Cerulean Blue Hue25%Dioxazine Purple−14%Titanium White67%Ivory Black−8%
w=C+zt=C⊤(C C⊤)−1ztw = C^{+} z_t = C^\top \big(C\,C^\top\big)^{-1} z_t

An exact match on paper but impossible to mix: it uses nearly every tube, some in negative amounts.

  1. Add 67% Titanium White
  2. Add 28% Transparent Burnt Sienna
  3. Add 25% Cerulean Blue Hue
  4. Take out 24% Naphthol Red Light (impossible)
  5. Add 16% Phthalocyanine Green Blue Shade
  6. Take out 14% Dioxazine Purple (impossible)
  7. Take out 14% Transparent Raw Umber (impossible)
  8. Add 12% Ultramarine Blue Red Shade
  9. Add 8% Yellow Oxide
  10. Take out 8% Ivory Black (impossible)
  11. Add 5% Quinacridone Crimson

With both rules in place (w∈Δw \in \Delta), finding a recipe is a small convex quadratic program with one best value: the closest mix your paints can make. paintrecipe solves it with an active-set method that starts from the best single paint and adds paints one at a time, only when they help, so recipes stay short: fewer tubes for the same color. A second pass (Gauss–Newton) then nudges the amounts to minimize the visible difference rather than the distance between Mixbox's numbers:

min⁡w∈Δ  ΔE76(mix⁡(w), target)\min_{w \in \Delta} \; \Delta E_{76}\big(\operatorname{mix}(w),\ \text{target}\big)

Part III.Results

Before the results, a quick look back. Parts I and II took the pipeline one step at a time; here is the whole trip again in three steps, from photo to recipe. Each card links back to where we covered it.

Here is the slug at our default settings, mixed from the default paints.

The slug photo
The photo
The slug painted in 16 mixed colors
Painted with the default paints
Outline of the painting's color areas1112222223333334444445555556666667777778889999991010101010101111111111111212121313141414141414151516
The color guide

The palette: 16 colors, each with a recipe in parts.

1
Eggshell · 3% of the painting8 parts Titanium White, 1 part Yellow Oxide, 0.35 parts Cerulean Blue Hue, 0.05 parts Quinacridone Crimson
2
Sea Green · 8% of the painting2 parts Cerulean Blue Hue, 1 part Yellow Medium Azo
3
Ivy · 17% of the painting10 parts Phthalocyanine Green Blue Shade, 2 parts Yellow Medium Azo, 1 part Quinacridone Crimson, 0.35 parts Yellow Oxide, 0.15 parts Cerulean Blue Hue
4
Onyx Black · 6% of the painting5 parts Phthalocyanine Green Blue Shade, 2 parts Transparent Burnt Sienna, 1 part Yellow Oxide, 1 part Ivory Black, 0.3 parts Transparent Raw Umber
5
Pool · 11% of the painting7 parts Cerulean Blue Hue, 7 parts Titanium White, 1 part Yellow Medium Azo
6
Emerald · 4% of the painting3 parts Cerulean Blue Hue, 2 parts Titanium White, 1 part Yellow Medium Azo
7
Clover · 13% of the painting6 parts Cerulean Blue Hue, 4 parts Phthalocyanine Green Blue Shade, 3 parts Yellow Medium Azo, 1 part Yellow Oxide, 0.15 parts Quinacridone Crimson
8
Driftwood Brown · <1% of the painting4 parts Yellow Medium Azo, 4 parts Cerulean Blue Hue, 3 parts Quinacridone Crimson, 2 parts Titanium White
9
Oasis · 9% of the painting5 parts Cerulean Blue Hue, 4 parts Titanium White, 1 part Yellow Medium Azo
10
Viridian · 9% of the painting8 parts Cerulean Blue Hue, 1 part Yellow Medium Azo, 1 part Yellow Oxide, 1 part Titanium White, 0.4 parts Quinacridone Crimson
11
Illuminati Green · 10% of the painting4 parts Cerulean Blue Hue, 1 part Yellow Medium Azo, 1 part Titanium White
12
Pebble · 2% of the painting7 parts Titanium White, 3 parts Cerulean Blue Hue, 1 part Yellow Medium Azo, 1 part Quinacridone Crimson, 1 part Yellow Oxide
13
Wheat · 2% of the painting6 parts Titanium White, 1 part Yellow Medium Azo, 1 part Yellow Oxide, 0.25 parts Quinacridone Crimson, 0.1 parts Cerulean Blue Hue
14
Ebony · 4% of the painting5 parts Cerulean Blue Hue, 2 parts Yellow Medium Azo, 2 parts Quinacridone Crimson, 0.2 parts Titanium White
15
Cloud · <1% of the painting8 parts Titanium White, 1 part Quinacridone Crimson, 1 part Yellow Oxide, 1 part Cerulean Blue Hue, 0.2 parts Transparent Burnt Sienna
16
Tan · 3% of the painting5 parts Titanium White, 2 parts Yellow Medium Azo, 1 part Quinacridone Crimson, 1 part Cerulean Blue Hue

Each color also comes with step-by-step mixing: start with the biggest amount and add the rest, checking the color after each addition.

How to mix TanTan4 paints · 9 parts by volumeColor difference ΔE 0.0 · very closeTARGETYOUR MIXPAINTS BY WEIGHT2Yellow Medium Azo21%1Quinacridone Crimson12%1Cerulean Blue Hue13%5Titanium White55%MIX PROGRESSIONBiggest first ⇄Δ 37.3›Δ 29.1›Δ 29.0›Δ 0.0+2+1+1+5

Try it with your own photo, or mix a single color.