Colour blindness affects roughly 8% of men and 0.5% of women with Northern European ancestry. For a data visualisation that uses colour as the primary encoding — a choropleth, a multi-series line chart, a heatmap — that’s a meaningful share of the audience for whom the visual may be conveying the wrong information, or none at all.

The right time to test this is during design, not after a complaint. ImageMagick’s -color-matrix flag lets you simulate the major forms of colour vision deficiency directly on any image — screenshots, design exports, chart renders — from the command line. This makes it scriptable, batchable, and easy to drop into a CI pipeline alongside screenshot tests.


The Types of Colour Vision Deficiency

There are eight conditions worth modelling, grouped by which cone type is affected:

Red-deficient (protan)

  • Protanopia — complete absence of red-sensitive cones. Reds appear very dark; red-green distinction is lost.
  • Protanomaly — reduced red sensitivity. A milder version of the above.

Green-deficient (deutan) — the most common form

  • Deuteranopia — complete absence of green-sensitive cones. Reds and greens appear as variations of the same muddy yellow-brown.
  • Deuteranomaly — reduced green sensitivity. Affects around 5% of men.

Blue-deficient (tritan) — rare

  • Tritanopia — complete absence of blue-sensitive cones. Blue appears green; yellow appears violet.
  • Tritanomaly — reduced blue sensitivity.

Monochromacy

  • Achromatopsia — complete absence of cone function. Vision is entirely greyscale, light-sensitive.
  • Achromatomaly — incomplete monochromacy; limited colour perception.

How the Colour Matrix Works

A 3×3 colour matrix transforms each pixel’s RGB values by treating them as a vector and multiplying:

R' = R×m00 + G×m01 + B×m02
G' = R×m10 + G×m11 + B×m12
B' = R×m20 + G×m21 + B×m22

The identity matrix — which produces no change — has 1s on the diagonal and 0s everywhere else. The colour blindness matrices shift those weights to redirect how the output channels are mixed from the input, modelling the way the brain would reconstruct colour from a different cone response.

These matrices were published by the ColorJack team and have since become the standard reference. Note the values below are normalised to the 0–1 range required by ImageMagick; the source publishes them as percentages (0–100).


Applying a Matrix Directly to an Image

The simplest approach: apply the matrix directly to any image file.

# Protanopia (red-blind)
convert photo.png -color-matrix \
  '.56667 .43333 0
   .55833 .44167 0
   0      .24167 .75833' \
  photo-protanopia.png
# Deuteranopia (green-blind)
convert photo.png -color-matrix \
  '.625  .375  0
   .7    .3    0
   0     .3    .7' \
  photo-deuteranopia.png
# Achromatopsia (full monochromacy)
convert photo.png -color-matrix \
  '.299 .587 .114
   .299 .587 .114
   .299 .587 .114' \
  photo-achromatopsia.png

The achromatopsia matrix is essentially a weighted greyscale conversion using the standard luminance coefficients — the same values used in the ITU-R BT.601 luma formula. All three output channels receive an identical mix, so the result is a true greyscale image regardless of output format.


All Eight Conditions

The complete set of matrices for scripting:

# Protanopia
convert photo.png -color-matrix \
  '.56667 .43333 0
   .55833 .44167 0
   0      .24167 .75833' \
  photo-protanopia.png

# Protanomaly
convert photo.png -color-matrix \
  '.81667 .18333 0
   .33333 .66667 0
   0      .125   .875' \
  photo-protanomaly.png

# Deuteranopia
convert photo.png -color-matrix \
  '.625   .375   0
   .7     .3     0
   0      .3     .7' \
  photo-deuteranopia.png

# Deuteranomaly
convert photo.png -color-matrix \
  '.8     .2     0
   .25833 .74167 0
   0      .14167 .85833' \
  photo-deuteranomaly.png

# Tritanopia
convert photo.png -color-matrix \
  '.95    .05    0
   0      .43333 .56667
   0      .475   .525' \
  photo-tritanopia.png

