<languageVersion : 1.0>
// Based on the “Analysis of Color Blindness” written by Onur Fidaner, Poliang Lin and Nevran Ozguven.
// http://scien.stanford.edu/class/psych221/projects/05/ofidaner/project_report.pdf
kernel Daltonize
<
namespace : "Daltonize";
vendor : "http://www.colorjack.com/";
version : 1;
description : "Daltonizing is a technique to modify a picture so that it is more visible to the visually impaired. This filter provides correction for Protanopia, Deuteranopia, and Tritanopia.";
>
{
input image4 src;
output pixel4 dst;
parameter int type
<
minValue: 0;
maxValue: 2;
defaultValue: 0;
>;
parameter float amount
<
minValue: 0.0;
maxValue: 1.0;
defaultValue: 1.0;
>;
const float3x3 Deuteranope = float3x3( // Deuteranope: greens are greatly reduced (1% men)
1.0, 0.0, 0.0,
0.494207, 0.0, 1.24827,
0.0, 0.0, 1.0
);
const float3x3 Protanope = float3x3( // Protanope: reds are greatly reduced (1% men)
0.0, 2.02344, -2.52581,
0.0, 1.0, 0.0,
0.0, 0.0, 1.0
);
const float3x3 Tritanope = float3x3( // Tritanope: blues are greatly reduced (0.003% population)
1.0, 0.0, 0.0,
0.0, 1.0, 0.0,
-0.395913, 0.801109, 0.0
);
const float3x3 RGB_to_LMS = float3x3( // Convert from RGB to LMS
17.8824, 43.5161, 4.11935,
3.45565, 27.1554, 3.86714,
0.0299566, 0.184309, 1.46709
);
const float3x3 LMS_to_RGB = float3x3( // Convert from LMS to RGB
0.0809444479, -0.130504409, 0.116721066,
-0.0102485335, 0.0540193266, -0.113614708,
-0.000365296938, -0.00412161469, 0.693511405
);
const float3x3 ERR_to_MOD = float3x3( // Daltonize image correction matrix
0.0, 0.0, 0.0,
0.7, 1.0, 0.0,
0.7, 0.0, 1.0
);
void evaluatePixel() {
float4 o = sampleNearest(src, outCoord()); // source pixel
float3 RGB = float3(o.r, o.g, o.b); // source color
float3 z = RGB * RGB_to_LMS; // transform into LMS colorspace
if(type == 0) z = z * Deuteranope; // calculate image as seen by the color blind
else if(type == 1) z = z * Protanope;
else if(type == 2) z = z * Tritanope;
z = z * LMS_to_RGB; // transform into RGB colorspace
z = (RGB - z) * ERR_to_MOD; // calculate deviance from normal
z = clamp(z + RGB, 0.0, 1.0); // apply compensation
dst.r = o.r * (1.0 - amount) + z.r * amount; // anomylize colors
dst.g = o.g * (1.0 - amount) + z.g * amount;
dst.b = o.b * (1.0 - amount) + z.b * amount;
dst.a = o.a;
}
}