图像滤波笔记

0、读取图片,预处理为灰度图(matlab代码)

%% read image
imdir = 'F:\pictures\壁纸\';
imname = 'image (1)';
impath  = strcat(imdir, imname, '.jpg');
ori_image = imread(impath);
conv_image = ori_image;
gray_image = rgb2gray(ori_image);
[x, y] = size(gray_image);

1、均值滤波

均值滤波介绍:

http://baike.baidu.com/link?url=kKT1uID3Z_FMRnVwehdQehCojPUJjsO1Hi8tJnaFRfduNvAMiaije42AyI7g_ofTsWEM31PqX958Rrw0WlJ-ZK

相关:

卷积:

%% set mean filter
kernel_x = 15;
kernel_y = 15;
kernel = (1/(kernel_x * kernel_y)) * ones(kernel_x, kernel_y);
%% corr
corr_image = uint8(imfilter(double(gray_image), double(kernel)));
corr_image_path = strcat(imdir, imname, '_corr.jpg');
imwrite(corr_image, corr_image_path, 'jpg');
%% conv
conv_image = uint8(conv2(double(gray_image), double(kernel), 'same'));
conv_image_path = strcat(imdir, imname, '_conv.jpg');
imwrite(conv_image, conv_image_path, 'jpg');

左边:均值滤波+相关, 右边:均值滤波+卷积,  可以看出卷积和相关的结果区别不大

均值滤波+卷积

2、高斯滤波

%% set gaussian filter
n  = 10;
o = (1+n)/2;
sigma = 2;
gk = double(zeros(n, n));
for i = 1:n
    for j = 1:n
        gk(i,j) = exp(-((i-o)^2 + (j-o)^2) / (2 * sigma^2));
    end
end
fac = sum(sum(gk));
gk = gk / fac;
%% conv with gaussian filter
for i = 1:3
    conv_image(:,:,i) = uint8(conv2(double(ori_image(:,:,i)), double(gk), 'same'));
end
conv_image_path = strcat(imdir, imname, '_gk.jpg');
imwrite(conv_image, conv_image_path, 'jpg');

3、定向高斯滤波

%% set oriented gaussian filter
n  = 20;
o = (1+n)/2;
sigma = 5;
ogk = double(zeros(n, n));
a = 0.0000001; b= 10;
sigma_matrix = [a, 0; 0, b];
orient1 = [1,1]; orient2 = [-1,1];
orient = [orient1;orient2];
sigma_matrix = orient' * sigma_matrix;
sigma_matrix = sigma_matrix * orient;
for i = 1:n
    for j = 1:n
        ogk(i,j) = 1 / exp(([i-o,j-o]*sigma_matrix*[i-o;j-o]) / (2 * sigma^2));
    end
end
imshow(ogk);
fac = sum(sum(ogk));
ogk = ogk / fac;
%% conv with gaussian filter
for i = 1:3
    conv_image(:,:,i) = uint8(conv2(double(ori_image(:,:,i)), double(ogk), 'same'));
end
conv_image_path = strcat(imdir, imname, '_ogk.jpg');
imwrite(conv_image, conv_image_path, 'jpg');

可以明显感觉到方向:\\\\\

4、图像微分

%% image derivatives
dx = [0,-1,0; -1,0,1; 0,1,0];
conv_image = uint8(conv2(double(gray_image), double(dx), 'same'));
% constrain image range from 0 to 255
minv = min(min(conv_image));
if minv < 0
    conv_image = conv_image - minv;
end
maxv = max(max(conv_image));
minv = min(min(conv_image));
factor = (255 - 0) / (maxv - minv + 1);
conv_image = conv_image * factor + 0;
% write image
conv_image_path = strcat(imdir, imname, '_dx.jpg');
imwrite(conv_image, conv_image_path, 'jpg');

5、一阶高斯滤波(DoG)、方向一阶高斯滤波

高斯函数和各阶导数:http://blog.csdn.net/lyapple2008/article/details/8087317

由于图像微分会产生噪声,所以将高斯平滑与图像微分结合起来,就得到了DoG。

DoG加上方向就得到有方向的一阶高斯滤波:

%% set derivatives of gaussian (DoG)
n  = 8;
o = (1+n)/2;
sigma = 2;
theta = -pi/4;
dog = double(zeros(n, n));
dogx = dog; dogy = dog; ddog = dog;
for i = 1:n
    for j = 1:n
        dogx(i,j) = -(i-o) * exp(-((i-o)^2 + (j-o)^2) / (2 * sigma^2)); 
        dogy(i,j) = -(j-o) * exp(-((i-o)^2 + (j-o)^2) / (2 * sigma^2));
        dog(i,j) = dogx(i,j) + dogy(i,j);
        ddog(i,j) = dogx(i,j)*cos(theta) + dogy(i,j)*sin(theta);
   end
