检测图像的边缘在Matlab中不起作用

时间:2018-04-05 17:18:38

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

我正在研究检测图像边缘的脚本。

这是脚本:

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); 

这是我一直得到的:

enter image description here

左边是原始图像,右边应该是检测到边缘的图像(正如你在脚本中看到的,我在图像上实现了一些噪声 - 必须在那里)。但是我什么都没有,无论阈值T的值是什么。

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

1 个答案:

答案 0 :(得分:5)

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

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

因此,请在拨打double后致电imnoise,这会使图片仍然在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); 

我明白了:

enter image description here

至于未来的发展,我建议您使用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);