Because I know you ❤ the Mathematics (or not...), I suggest to show you several new image processing filters that can be applied using just a few mathematical functions that you may know and which are the cosine, the sine and the arctangent functions. Here are some details about them :
The Trigonometric Functions and The Inverse Trigonometric Functions.
Firstly, the image distortion will consist in changing the location of all the pixels (we won't have to change the color properties of the pixels like in my previous tutorials). But before moving any pixel to another location (which will have to be inside the image matrix representation), we obviously have to determine what will be the coordinates (x,y) of this new location. And it's here that the mathematical functions I just named will be useful concerning the filters that we will see. Finally, I will present the result of the use of different classic operators (+, -, *, ...) applied to 2 images.
Firstly, the image distortion will consist in changing the location of all the pixels (we won't have to change the color properties of the pixels like in my previous tutorials). But before moving any pixel to another location (which will have to be inside the image matrix representation), we obviously have to determine what will be the coordinates (x,y) of this new location. And it's here that the mathematical functions I just named will be useful concerning the filters that we will see. Finally, I will present the result of the use of different classic operators (+, -, *, ...) applied to 2 images.
Fisheye Lens effect :
The fisheye lens effect can give the impression that your image is zoomed and projected on a sphere (see the illustration). This effect is frequently used in photography. To get this result, you have to create a new empty image and fill it by seeking the pixels of the original image that are part of the sphere that you are creating. I can only suggest to refer yourself to this very well explained procedure (by Jussi) that I found by chance and which works perfectly. Note that in the following source code, sqrt is the square root function, atan is the arctangent function, cos and sin are respectively the cosine and sine functions and I manipulate some floating point numbers like with all the following distortion filters.
The polar effect consists in converting the cartesian coordinates (x,y) of every pixels of your image matrix representation into polar coordinates. So this effect has as purpose to project your image on a circle (see the illustration). To get this result, you have to calculate the polar coordinates r (a radius) and φ (an angle in radians) where r = sqrt(x2 + y2) and φ = 4*atan(y/x). Now, you can move every pixels to their new location (x',y') (only if x' and y' are inside the image matrix representation) where x' = r / 4 * cos(φ) + (image width/2) and y' = r / 4 * sin(φ) + (image height/2).
Wave effects :
Why wave effects and not wave effect? Because we will see exactly 3 types of wave : the horizontal and vertical ones and the combination of both. For the horizontal wave effect, each pixel with coordinates (x,y) must be replaced by the pixel located at (x',y) where x' = x + 20*sin(y * (2*4*atan(1))/128). Note that 4*atan(1) is a little trick I use to get exact value of π (3.141592653589793...) because atan(1) = π/4 so 4*atan(1) = π. For the vertical wave effect, the principle is similar, each pixel located at (x,y) must be replaced by the pixel located at (x,y') where y' = y + 20*sin(x * (2*4*atan(1))/128). The last wave effect can be obtained by replacing each pixel with coordinates (x,y) by the one located at (x',y'), it's just as easy as that. My waves function returns the desired effect according to the specified integer n :
Swirl effect :
The swirl effect is very similar to the polar effect. After calculating the polar coordinates
r = sqrt((x - image width/2)2 + (y - image height/2)2) and φ = r * (4*atan(1))/256 where (x,y) are the coordinates of the current pixel, this last one must be replaced by the pixel located at (x',y') where
x' = (x - width/2) * cos(φ) - (y - height/2) * sin(φ) + (width/2) and y' = (x - width/2) * sin(φ) + (y - height/2) * cos(φ) + (height/2). Note that this effect can be applied from another origin point than the middle of your image. You just have to change the parameters (image width/2) and (image height/2).
Ripple effect :
The ripple effect, like the swirl effect, can be applied at the origin point of your choice and you are free to set the number n of waves that will be generated and their amplification factor s. This time, after calculating the polar coordinates r = sqrt(x2 + y2) and φ = atan(y/x) where (x,y) are the coordinates of the current pixel, this last one must be replaced by the pixel located at (x',y') where
x' = (r + (s * cos((r/R) * 4*atan(1) / 2*n))) * cos(φ),
y' = (r + (s * cos((r/R) * 4*atan(1) / 2*n))) * sin(φ) and R = sqrt((width/2)2 + (height/2)2).
x' = (r + (s * cos((r/R) * 4*atan(1) / 2*n))) * cos(φ),
y' = (r + (s * cos((r/R) * 4*atan(1) / 2*n))) * sin(φ) and R = sqrt((width/2)2 + (height/2)2).
Warping effect :
The warping effect is probably the most disturbing distortion but actually, it can be useful for correcting image distortion or for the morphing which is a special effect that changes one image or shape into another through a seamless transition. To get the horizontal warping effect for example, you will have to replace any pixel with coordinates (x,y) by the pixel located at (x',y) where
x' = image width - (-sgn(x - (width/2)) / ((width/2) * (x - (width/2))2 + (width/2))).
Sgn is the sign function (details). Here is a source code example :
x' = image width - (-sgn(x - (width/2)) / ((width/2) * (x - (width/2))2 + (width/2))).
Sgn is the sign function (details). Here is a source code example :
According to plan, we will now see the use of some classic operators and their respective result using this image as the second test image :
So we have the image of Lena that we will name img1 and which contains a certain number of (Red1,Green1,Blue1) pixels, this new image, with the chameleon, that we will name img2 and which contains a certain number of (Red2,Green2,Blue2) pixels. Our goal is to create a new image that we will name img3.
Addition :
With this operation, the final image, img3, must contain (Red1+Red2, Green1+Green2, Blue1+Blue2) pixels. But you have to make sure that all sums result in values that are between 0 and 255.
Note that this rule must be applied to all the following functions.
Note that this rule must be applied to all the following functions.
Here is a source code example that will help to understand the following (I voluntarily created a third matrix, named matrix3, to well illustrate img1, img2 and the final result, img3 = img1 + img2) :
Subtraction left :
img3 must contain (Red1 - Red2, Green1 - Green2, Blue1 - Blue2) pixels.
Subtraction right :
img3 must contain (Red2 - Red1, Green2 - Green1, Blue2 - Blue1) pixels.
Difference :
img3 must contain (abs(Red1 - Red2), abs(Green1 - Green2), abs(Blue1 - Blue2)) pixels.
Note that abs is the absolute value function (details).
Average :
img3 must contain ((Red1+Red2) / 2, (Green1+Green2) / 2, (Blue1+Blue2) / 2)) pixels.
Multiplication :
img3 must contain
(255*(Red1/255 + Red2/255), 255*(Green1/255 + Green2/255), 255*(Blue1/255 + Blue2/255)) pixels. Note that in this case, you have to use floating point numbers when you are calculating x/255.
(255*(Red1/255 + Red2/255), 255*(Green1/255 + Green2/255), 255*(Blue1/255 + Blue2/255)) pixels. Note that in this case, you have to use floating point numbers when you are calculating x/255.
Cross Fading :
img3 must contain (Red1*f + Red2*f, Green1*f + Green2*f, Blue1*f + Blue2*f) pixels where f is a certain factor which must be between 0 and 1. The higher the value, the more brighter img3 will be. You can also choose different factors for each channel and here is a random idea, if you know how to horizontally or vertically flip an image (which is very easy), you can try to apply a cross fading effect between the original image and its reverse like that :
Amplitude :
img3 must contain
(sqrt(Red12 + Red22)/sqrt 2, sqrt(Green12 + Green22)/sqrt 2, sqrt(Blue12 + Blue22)/sqrt 2) pixels.
(sqrt(Red12 + Red22)/sqrt 2, sqrt(Green12 + Green22)/sqrt 2, sqrt(Blue12 + Blue22)/sqrt 2) pixels.
Min :
img3 must contain (min(Red1,Red2), min(Green1,Green2), min(Blue1,Blue2)) pixels.
Max :
img3 must contain (max(Red1,Red2), max(Green1,Green2), max(Blue1,Blue2)) pixels.
...
It exists many others functions between 2 images like the boolean operations for example (AND, OR, XOR...) but the results were too terrifying! Apart from that, why not a bonus filter to finish this post? Have you ever heard about the anaglyphs? It's the name given to the stereoscopic 3D effect which allows you to see an image in 3D with your super stereoscopic glasses . To get this effect, it's very easy. When you have chosen an image (img1), you have to create a new image (img2) which corresponds to a horizontal shift of img1 (don't make a too big horizontal shift). Then you can create your anaglyph which has the particularity that all its Red pixel components must be the Red pixel components of img1 and all its Green and Blue pixel components must be the ones of img2.
Here is my result with a horizontal shift of 10px to the right :
¿ Cool ?