end
%% conv with DoG
% both x and y axis
conv_image = conv2(double(gray_image), double(dog), 'same');
% constrain image range from 0 to 255
minv = min(min(conv_image));
if minv < 0
    conv_image = conv_image - minv;
end
maxv = max(max(conv_image));
minv = min(min(conv_image));
factor = (255 - 0) / (maxv - minv + 1);
conv_image = conv_image * factor + 0;
% write image
conv_image_path = strcat(imdir, imname, '_dog.jpg');
imwrite(uint8(conv_image), conv_image_path, 'jpg');

% DoG on vertical axis, remain the lines on horizontal axis
conv_image = conv2(double(gray_image), double(dogx), 'same');
minv = min(min(conv_image));
if minv < 0
    conv_image = conv_image - minv;
end
maxv = max(max(conv_image));
minv = min(min(conv_image));
factor = (255 - 0) / (maxv - minv + 1);
conv_image = conv_image * factor + 0;
conv_image_path = strcat(imdir, imname, '_dogx.jpg');
imwrite(uint8(conv_image), conv_image_path, 'jpg');

% DoG on horizontal axis, remain the lines on vertical axis
conv_image = conv2(double(gray_image), double(dogy), 'same');
minv = min(min(conv_image));
if minv < 0
    conv_image = conv_image - minv;
end
maxv = max(max(conv_image));
minv = min(min(conv_image));
factor = (255 - 0) / (maxv - minv + 1);
conv_image = conv_image * factor + 0;
conv_image_path = strcat(imdir, imname, '_dogy.jpg');
imwrite(uint8(conv_image), conv_image_path, 'jpg');

% DoG on derection of theta
conv_image = conv2(double(gray_image), double(ddog), 'same');
minv = min(min(conv_image));
if minv < 0
    conv_image = conv_image - minv;
end
maxv = max(max(conv_image));
minv = min(min(conv_image));
factor = (255 - 0) / (maxv - minv + 1);
conv_image = conv_image * factor + 0;
conv_image_path = strcat(imdir, imname, '_ddog.jpg');
imwrite(uint8(conv_image), conv_image_path, 'jpg');

下图,第一张为dogx滤波结果(可以看出保留了大量水平方向的边缘),第二张为dogy滤波结果(可以看出保留了大量竖直方向上的边缘)

 

下图,第一张为DoG滤波结果(可以与上图两张比较一下,同时保留了两个方向的边缘),第二张为-pi/4方向上的DoG(可以看出保留了大量 “\\\\\\” 这样的边缘)

 

6、二阶高斯滤波(LoG)

LoG可以用DoG来近似:

%% set laplacian of gaussian (DoG)
% n  = 5;
% o = (1+n)/2;
% sigma = 0.8;
% theta = pi/4;
% log = double(zeros(n, n));
% logx = log; logy = log; dlog = log;
% for i = 1:n
%     for j = 1:n
%         logx(i,j)=-(((i-o)^2 - sigma^2)/(2*pi*sigma^4))*exp(-((i-o)^2 + (j-o)^2)/(2 * sigma^2));
%         logy(i,j)=-(((j-o)^2 - sigma^2)/(2*pi*sigma^4))*exp(-((i-o)^2 + (j-o)^2)/(2 * sigma^2));
%         log(i,j) = logx(i,j) + logy(i,j);
%         dlog(i,j) = logx(i,j)*cos(theta) + logy(i,j)*sin(theta);
%    end
% end
log=[-2,-4,-4,-4,-2;...
    -4,0,8,0,-4;...
    -4,8,24,8,-4;...
    -4,0,8,0,-4;...
    -2,-4,-4,-4,-2];
%% conv with LoG
conv_image = conv2(double(gray_image), double(log), 'same');
minv = min(min(conv_image));
if minv < 0
    conv_image = conv_image - minv;
end
maxv = max(max(conv_image));
minv = min(min(conv_image));
factor = (255 - 0) / (maxv - minv + 1);
conv_image = conv_image * factor + 0;
conv_image_path = strcat(imdir, imname, '_log.jpg');
imwrite(uint8(conv_image), conv_image_path, 'jpg');

*上面的代码直接用LoG模版来计算的,这与上面被注释掉的代码是等价的。

LoG的介绍:

http://baike.soso.com/v61649603.htm

从上面的结果图可以看出,LoG的滤波结果比DoG更精细,可能是因为LoG抹去了更多的噪声。此外,log适合用在圆形的边缘上。

附:DoG和LoG的图形

sigma = 2;
x=linspace(-10,10,200);
y=linspace(-10,10,200);
[xx,yy]=meshgrid(x,y);
dog = ((-xx./(2*pi*sigma^4)).*exp(-((xx).^2 + (yy).^2)./(2 * sigma^2)))...
    + ((-yy./(2*pi*sigma^4)).*exp(-((xx).^2 + (yy).^2)./(2 * sigma^2)));

