如何在不使用fspecial,imfilter或conv2的情况下在MATLAB中创建和应用高斯滤波器? [英] How do I create and apply a Gaussian filter in MATLAB without using fspecial, imfilter or conv2?

查看:183
本文介绍了如何在不使用fspecial,imfilter或conv2的情况下在MATLAB中创建和应用高斯滤波器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在MATLAB中有以下代码:

  I = imread(image); 
h = fspecial('gaussian',si,sigma);
I = im2double(I);
I = imfilter(I,h,'conv');
figure,imagesc(I),impixelinfo,title('与高斯讨论后的原始图像'),colormap('gray');

如何在没有 imfilter <的情况下为图像定义和应用高斯滤波器/ code>, fspecial conv2

解决方案

非常不幸的是,您无法使用图像处理工具箱中的某些内置方法来帮助您完成此任务。但是,我们仍然可以按照您的要求进行操作,但会有点困难。我仍然会使用IPT中的一些功能来帮助我们按照你的要求去做。此外,我将假设您的图像是灰度。如果您想为彩色图像执行此操作,我会留给您。






创建高斯蒙版



你可以做的是使用将占用像素邻域并将其转换为列。 im2col 将获取每个列并创建一个矩阵,其中每列代表一个像素邻域。



我们接下来要做的就是将高斯模板和转换这个变成列向量。接下来,我们将获取此列向量,并将此复制为我们从 im2col 的结果中创建的多个列以创建...让我们将其称为高斯矩阵缺乏一个更好的术语。使用这个高斯矩阵,我们将使用此矩阵和 im2col 的输出进行逐元素乘法。一旦我们这样做,我们可以总结每列的所有行。逐个元素乘法的最佳方法是通过 bsxfun ,我将尽快向您展示如何使用它。



结果将是您的过滤图像,但它将是一个单一的向量。您需要使用 col2im将此向量重新整形为矩阵形式 获取我们的滤镜图片。然而,这种方法的一个小问题是它不会过滤空间掩模超出图像尺寸的像素。因此,您实际上需要用零填充图像的边框,以便我们可以正确地执行过滤器。我们可以使用 padarray 来完成此操作



因此,我们的代码看起来像这样,与您在上面定义的变量一起使用:

  N = 5; %//定义高斯蒙版的大小
sigma = 2; %//在此定义西格玛

%//生成高斯掩码
ind = -floor(N / 2):floor(N / 2);
[X Y] = meshgrid(ind,ind);
h = exp( - (X. ^ 2 + Y. ^ 2)/(2 * sigma * sigma));
h = h / sum(h(:));

%//将过滤器转换为列向量
h = h(:);

%//过滤我们的图像
I = imread(image);
I = im2double(I);
I_pad = padarray(I,[floor(N / 2)floor(N / 2)]);
C = im2col(I_pad,[N N],'滑动');
C_filter = sum(bsxfun(@times,C,h),1);
out = col2im(C_filter,[N N],size(I_pad),'sliding');






out 包含将高斯过滤蒙版应用于输入图像 I 后的过滤图像。例如,假设 N = 9,sigma = 4 。我们还使用 cameraman.tif 这是一个MATLAB系统路径的图像。通过使用上述参数以及图像,这是我们得到的输入和输出图像:






I have the following code in MATLAB:

I=imread(image);
h=fspecial('gaussian',si,sigma);
I=im2double(I);
I=imfilter(I,h,'conv');
figure,imagesc(I),impixelinfo,title('Original Image after Convolving with gaussian'),colormap('gray');

How can I define and apply a Gaussian filter to an image without imfilter, fspecial and conv2?

解决方案

It's really unfortunate that you can't use the some of the built-in methods from the Image Processing Toolbox to help you do this task. However, we can still do what you're asking, though it will be a bit more difficult. I'm still going to use some functions from the IPT to help us do what you're asking. Also, I'm going to assume that your image is grayscale. I'll leave it to you if you want to do this for colour images.


Create Gaussian Mask

What you can do is create a grid of 2D spatial co-ordinates using meshgrid that is the same size as the Gaussian filter mask you are creating. I'm going to assume that N is odd to make my life easier. This will allow for the spatial co-ordinates to be symmetric all around the mask.

If you recall, the 2D Gaussian can be defined as:

The scaling factor in front of the exponential is primarily concerned with ensuring that the area underneath the Gaussian is 1. We will deal with this normalization in another way, where we generate the Gaussian coefficients without the scaling factor, then simply sum up all of the coefficients in the mask and divide every element by this sum to ensure a unit area.

Assuming that you want to create a N x N filter, and with a given standard deviation sigma, the code would look something like this, with h representing your Gaussian filter.

%// Generate horizontal and vertical co-ordinates, where
%// the origin is in the middle
ind = -floor(N/2) : floor(N/2);
[X Y] = meshgrid(ind, ind);

%// Create Gaussian Mask
h = exp(-(X.^2 + Y.^2) / (2*sigma*sigma));

%// Normalize so that total area (sum of all weights) is 1
h = h / sum(h(:));

If you check this with fspecial, for odd values of N, you'll see that the masks match.


Filter the image

The basics behind filtering an image is for each pixel in your input image, you take a pixel neighbourhood that surrounds this pixel that is the same size as your Gaussian mask. You perform an element-by-element multiplication with this pixel neighbourhood with the Gaussian mask and sum up all of the elements together. The resultant sum is what the output pixel would be at the corresponding spatial location in the output image. I'm going to use the im2col that will take pixel neighbourhoods and turn them into columns. im2col will take each of these columns and create a matrix where each column represents one pixel neighbourhood.

What we can do next is take our Gaussian mask and convert this into a column vector. Next, we would take this column vector, and replicate this for as many columns as we have from the result of im2col to create... let's call this a Gaussian matrix for a lack of a better term. With this Gaussian matrix, we will do an element-by-element multiplication with this matrix and with the output of im2col. Once we do this, we can sum over all of the rows for each column. The best way to do this element-by-element multiplication is through bsxfun, and I'll show you how to use it soon.

The result of this will be your filtered image, but it will be a single vector. You would need to reshape this vector back into matrix form with col2im to get our filtered image. However, a slight problem with this approach is that it doesn't filter pixels where the spatial mask extends beyond the dimensions of the image. As such, you'll actually need to pad the border of your image with zeroes so that we can properly do our filter. We can do this with padarray.

Therefore, our code will look something like this, going with your variables you have defined above:

N = 5; %// Define size of Gaussian mask
sigma = 2; %// Define sigma here

%// Generate Gaussian mask
ind = -floor(N/2) : floor(N/2);
[X Y] = meshgrid(ind, ind);
h = exp(-(X.^2 + Y.^2) / (2*sigma*sigma));
h = h / sum(h(:));

%// Convert filter into a column vector
h = h(:);

%// Filter our image
I = imread(image);
I = im2double(I);
I_pad = padarray(I, [floor(N/2) floor(N/2)]);
C = im2col(I_pad, [N N], 'sliding');
C_filter = sum(bsxfun(@times, C, h), 1);
out = col2im(C_filter, [N N], size(I_pad), 'sliding');


out contains the filtered image after applying a Gaussian filtering mask to your input image I. As an example, let's say N = 9, sigma = 4. Let's also use cameraman.tif that is an image that's part of the MATLAB system path. By using the above parameters, as well as the image, this is the input and output image we get:

这篇关于如何在不使用fspecial,imfilter或conv2的情况下在MATLAB中创建和应用高斯滤波器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