This Visual Basic .NET class implements an image filter that can change an RGB image to a grayscale image whilst leaving a selected range of RGB values unchanged. A small demo project is available to show the filter's use.
When creating and optimizing Hue/Saturation/Lightness filter and Grayscale filter I learned a lot about images and colors. Observing the HSL circle (below), I got an idea to make filter where a certain color would remain intact while others are converted to grayscale.
As can be seen in the HSL circle, similar colors are grouped within a certain angle. If we want the red color to remain intact and other colors to be converted to grayscale, we should not change pixels with a hue around 0 degrees. Since I had HSL and grayscale conversions already programmed, programming the filter was easy. Most of the time it was used to implement a tolerance calculation. The decision to implement tolerances for saturation and lightness proved to be right when testing the filter. Shadows can be effectively filtered, reducing saturation and lightness tolerance.
Tolerances for saturation and lightness (SL) work in a somewhat unusual way. I took the SL of the color we wish to remain unchanged as zero tolerance. Plus and minus tolerances do not necessary have equal values. If, for example, the saturation of the color we wish to remain unchanged is 0.75, then with tolerance set to 0.1 (10%) the minus tolerance will be 0.075 and the plus tolerance will be 0.025, i.e. 10% of the difference between 0.75 and 1.0.
Using the code
Using the filter is simple. Set the properties and call the execution function. I have provided a small demo project where you can play with both filters, change color factors and colors, and finally save the filtered images. The code for the project is also included.
The base for the demo application is the same as for the other two projects mentioned. With sliders, you can change tolerance for hue (0 to 180 degrees), saturation and lightness (0 to 100%). You can select the color with the color dialog and color picker. Implementation of the color picker is a bit clumsy. You have to click the "Picker" button, select the color and then click same button again to get a normal cursor. Picking the color is working only when the "Picker" cursor is displayed. The color under the cursor is shown in a small square between the buttons.
The demo application uses a cheap trick to look fast. The pictures displayed are resized and all the filtering is done on resized image. The filtering of a real image is done only before saving, so saving can take some more time: approximately 2 seconds on my computer with an image size of 2288x1712 pixels. I've provided two pictures you can play with in the beginning. I get nice results with both images.
Points of interest
When preparing the demo application, I learned how to change the cursor with the custom image. It's simple if you already have cursor file. It's some more work if you are making one.
I needed an HSL circle image for this article and just for fun I programmed a function that creates the required image with a given circle radius and lightness value.
- 2007-06-25: Version 1.0
- 2007-07-12: Article edited and moved to the main CodeProject.com article base