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

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

问题描述

我在 MATLAB 中有以下代码:

I=imread(image);h=fspecial('gaussian',si,sigma);I=im2double(I);I=imfilter(I,h,'conv');图,imagesc(I),impixelinfo,title('卷积高斯后的原始图像'),colormap('灰色');

如何定义高斯滤波器并将其应用于没有 imfilterfspecialconv2 的图像?

解决方案

很遗憾您无法使用 Image Processing Toolbox 中的一些内置方法来帮助您完成此任务.但是,我们仍然可以按照您的要求进行操作,尽管这会更困难一些.我仍将使用 IPT 的一些功能来帮助我们完成您的要求.此外,我将假设您的图像是灰度.如果您想对彩色图像执行此操作,我会留给您.

<小时>

创建高斯蒙版

您可以做的是使用 这将采用像素邻域并将它们变成列.im2col 将获取这些列中的每一列并创建一个矩阵,其中每一列代表一个像素邻域.

接下来我们可以做的是获取我们的高斯掩码并将其转换为列向量.接下来,我们将获取这个列向量,并根据 im2col 的结果将其复制到尽可能多的列中以创建...我们将其称为高斯矩阵,因为缺少更好的术语.使用这个高斯矩阵,我们将与这个矩阵和 im2col 的输出进行逐个元素的乘法.一旦我们这样做,我们就可以对每列的所有行求和.进行这种逐元素乘法的最佳方法是通过 bsxfun,我很快就会告诉你如何使用它.

这样做的结果将是您过滤后的图像,但它将是一个向量.您需要使用 col2im 得到我们过滤后的图像.然而,这种方法的一个小问题是它不会过滤空间掩码超出图像尺寸的像素.因此,您实际上需要用零填充图像的边框,以便我们可以正确地进行过滤.我们可以使用 padarray 做到这一点.

因此,我们的代码将类似于您在上面定义的变量:

N = 5;%//定义高斯掩码的大小西格玛 = 2;%//这里定义 sigma%//生成高斯掩码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(:);%//过滤我们的图像我 = 已读(图像);我 = im2double(I);I_pad = padarray(I, [楼层(N/2) 楼层(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天全站免登陆