# Tritanomaly
convert photo.png -color-matrix \
  '.96667 .03333 0
   0      .73333 .26667
   0      .18333 .81667' \
  photo-tritanomaly.png

# Achromatopsia
convert photo.png -color-matrix \
  '.299  .587  .114
   .299  .587  .114
   .299  .587  .114' \
  photo-achromatopsia.png

# Achromatomaly
convert photo.png -color-matrix \
  '.618  .32   .062
   .163  .775  .062
   .163  .32   .516' \
  photo-achromatomaly.png

Batch Processing with a HALD CLUT

For processing many images with the same transform, regenerating the colour matrix calculation per pixel, per image is wasteful. A HALD (HALftone D-dimensional lookup table) collapses the matrix into a precomputed colour lookup image that can be applied to any number of targets cheaply.

Generate the identity HALD — a reference image encoding all 512 possible colours:

convert hald:8 hald.png

Apply the colour matrix once to produce the distorted CLUT:

convert hald.png -color-matrix \
  '.56667 .43333 0
   .55833 .44167 0
   0      .24167 .75833' \
  hald-protanopia.png

Apply the pre-built CLUT to any image in one step:

convert photo.png hald-protanopia.png -hald-clut photo-protanopia.png

Build all eight CLUTs once and store them. From that point, applying any simulation to any image is a single command with no matrix arithmetic — the lookup is a direct pixel map. For a test suite processing hundreds of chart screenshots per build, the difference is significant.


Generating a Comparison Sheet

A montage of all simulations alongside the original is useful for design review. ImageMagick’s montage command handles this:

# Generate all simulations
for condition in protanopia protanomaly deuteranopia deuteranomaly tritanopia tritanomaly achromatopsia achromatomaly; do
  convert photo.png "hald-${condition}.png" -hald-clut "photo-${condition}.png"
done

# Assemble into a labelled comparison grid
montage photo.png photo-protanopia.png photo-protanomaly.png \
        photo-deuteranopia.png photo-deuteranomaly.png \
        photo-tritanopia.png photo-tritanomaly.png \
        photo-achromatopsia.png photo-achromatomaly.png \
  -tile 3x3 \
  -geometry 400x300+10+10 \
  -title 'Colour blindness simulation' \
  -label '%t' \
  comparison.png

The -label '%t' flag uses each input filename as a caption. Name your simulation outputs descriptively and the labels write themselves.


Boosting Saturation for Visual Comparison

The notes I kept alongside these matrices include a useful -fx expression for increasing saturation — handy when you want to make differences between conditions more visible in a side-by-side:

convert photo.png \
  -channel r -fx '+u.r*1.2 - u.g*0.1 - u.b*0.1' \
  -channel g -fx '-u.r*0.1 + u.g*1.2 - u.b*0.1' \
  -channel b -fx '-u.r*0.1 - u.g*0.1 + u.b*1.2' \
  photo-vivid.png

Each channel is boosted by 20% while subtracting 10% from the other two — a simple way to push colours apart without a full saturation operator. Apply this to the original before generating simulations if you’re working with a low-saturation source image and the differences between conditions are subtle.


What This Doesn’t Tell You

The matrix simulations are approximations. They model average cone response characteristics derived from population studies, not any specific individual’s visual system. Two people with deuteranopia may experience colour differently from each other and from what these matrices produce.

This is also not a substitute for testing with actual users who have colour vision deficiency. It is a fast, automatable first filter — useful for catching the obvious failures before they ship. A chart where red and green carry meaning, both of which become the same shade under deuteranopia, is a problem you can catch with a batch script. Catching it in a script is better than catching it in a support ticket.

For browser-rendered visualisations, Chrome and Firefox both ship colour blindness emulation in their DevTools accessibility panels. That’s the faster path for one-off checks during development. ImageMagick is the right tool when you need it in a pipeline, on arbitrary image files, or when you need to generate documentation showing how an asset looks across all conditions at once.

The ImageMagick colour modification documentation covers the full range of what -color-matrix and -fx can do beyond these examples.