【问题标题】:Detecting edges of an image doesn't work in Matlab检测图像的边缘在 Matlab 中不起作用
【发布时间】:2018-09-15 14:39:51
【问题描述】:

我正在编写一个检测图像边缘的脚本。

这是脚本:

clear all; close all; clc;

c = rgb2gray(imread('image_S004_I0004.jpg'));
c = double(c);
k = imnoise(c, 'salt & pepper', 0.01); 

gg = [-1 0 1;-2 0 2; -1 0 1];
gh = gg';

grad_g = conv2(k, gg);
grad_h = conv2(k, gh);
grad = sqrt(grad_g.^2 + grad_h.^2);

[r s] = size(grad);
T = 80;
for ii = 1:r
    for jj = 1:s

        if grad(ii, jj) < T
            thresh_grad(ii, jj) = 0;
        else 
            thresh_grad(ii, jj) = 1;
        end
    end
end

figure()
subplot(121); imshow(uint8(c));
subplot(122); imshow(thresh_grad); 

这是我经常得到的:

左边是原始图像,右边应该是检测到边缘的图像(正如您在脚本中看到的,我在图像上添加了一些噪点 - 必须存在)。但无论阈值 T 的值是多少,我实际上一无所获。

你能帮我找出我的错误吗?

【问题讨论】:

  • 没仔细看,但可能c = double(c);应该是c = im2double(c);,最后imshow(uint8(c));应该只是imshow(c);
  • 或者imshow(thresh_grad,[])?
  • 请注意,您可以将所有像素上的循环替换为thresh_grad = grad &gt;= T。
  • #Sardar Usama 它不起作用。仍然给我同样的结果。 #Cris Luengo 它不起作用
  • @Bacon:用@ 字符标记人。否则我们不会收到通知。 grad 是什么样的?你对此满意吗?

标签: matlab image-processing edge-detection noise sobel


【解决方案1】:

您的代码中的问题就在您应用噪声之前。在调用imnoise 之前,您将图像投射到double。通过这样做,double 精度图像被假定具有[0,1] 的动态范围,因此imnoise 的输出将被裁剪到[0,1] 范围。这意味着您的阈值80 将因此不合适,因为永远不会有任何渐变值会超过 80 的值,因此所有内容都显示为黑色。

此外,thresh_grad 未定义,建议您在使用前预先分配图像。只需在双 for 循环之前执行 thresh_grad = zeros(size(grad));。

因此,在调用imnoise 之后调用double,这将使图像仍然在uint8 中,然后转换为double 以进行卷积。通过这样做,我设法获得了输出。我无权访问您的图像,但我使用了 MATLAB 图像处理工具箱中内置的 cameraman.tif 图像。

因此:

c = imread('cameraman.tif');
k = imnoise(c, 'salt & pepper', 0.01); 
k = double(k); % Change

gg = [-1 0 1;-2 0 2; -1 0 1];
gh = gg';

grad_g = conv2(k, gg);
grad_h = conv2(k, gh);
grad = sqrt(grad_g.^2 + grad_h.^2);

[r, s] = size(grad);
thresh_grad = zeros(size(grad)); % Added
T = 80;
for ii = 1:r
    for jj = 1:s

        if grad(ii, jj) < T
            thresh_grad(ii, jj) = 0;
        else 
            thresh_grad(ii, jj) = 1;
        end
    end
end

figure()
subplot(121); imshow(uint8(c));
subplot(122); imshow(thresh_grad); 

我明白了:


至于未来的发展,我建议你使用im2double将图像实际转换为double精度,这也将数据转换为[0,1]范围。因此,您需要将阈值从 80 更改为 80/255,因为 80 的阈值最初是为 uint8 图像设计的。

最后,当您显示原始图像时,您可以摆脱uint8 投射。

为了完整性:

c = imread('cameraman.tif');
c = im2double(c); % Change
k = imnoise(c, 'salt & pepper', 0.01); 

gg = [-1 0 1;-2 0 2; -1 0 1];
gh = gg';

grad_g = conv2(k, gg);
grad_h = conv2(k, gh);
grad = sqrt(grad_g.^2 + grad_h.^2);

[r, s] = size(grad);
thresh_grad = zeros(size(grad)); % Added
T = 80 / 255; % Change
for ii = 1:r
    for jj = 1:s

        if grad(ii, jj) < T
            thresh_grad(ii, jj) = 0;
        else 
            thresh_grad(ii, jj) = 1;
        end
    end
end

figure()
subplot(121); imshow(c);
subplot(122); imshow(thresh_grad); 

【讨论】:

  • 我没有大量使用图像处理工具箱(或者实际上根本没有使用),我发现imnoise 会将双输入剪辑到 [0,1] 范围,这让我感到震惊。那只是要求用户投诉! :)
  • @CrisLuengo 我只是在调试代码中的每个变量时才注意到这一点。当我在imnoise 之前和之后显示图像时,我注意到了剪辑。我知道有点可笑!
  • 我已经解决了。谢谢大家的帮助,很抱歉我迟到的回答!
猜你喜欢
  • 2013-12-17
  • 1970-01-01
  • 2010-12-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-25
  • 1970-01-01
相关资源
最近更新 更多