,.
. :%%%. .%%%.
__%%%(\ `%%%%% .%%%%%
/a ^ '% %%%% %: ,% %%"`
'__.. ,'% .-%: %-' %
~~""%:. ` % ' . `.
%% % ` %% .%: . \.
%%:. `-' ` .%% . %: :\
%(%,%..." `%, %%' %% ) )
%)%%)%%' )%%%.....- ' "/ (
%a:f%%\ % / \`% "%%% ` / \))
%(%' % /-. \ ' \ |-. '.
`' |% `() \| `()
|| / () /
() 0 | o
\ /\ o /
o ` /-|
___________ ,-/ ` _________ ,-/ _________________ INCLUDES _ OCAML _ SOURCE _ CODE _ EXAMPLES _____________________________________________

Tuesday, May 6, 2014

The Classic Filters

As I said it in my last post, we are going to see how to implement some image processing filters, starting with the classic ones. Note that I will certainly use some useful functions that were previously described. So if you didn't read my last post, I recommend you to do it (don't worry, it's not very long).
And before beginning, I would like to show you something...
As you may know now, the image processing is all about matrices but I didn't show you how to convert your image into a matrix in order to work on it and then transform this matrix into your new image. The answer is that it just depends on the image management library you are using. For example, I use OCamlSDL to see the results of my functions (because as I already said, I will use the OCaml programming language). So as you can imagine, I have a function that loads an image, another one which transforms this image to a matrix, another one which does the reverse and finally a function which can save the resulting image as a .bmp file :

So let's begin with the most simple filter, the negative filter. What you have to do is replacing all the (Red,Green,Blue) pixels of your image by (255 Red255 Green255 Blue).

Note that you can also try to see what's happening when you apply the negative effect only on some pixel channels of your choice. Here is my result :
Now, we will have to do conversions between floating point numbers and integers with the sepia filter. As it's also a very simple filter, I show you directly the formula I used in an example of source code :

Easy?! Just note that the fix_rgb function was already described in my last post, foi is a function that converts an integer to a floating point number (foi stands for float_of_int), iof converts a floating point number to an integer (iof stands for int_of_float) and I put dots behind all operators like that "+." just because it's the OCaml syntax when you are manipulating floating point numbers. The beautiful result :
The next function that I am going present can provide many different results.
In fact, we will enabled and disabled some pixel channels in order to colorize our image.
So if you want to colorize your image in Magenta for example, you have to browse your image matrix representation and replace all Green pixel channels by 0. Why we don't do same for the Red or the Blue pixel components? Because Red+Blue=Magenta, so we don't change their current value!
You can now try all possibilities which are normally those ones (we will ignore the cases (0,0,0) and (255,255,255) that we already saw in my last post) :
What you can also do and which is more interesting, is to observe what's happening when you shift or swap the pixel components. Actually, it will give you lots of new color effects and they are too many for giving you the complete list of possibilities... (Red,Blue,Green), (Green,Blue,Red), (Green,Red,Blue), (Blue,Red,Green), (Blue,Green,Red), (Red,Red,Green), ...
You still can disable some pixel components like (Green,0,Red), (Blue,0,Green), ...
It's time to talk about the grey level of an image. It exists many methods to convert your image in grey level and I will try to present the most important ones. Firstly, you must know that the particularity of the grey level is that it always verifies that the RedGreen and Blue pixel components in any pixel of your image become equal. You can use the "Averaging" method where all (Red,Green,Blue) pixels of your image must be replaced by (Grey,Grey,Grey) where Grey = (Red+Green+Blue) / 3.
Then comes the "Luma" method where Grey Red * 0.2126 + Green * 0.7152 + Blue * 0.0722
(here again, some conversions between integers and floating point numbers will be necessary).
You can also convert an image to the grey level with the RedGreen or Blue channels by considering (Grey,Grey,Grey) as (Red,Red,Red) for the Red channel
or as (Green,Green,Green) or (Blue,Blue,Blue).
You can use the "Max decomposition" method where Grey = max(Red,Green,Blue)
or the "Min decomposition" method where Grey = min(Red,Green,Blue)
and finally there is the "Desaturation" method where
Grey = (max(Red,Green,Blue) + min(Red,Green,Blue)) / 2. Here is the "Averaging" result :
Now, I suggest to change your image to another color space like the famous YCbCr one.
This function is based on conversions like the sepia filter and you can get this type of effect :
Here is how I wrote my converting function to the YCbCr color space according to Wikipedia :

Well, we will finish this post with a last filter which can solarize your image.
This function will only depend on a certain threshold which must be between 0 and 255.
You will have to browse your matrix and apply this procedure for every components of every pixels :

As you see, the pixel components are replaced by their negative value only if their current value is under the threshold you have chosen. Start to test your function with a threshold of 127 for example.
Here is my result :