【问题标题】:Best method to find edge of noise image寻找噪声图像边缘的最佳方法
【发布时间】:2015-08-13 18:09:23
【问题描述】:

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

  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,[]);

【问题讨论】:

    标签: image matlab image-processing edge-detection


    【解决方案1】:

    Canonical edge-preserving smoothing 过滤器应该足以满足您的特定应用程序。这些同时消除噪声(我应该添加高斯分布......),同时尽可能保持边缘。经典的例子包括bilateral filter、Kaiming He 的Guided image filter、Gastal 和 Oliveira 的Domain Transform filtering(我过去成功使用过),甚至还有anisotropic diffusion

    为了快速尝试,Guided 图像过滤器现在作为官方函数包含在自 MATLAB R2014a 以来通过imguidedfilter 函数成为图像处理工具箱的一部分。如果您没有 MATLAB R2014a 或更高版本,则可以通过以下链接下载原始 MATLAB 源代码:http://kaiminghe.com/eccv10/guided-filter-code-v1.rar,但您可以从我在上面链接到您的主网站获取。

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

    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, []);
    

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

    完成后,请尝试使用任何规范的边缘检测器来检测边缘。您正在使用的那个在找到边缘之前预先模糊了图像,但是它使用标准平滑并且它会错过一些边缘。因为使用引导图像过滤器使我们能够保持边缘并且整个图像基本上没有噪声,所以我们可以尝试一些简单的方法,例如对边缘平滑结果使用 Sobel 过滤器:

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

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

    ...我们得到这个:

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

    【讨论】:

    • 感谢 rayryeng。我查看了我的结果和您的结果,发现您的结果比我的结果要好得多。但是,我们需要一些证明您的方法可以实现边缘保留。您是否知道任何定量测量表明您的方法比我的方法更好?
    • 你可以使用一堆定量的方法来确定一个结果是否比另一个更好,但这需要你参考原始边缘图像。如果你没有那个,那么你只能定性地看待它。假设你有一个参考,你可以使用 PSNR、MSE 或任何相关的同类。话虽如此,如果没有可比较的参考,您无法在我的方法和您的方法之间进行比较。
    • @Benoit_11 - 谢谢 :)
    • 我使用拉普拉斯算子从分段图像(4 个标签)中创建了一个参考边缘。您可以在dropbox.com/s/4feqixaiby3zgky/Edges_invert.mat?dl=0 下载,或者如果您想自己创建。您可以在dropbox.com/s/qfovofhdldiwijn/I_Ref.mat?dl=0 下载分段图像。希望您的方法取得了良好的效果
    • @user3051460 - 我认为最好自己比较我和安德所写的内容,然后自己找出哪种方法更好。您是确定这一点的最佳人选,让我们为您进行比较不会让您学到任何东西。一个简单的测试可能是对梯度图像进行阈值处理,使它们成为边缘像素,然后在两个图像之间进行 SSD。 PSNR 也是一种很好的方法,您可以在此处查看如何计算它:stackoverflow.com/questions/16264141/…
    【解决方案2】:

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

    此算法强制图像具有“尽可能少的灰度级别”*。因此,它将对图像进行去噪(因为相似的 gary 级别将转换为相同的级别),但会保留边缘。

    Matlab 没有实现电视,但是可以查看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 正则化技术。

    【讨论】:

      猜你喜欢
      • 2018-12-31
      • 2016-04-09
      • 1970-01-01
      • 2018-07-11
      • 2019-02-27
      • 2021-05-18
      • 2010-10-03
      • 2011-02-15
      • 1970-01-01
      相关资源
      最近更新 更多