log = (((xx.^2 - sigma^2)./(2*pi*sigma^4)).*exp(-(xx.^2 + yy.^2)./(2 * sigma^2)))...
    +(((yy.^2 - sigma^2)./(2*pi*sigma^4)).*exp(-(xx.^2 + yy.^2)./(2 * sigma^2)));
figure;
mesh(xx,yy,dog);
figure;
mesh(xx,yy,log);

 

转载于:https://www.cnblogs.com/mender/p/3489705.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在数字图像处理中,图像滤波是非常常见的一种操作。而均值滤波和高斯滤波是最常见的滤波算法之一。下面我们就来介绍一下均值滤波和高斯滤波的原理和实现。 ## 1. 均值滤波 均值滤波是最简单的一种线性滤波算法。其原理是对图像中每个像素点的邻域像素进行平均值操作,以达到去除噪声的目的。均值滤波的模板可以是任意大小的,通常使用 3×3 或 5×5 的模板。 ### 1.1 均值滤波原理 均值滤波的原理是将图像中每个像素点的邻域像素值进行平均,然后将该平均值作为当前像素点的像素值。均值滤波可以消除图像中的噪声,但是也会导致图像的模糊。 ### 1.2 均值滤波实现 均值滤波的实现非常简单,只需要对每个像素点的邻域像素值进行求和,然后再除以邻域像素的数量即可。具体步骤如下: 1. 定义一个与原图像大小相同的新图像。 2. 对每个像素点的邻域像素进行求和,然后求平均值。 3. 将平均值作为当前像素点的像素值,赋值给新图像。 代码实现如下: ```java public static BufferedImage meanFilter(BufferedImage img, int size) { int width = img.getWidth(); int height = img.getHeight(); int half = size / 2; BufferedImage result = new BufferedImage(width, height, img.getType()); for (int i = half; i < height - half; i++) { for (int j = half; j < width - half; j++) { int sum = 0; for (int k = -half; k <= half; k++) { for (int l = -half; l <= half; l++) { sum += new Color(img.getRGB(j + l, i + k)).getRed(); } } int value = sum / (size * size); result.setRGB(j, i, new Color(value, value, value).getRGB()); } } return result; } ``` 其中,size 为模板大小。 ## 2. 高斯滤波 高斯滤波是一种线性平滑滤波算法,与均值滤波不同的是,它使用的是高斯核函数。高斯核函数可以减小图像中噪声的影响,同时也不会使图像过度模糊。 ### 2.1 高斯滤波原理 高斯滤波的原理是利用高斯函数的特性,对图像中每个像素点的邻域像素值进行加权平均,以达到去除噪声的目的。高斯滤波也可以消除图像中的噪声,同时保留更多的图像细节。 ### 2.2 高斯滤波实现 高斯滤波的实现需要先生成一个高斯核,然后对每个像素点的邻域像素进行加权平均。具体步骤如下: 1. 定义一个与原图像大小相同的新图像。 2. 生成一个高斯核。 3. 对每个像素点的邻域像素进行加权平均,然后将加权平均值作为当前像素点的像素值,赋值给新图像。 代码实现如下: ```java public static BufferedImage gaussianFilter(BufferedImage img, int size, double sigma) { int width = img.getWidth(); int height = img.getHeight(); int half = size / 2; double[][] kernel = gaussianKernel(size, sigma); BufferedImage result = new BufferedImage(width, height, img.getType()); for (int i = half; i < height - half; i++) { for (int j = half; j < width - half; j++) { double sum = 0; for (int k = -half; k <= half; k++) { for (int l = -half; l <= half; l++) { int pixel = new Color(img.getRGB(j + l, i + k)).getRed(); sum += kernel[k + half][l + half] * pixel; } } int value = (int) Math.round(sum); value = Math.min(255, Math.max(0, value)); result.setRGB(j, i, new Color(value, value, value).getRGB()); } } return result; } ``` 其中,size 为高斯核大小,sigma 为高斯核标准差。 高斯核函数的生成可以使用以下代码: ```java public static double[][] gaussianKernel(int size, double sigma) { double[][] kernel = new double[size][size]; double sum = 0; int half = size / 2; for (int i = -half; i <= half; i++) { for (int j = -half; j <= half; j++) { kernel[i + half][j + half] = Math.exp(-(i * i + j * j) / (2 * sigma * sigma)); sum += kernel[i + half][j + half]; } } for (int i = 0; i < size; i++) { for (int j = 0; j < size; j++) { kernel[i][j] /= sum; } } return kernel; } ``` 以上就是均值滤波和高斯滤波的原理和实现。需要注意的是,滤波操作会导致图像的模糊,因此在使用滤波算法时需要根据具体应用场景选择合适的滤波方法和参数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值