Simple image filters

We are going to apply simple finite convolution filters to an RGB image. The convolution is done on each color channel and it is computed with this octave code.

We take as test images a somewhat artistic photo and another somewhat more geometric.

pumpkins0 bump0

Three extremely simple but effective filters are the sharpen, Laplacian and emboss filters given by 3x3 matrices.

 
0-10
S= -15-1
  0-10
 
 
0-10
L= -14-1
  0-10
 
 
-2-10
E= -111
  012

The first filter emphasize the edges. For a uniform color it does not change anything because the sum of the entries is one but if the crux containing a pixel is uncompensated then it is magnified. By the way, the values are clipped to [0,1] in the following images. If we sharpen too much then the pixels saturate to their extreme values.

filti_s1 filti_s2
Sharpen Sharpen twice

The Laplacian filter gives 0 (black) for an uniform color. It is like subtracting to the sharpen filter the original image and then it is an edge detector. Its performance is better appreciated in B/W images. It gives a not bad result using the geometric image

filti_l1 filti_l2
Laplacian first image Laplacian second image

It is much more difficult to predict the effect of the emboss filter if one forgets the name and only examines the matrix. It establishes a kind of bump map along the diagonal and the result is, no wonder, as embossing. To the left is repeated the original image to ease the comparison.

pumpkins filti_e
Original image Emboss

Finally we will consider different filters to blur the second image. The most obvious is to take the average of the values of the pixel surrounding each one in a square of certain side. The sharp cut of the square gives results "less blended" than the application of an average weighted with a Gaussian distribution function for certain standard deviation.

filti_b filti_g
Mean side=11 Gaussian sigma=4

If we take the average on only a row of the square then the blurring seems to be horizontal, this is called a motion blur. Another instance is to take the identity matrix to express a diagonal motion. As diagonal and sizes for a square are related through the square root of 2, which is close to 10/7, the following examples make sense for comparison:

filti_m filti_d
Horizontal blur dim=10 Diagonal blur dim=7


The code

This is the octave code that applies the filters:


pkg load image

%FOR EVEN DIMENSIONS imfilter (...'conv') AND conv2
%DO NOT COINCIDE, THEY ARE SHIFTED

clear all


ima = imread('../images/bump0.jpg');
ima = im2double(ima);


%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%% BLUR %%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%

% Mean blur
F = ones(11)/121;
imagf = imfilter( ima, F, 'same', 'conv', 'symmetric');
imwrite(imagf,'./filti_b.jpg');


% Gaussian blur
imagf = imsmooth( ima, "Gaussian", 4);
imwrite(imagf,'./filti_g.jpg');

% Higher Gaussian
%F = [1,4,6,4,1; 4,16,24,16,4; 6,24,36,24,6; %4,16,24,16,4; 1,4,6,4,1]/256;
%imagf = imfilter( ima, F, 'same', 'conv', 'symmetric');
%imwrite(imagf,'./filti_4.jpg');


% Motion blur
N = 10;
F = zeros(N);
F(1,:)=ones(1,N)/N;
imagf = imfilter( ima, F, 'same', 'conv', 'symmetric');
imwrite(imagf,'./filti_m.jpg');


% Motion diagonal 6
F = eye(7)/7;
imagf = imfilter( ima, F, 'same', 'conv', 'symmetric');
imwrite(imagf,'./filti_d.jpg');

imak = ima;


ima = imread('../images/pumpkins0.jpg');
ima = im2double(ima);


%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%% EMBOSS %%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%

% Emboss (clamped)
F = [-2 -1 0;-1 1 1;0 1 2];
imagf = imfilter( ima, F, 'same', 'conv', 'symmetric');
imwrite(imagf,'./filti_e.jpg');


%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%% LAPLACE %%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%

% Laplace B/W
F = [0 1 0;1 -4 1;0 1 0];
imagf = imfilter( rgb2gray(ima), F, 'same', 'conv', 'symmetric');
imwrite(imagf,'./filti_l1.jpg');

% Laplace first image B/W
imagf = imfilter( rgb2gray(imak), F, 'same', 'conv', 'symmetric');
imwrite(imagf,'./filti_l2.jpg');


%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%% SHARPEN %%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%

% Sharpen (clamped)
F = [0 -1 0;-1 5 -1;0 -1 0];
imagf = imfilter( ima, F, 'same', 'conv', 'symmetric');
imwrite(imagf,'./filti_s1.jpg');

% Sharpen twice
F = [0 -1 0;-1 5 -1;0 -1 0];
imagf = imfilter( ima, F, 'same', 'conv', 'symmetric');
imagf = imfilter( imagf, F, 'same', 'conv', 'symmetric');
imwrite(imagf,'./filti_s2.jpg');