Posted by Dan Byström on October 31, 2004
I hadn’t planned for a follow up on this – therefore I’m not going to apologize for the horrible blog title.
Earlier this week, I was sitting on the train to Stockholm, reading the C/C++ Users Journal when I came across an article about writing C++ extensions for Matlab in order to do transformations of RGB into different color spaces. This was enough to make my mind drift back to my previous blog on colors.
I thought “If we can simulate a defect red-green color vision by smoothing out the difference between the red and the green component in an image, pixel by pixel, then how about doing do the opposite? That is, increase the gap in order to make it easier to visualize for a color blind person?”
If we for each pixel in an image determine which one of the red and green component is the most contributing (have the largest value of the two) and then amplify that component and at the same time reduce the other component, then we should make it easier for the eye to distinguish the red from the green.
If we try such an algorithm on the flower picture from my previous blog, then for the “simulated image” we would simply return to the original picture. Not much gain, you might think. But when we try this algorithm on the original image, we would instead get a more colorful image. Psychedelic, a normal seeing person might call it. Or if you grew up in the sixties, you might just long for a smoke.
Let me show you what I mean. Below are two buttons, one green and one red. The “problem” is that they may appear very similar to a color blind person. Really – this is often hard to grasp for many people. Interestingly, the concept of fuzzy viewing (so that you need eye glasses in order to see sharp) is never questioned. I guess this is because even people with perfect seeing understand what is going on because their seeing becomes fuzzy too when they try to view something at a (sufficiently) far distance.
Original images – before we apply any transformation.
I have applied the above described “color sharpening” algorithm to the buttons to produce the new buttons below. And suddenly the colors have become much more distinct and easier to make out. Notice that the blue color is unaffected.
Transformed colors – the same algorithm has been applied to both buttons.
Now how do we implement such an algorithm? One way is certainly by looping through each pixel and perform an “if statement” and a little calculation. But indeed there is a better way. Yes, you guessed it… the ColorMatrix of course!
In order to produce the “color smoothing” last week, I used the following ColorMatrix:
/ 1 – z z 0 0 0 \ | z 1-z 0 0 0 | M(z) = | 0 0 1 0 0 | | 0 0 0 1 0 | \ 0 0 0 0 1 /
In order to reverse the process, we just have to use the inverse matrix M-1(z). Inverting a (large) matrix is a whole science, but our case is almost trivial. Since rows and columns 3-5 are identical to the identity matrix, we only have to deal with a 2×2 matrix. Numerically we can even use the
Matrix.Inverse method (namespace
System.Drawing.Drawing2D) to do so:
int z = 0.3; // z should be in the [0,0.5[ interval
Matrix M = new Matrix( 1-z, z, z, 1-z, 0, 0 );
Now we have our sought coefficients in M.Elements[0..3] ready to be used in our ColorMatrix. But this is cheating. Instead, pulling out our trustworthy paper&pencilTM, we soon arrive to this solution:
/ 1 – z
1 – 2z
1 – 2z
0 0 0 \ M-1(z) = | – z
1 – 2z
1 – z
1 – 2z
0 0 0 | | 0 0 1 0 0 | | 0 0 0 1 0 | \ 0 0 0 0 1 /
We observe than for z = 0.5 this matrix isn’t defined, since we will get a division by zero if we try to calculate its coefficients. This is something we knew from the beginning, for two reasons:
- Mathematically. M(0.5) has a determinant of zero (denoted det(M) or |M|) and therefore we know that no inverse matrix exist.
- By context. The meaning of z = 0.5 is “remove ALL difference between red and green”. Any little hint of what they might have been before M(0.5) was applied is completely lost and gone forever. Logically, no inverse can therefore exist.
Anyway, applying the above calculated M-1(0.3) to our flower photo from last week, this time we get this result:
The image to the right has been created by applying the M-1(z) color matrix to the left image, using a z value of 0.3, giving the more dominant red/green color a boost while supressing the other.
Well, the idea of inverting a color matrix was really all I wanted to tell you about.