寻找噪声图像边缘的最佳方法

Best method to find edge of noise image

我有一张噪声图像,如下图所示。假设它是高斯噪声。 目前,我正在使用两个步骤来找到边缘

  1. 使用高斯滤波器 G 平滑图像
  2. 根据方程求边

    g=1/(1+β∇ (I*G)^2)

其中 G 是高斯滤波器。 β 是控制噪声水平的权重。

但是,高斯滤波器是图像边缘丢失的原因。我想找到一种更好的方法,可以保留边缘信息。你能建议我找到该图像边缘的最佳方法吗?

这是我执行上述步骤的结果

这是我正在处理的添加了噪点的图像:

为了得到边缘,这是我写的MATLAB代码:

beta=0.01;
G = fspecial('gaussian',[3 3],1);
I_G = conv2(I,G,'same');
[Gx,Gy] = gradient(I_G);
NormGrad = sqrt(Gx.^2 + Gy.^2); 
g = 1./ (1 + beta* NormGrad.^2);
imshow(g,[]);

规范 edge-preserving smoothing filters should be quite adequate for your particular application. These simultaneously remove noise (Gaussian distributed I should add...) while maintaining edges as best as possible. Classic examples include the bilateral filter, the Guided image filter by Kaiming He, Domain Transform filtering by Gastal and Oliveira (which I have successfully used in the past) and even anisotropic diffusion.

为了快速尝试,自 MATLAB R2014a 以来,Guided image filter 现在作为官方功能包含在图像处理工具箱中,通过 imguidedfilter function. If you don't have MATLAB R2014a or up, then you can download the raw MATLAB source of the code via this link here: http://kaiminghe.com/eccv10/guided-filter-code-v1.rar,但您可以从主网站获取此功能我 link上面给你的。

假设您没有 R2014a,请下载引导图像过滤器代码,让我们用它来过滤您的示例。鉴于您的 link 示例图像被噪声损坏,我下载了它并在下面的代码中使用它:

I = im2double(imread('http://i.stack.imgur.com/ACRE8.png')); %// Load in sample image that was corrupted by noise
r = 2; %// Parameters for the Guided image filter
eps = 0.1^2;

%// Filter the image, using itself as a guide
q = guidedfilter(I, I, r, eps);

%// Show the original image and the filtered result
figure;
subplot(1,2,1); imshow(I, []);
subplot(1,2,2); imshow(q, []);

我们展示的是原图,然后是右边的引导过滤结果:

完成后,尝试使用任何规范的边缘检测器来检测边缘。您使用的是在找到边缘之前对图像进行预模糊,但它使用标准平滑并且会遗漏某些边缘。因为使用 Guided image filter 将我们带到边缘保持不变并且整个图像基本上没有噪声的点,所以我们可以在边缘平滑结果上尝试一些简单的方法,比如 Sobel 过滤器:

[Gmag,~] = imgradient(q, 'sobel');
imshow(max(Gmag(:)) - Gmag,[]);

上面的代码使用 imgradient 找到图像渐变,然后我们通过反转强度来显示图像,以便黑色值变成白色,白色变成黑色,如您的示例所示。

...我们得到这个:

如您所见,即使存在噪音,我们仍然能够敲出很多边缘。

只是为了向@rayryeng 的相当完整和有趣的答案添加另一种方法,我将向您展示如何使用众所周知的 Split-Bregman 全变分算法进行降噪。

此算法强制图像具有 "less possible amount of grayscale levels"*。因此,它将对图像进行去噪(因为相似的加里级将被转换为相同的)但它会保留边缘。

Matlab 没有实现 TV,但你可以查看 this implementation

使用示例(希望代码不言自明)

N = 256; n = N^2;

% Read image;
g=double(imread('http://i.stack.imgur.com/ACRE8.png'));
%fill it with zeroes to make a NxN image
sz=size(g);
img=zeros(N);
img(1:size(g,1),1:size(g,2))=g;
g=img;

% the higher this parameter is, the stronger the denoising
mu = 6;

% denoise 
g_denoise_atv = SB_ATV(g,mu);
%prepare output
denoised=reshape(g_denoise_atv,N,N);
denoised=denoised(1:sz(1),1:sz(2));

% edges
[Gmag,~] = imgradient(denoised, 'sobel');

subplot(131); imshow(g(1:sz(1),1:sz(2)),[]);title('Original');
subplot(132); imshow(denoised,[]);title('Denoised');
subplot(133); imshow(max(Gmag(:)) - Gmag,[]);title('Edges');

]

如果您使用 mu 参数,您可以获得非常去噪(但图像数据丢失)的图像或非常少的去噪(但图像质量数据保留得更好);

mu=40

mu=1;

* 这是对方法的非数学解释。对于纯粹主义者,请检查 L1 正则化技术。