Introduction to Gaussian filter
I try to introduce these interesting things as low as possible ~ Here, we only need the normal distribution function as the basis to start playing the Gaussian filter of the image. Don't panic!
In general, there are many pixels in an image. In many cases, a large pixel is used to record a scene area, in this case, the digital discrete environment is used to simulate the continuity of color changes in real life (note that the computer's discrete environment is a real simulation .)
What is Gaussian filtering? In one sentence, the Gaussian function is used to obtain the weights and perform weighted average in a region!
Simple things should never be complicated. What is the definition of an engineer? The simpler the engineer is, the better. There is no difficult problem in the world, but the people who explain it are not straightforward enough.
The formula is here. How can this problem be solved? The following program is used to "experience" and comprehend Gaussian filtering.
X y indicates the distance from the center.
The simplest single-channel black/white image processing function (short enough to describe the algorithm) is provided here. The implementation function of the color image will be provided later. In order to make the program algorithm easier to understand, I try not to call the MATLAB API and use the C language to compile the demo program ).
The following program has not been optimized
(I am worried that the program will be easier to understand than the original algorithm after optimization... so when the user calls the Kernel Window relatively large (kernel_size> 11), the program will be slower)
%***********************************************************% code writer : EOF% code file : test.m% code date : 2014.10.25% e-mail : [email protected]%% Code Description:%% Here is my implementation of gaussian filter which% is only work for single channel image.%% If you find something wrong with my code ,please touch% me by e-mail.%**************************************************************function Output = gaussian_filter_for_dark_Image(Image,Kernel_size,epsilon) if size(Image,3) ~= 1 fprintf('Hey guys, please input a single channel image.\n'); end Location_X = zeros(Kernel_size,Kernel_size); Location_Y = zeros(Kernel_size,Kernel_size); %% Initialization for original Location. for row = 1 : Kernel_size for col = 1 : Kernel_size Location_X(row ,col) = (col -1) - floor(Kernel_size/2); Location_Y(row ,col) = (row -1) - floor(Kernel_size/2); end end Kernel = zeros(Kernel_size,Kernel_size); for row = 1 : Kernel_size for col = 1 : Kernel_size % Oh , Attention. Here we are gonna to compute the Kernel of % our filter. Kernel(row,col) = (1/(2*pi*(epsilon.^2))) * ... exp( - (Location_X(row,col).^2 + Location_Y(row,col).^2)./(2* (epsilon.^2) )); end end Image_Height = size(Image,1); Image_Width = size(Image,2); Output = zeros(Image_Height,Image_Width); for row = 1: Image_Height for col = 1: Image_Width sum_value = 0; % Set the patch start location and end location. Kernel_row_start = row - floor(Kernel_size/2); Kernel_col_start = col - floor(Kernel_size/2); Kernel_row_end = row + floor(Kernel_size/2); Kernel_col_end = col + floor(Kernel_size/2); for Kernel_row = Kernel_row_start : Kernel_row_end for Kernel_col = Kernel_col_start : Kernel_col_end %% Sum all weighted neighboring pixel by gaussian distribution. if Kernel_row > 0 && Kernel_col > 0 && ... Kernel_row <= Image_Height && Kernel_col <= Image_Width sum_value = sum_value + ... Kernel(Kernel_row - Kernel_row_start + 1,... Kernel_col - Kernel_col_start + 1) *... Image(Kernel_row,Kernel_col); end end end Output(row,col) = sum_value; end end end
Test:
Parameter: kernel_size = 11, Epsilon = 2.5
The left is the input image, and the right is the result of filtering.
If you carefully analyze the Gaussian weights obtained by kernel_size, you will find that the kernel_size is too large, which makes no practical sense. generally, the results of 7 and 11 are very similar. Epsilon is the one that really affects the blur effect. Here, the Epsilon value is 2.5. If you have a smaller value, the Blur degree of the image will be weak (that is, clear)
Since the Gaussian filter of a single-channel image is completed, the Gaussian filter of a color image becomes logical and simple.
Here I integrate single-channel and three-channel image Gaussian filtering to write a function (, I love robust)
Why is the three channels so long? I feel like I have been running for a long time... I still need to optimize it later.
The output result of kernel_win_size = 3 and epsilon = 1.5 is as follows:
The source image is on the left and the filtered result is on the right.
%***********************************************************% code writer : EOF% code file : gaussian_filter_for_Image.m% code date : 2014.10.25% e-mail : [email protected]%% Code Description:%% Here is my implementation of gaussian filter .% % Parameter @Image is the inputed image, @Kernel_size % describe the size of filter kernel and @epsilon is the % parameter in normal-distribution which you are familiar with.%% If you find something wrong with my code ,please touch% me by e-mail.%**************************************************************function Output = gaussian_filter_for_Image(Image,Kernel_size,epsilon) if size(Image,3) ~= 1 && size(Image,3) ~= 3 fprintf('Hey guys, please input a single or three channel image.\n'); end Location_X = zeros(Kernel_size,Kernel_size); Location_Y = zeros(Kernel_size,Kernel_size); %% Initialization for original Location. for row = 1 : Kernel_size for col = 1 : Kernel_size Location_X(row ,col) = (col -1) - floor(Kernel_size/2); Location_Y(row ,col) = (row -1) - floor(Kernel_size/2); end end Kernel = zeros(Kernel_size,Kernel_size); for row = 1 : Kernel_size for col = 1 : Kernel_size % Oh , Attention. Here we are gonna to compute the Kernel of % our filter. Kernel(row,col) = (1/((2*pi*(epsilon.^2)))) * ... exp( - (Location_X(row,col).^2 + Location_Y(row,col).^2)./(2* (epsilon.^2) )); end end sum_of_Kernel = sum(Kernel(:)); Image_Height = size(Image,1); Image_Width = size(Image,2); if size(Image,3) == 1 Output = zeros(Image_Height,Image_Width); else Output = zeros(Image_Height,Image_Width,3); end for row = 1: Image_Height for col = 1: Image_Width % Set the patch start location and end location. Kernel_row_start = row - floor(Kernel_size/2); Kernel_col_start = col - floor(Kernel_size/2); Kernel_row_end = row + floor(Kernel_size/2); Kernel_col_end = col + floor(Kernel_size/2); for channel = 1: size(Image,3) sum_value = 0; for Kernel_row = Kernel_row_start : Kernel_row_end for Kernel_col = Kernel_col_start : Kernel_col_end %% Sum all weighted neighboring pixel by gaussian distribution. if Kernel_row > 0 && Kernel_col > 0 && ... Kernel_row <= Image_Height && Kernel_col <= Image_Width sum_value = sum_value + ... Kernel(Kernel_row - Kernel_row_start + 1,... Kernel_col - Kernel_col_start + 1) *... Image(Kernel_row,Kernel_col,channel); end end end %% % Never forget to divide 'sum_of_kernel', otherwise your outputed image % would looks like more dark than original image. Output(row,col,channel) = sum_value/sum_of_Kernel; end end end end
Q:
You may have encountered the following Gaussian filter kernel"
In fact, this is the distribution data that has been computed by others and then directly used.
Here we use the highly customizable window size kernel_size.
The essence is the same
Don't panic :)
Introduction to Gaussian filter