UPD: The title has been changed to more closely match the topic of the article.The article discusses the use of the
convolution matrix (twisting matrix or convolution matrix), with which you can create and overlay filters on images, such as blur, sharpen and many others.
The article will be of interest not only to web programmers, but also to all who in one way or another are engaged in software image processing, since the functions for working with the curl matrix are available in many languages (exactly php and flash are known). Also, the article will be of interest to designers using Adobe Photoshop, because it contains the appropriate filter (Filter-Other-Custom).
')
The examples will be in PHP using the GD library. Theory, practice, examples (carefully, a lot of pictures!)
Theory
Speaking in non-mathematical terms,
convolution is the transformation of one matrix with the help of another, which is called the
kernel (“kernel”). When processing images, matrices of RGB channels of pixels in rectangular coordinates act as the source.
As the core, a 3x3 matrix is usually used, but possibly more (5x5, 7x7, etc.). The core contains the
degree of influence ("value") of the element's surrounding values on the element itself.
Conversion occurs as follows. Each element of the original matrix is multiplied by the central value of the core matrix. In addition, the surrounding elements are multiplied by the corresponding values (with a core size of 3x3, they will be 8), after which the results are summed up and accepted as the transformed value.
Here is a simple graphical example:

The value to be converted is highlighted in red, the core matrix is in green.
What was the result of the conversion? The values of all surrounding pixels, including the eigenvalue, are zero, except for the upper middle one, where it is equal to one. Thus, the result:
(40 * 0) + (42 * 1) + (46 * 0) + (46 * 0) + (50 * 0) + (55 * 0) + (52 * 0) + (56 * 0) + (58 * 0) = 42As you can see, this transformation shifts the image down by 1 pixel.
Thus,
convolution in this case is the transformation of the image, as a result of which the
surrounding region affects each pixel of the result. The degree of influence of this area is set using the “core” or twisting matrix.
Div and offset values
When processing images with only one transformation, you will not get off; you need more normalization. What if the resulting value is greater than 255 or less than 0? There are no such flowers. Moreover, the fact that going beyond the boundaries of color is a rather frequent phenomenon.
To normalize the result, additional variables are used: div (divisor) and offset (coefficient). They work very simply: the result of the conversion is divided by a div and offset is added to it.
It's not hard to guess that by default div = 1, offset = 0 (div = 0 cannot be set!).
In conversions, the sum of all elements of the twist matrix is usually taken as a div. This condition allows you to prevent color distortion if they are not needed.
Indeed, if the transformed region contains the same color, the result is obtained as the sum of the kernel elements multiplied by this color. Accordingly, in order to leave the color unchanged, it is necessary to divide the conversion result by this very amount.
A simple example: the negative filter.
As the source, we take the following image:

for example, it will be possible to see how large and small text, picture and lines change. Now create a twisting matrix to get the negative effect:

According to the matrix, it turns out that as a result of the transformation, all colors will have a negative value. For the colors to be negative, you need to set offset = 256, so the colors of all pixels are subtracted from 256, which is a negative image:

How it is done in PHP:
In the GD library in PHP, there is an
imageconvolution function that contains 4 parameters. The first is the image ID. The second is a matrix in the form of an array of 3 arrays with 3 variables. The third and fourth are div and offset.
Here is the code that makes the image negative:
<?php
$img = imagecreatefromjpeg( 'images/pattern.jpg' );
$matrix = array (
array( 0, 0, 0),
array( 0, -1, 0),
array( 0, 0, 0)
);
imageconvolution($img, $matrix, 1, 256);
imagejpeg($img, 'images/pattern_negative.jpg' , 100);
?>
* This source code was highlighted with Source Code Highlighter .
Immediately it is worth mentioning one very unpleasant feature of GD: when converting with the help of the imageconvolution, the alpha channel collapses. This
bug has been described for a long time , but as far as I know, it has not been fixed. There is no such thing in flash; moreover, there are additional parameters that are responsible for processing the edges of images when some pixels fall out. In php, the edges are simply not processed.
Blur, sharpen, emboss
Here is a standard set of effects matrices:

Note that for the blur coefficient div = 9. For such a matrix, only such a coefficient does not lead to color distortion. I must also say that there are several options for blur, they are slightly different in the strength of the effect.
And what are the resulting images:
Blur:
Sharpen:
Emboss:
"Neat" effects.
As can be seen from the last example with blur, the effect is superimposed on the image, but quite strongly. Is it possible to reduce the effect on the image? It turns out you can. But for this, it is necessary to change not the degree of influence of surrounding pixels, as it may seem at first glance, but the number of influencing pixels:

Then we get effects that will look much neater:
Light-blur:
Light-sharpen:
Light emboss:
It is worth asking here, but how to increase the strength of the effect? Unfortunately, only by its multiple overlap, because no matter how cool you are, the 3x3 pixel area is still processed. Naturally, this is very resource-intensive, in order to get a blur to the spots with the help of a Gaussian blur, sometimes you have to apply a filter 100-200 times. It takes a very long time and a lot of resources.
Finally
... I want to say that you yourself can create some interesting effect. To do this, it is enough to
experiment with the twisting matrix .
The twist matrix can be successfully applied when:- creating "small" pictures, for example. generating avatars and previews (especially light-blur looks good here).
- to create "shadows" (if it were still with the alpha channel ...)
- when creating a CAPTHCA (text + strong Sharpen or Emboss)
- and etc. :-)
UPD: Creating a cute shadow (Bonus-track, for php-programmers only)
/**
*
* ! !
*
* @param res $image -
* @param int $shadow_width - (1..10, )
* @param int $shadow_deep - (1..20, , )
* @param string $bg_color - #7def34
*/
function imageaddshadow (&$image, $shadow_width = 4, $shadow_deep = 7, $bg_color = false )
{
$w = imagesx($image);
$h = imagesy($image);
$iw = $w + 4*$shadow_width;
$ih = $h + 4*$shadow_width;
$img = imagecreatetruecolor($iw, $ih);
$shadow_deep= 255-$shadow_deep*12;
$shadow = imagecolorallocate($img, $shadow_deep, $shadow_deep, $shadow_deep);
if (!$bg_color) {
//
$bg = imagecolorallocate($img, 255, 255, 255);
}
else {
list($r, $g, $b) = array_map( 'hexdec' , str_split(ltrim($bg_color, '#' ), 2));
$bg = imagecolorallocate($img, $r+1, $g+1, $b+1);
}
//
imagefilledrectangle($img,0,0,$iw,$ih,$bg);
//
imagefilledrectangle($img,
1+$shadow_width,
1+$shadow_width,
$iw-1-$shadow_width,
$ih-1-$shadow_width,
$shadow);
//
$matrix = array (
array( 1, 1, 1),
array( 1, 1, 1),
array( 1, 1, 1)
);
//
for ($i=0; $i < $shadow_width*2; $i++, imageconvolution($img, $matrix, 9, 0));
//
imagecopyresampled($img, $image, 2*$shadow_width,2*$shadow_width,0,0,$w,$h,$w,$h);
// !
$image = $img;
}
* This source code was highlighted with Source Code Highlighter .
Result:

Thanks for reading! Constructive criticism and indication of grammatical errors
with the help of the PM is welcome.