检测图像的边缘在Matlab中不起作用 [英] Detecting edges of an image doesn't work in Matlab

查看:161
本文介绍了检测图像的边缘在Matlab中不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm working on a script detecting edges of an image.

这是脚本:

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的值是什么。

On the left is an original image, on the right should be an image with detected edges (as you can see in the script, I have implemented some noise on the image - has to be there). But I get literally nothing, not matter what the value of threshold T is.

你能帮我找错吗?

推荐答案

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

The problem in your code is right before you apply the noise. You are casting the image to double prior to calling imnoise. By doing this, double precision images are assumed to have a dynamic range of [0,1] and so the output of imnoise would be clipped to the [0,1] range. This means that your threshold of 80 would therefore be unsuitable because there will never be any gradient values that would exceed the value of 80 so everything is visualized as black.

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

In addition, thresh_grad is not defined and it's recommended you pre-allocate the image prior to using it. Simply do thresh_grad = zeros(size(grad)); prior to the double for loop.

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

As such, call double after you make the call to imnoise which would make the image still be in uint8 and then convert to double for the purposes of convolution. By doing this I managed to get output. I don't have access to your image, but I used the cameraman.tif image that's built-into MATLAB's image processing toolbox.

因此:

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 precision,它还会将数据转换为 [0,1] 范围。因此,您需要将阈值从 80 更改为 80/255 作为的阈值80 最初是为 uint8 图像而设计的。

As for future development, I recommend you use im2double to actually convert the images to double precision, which would also convert the data into a [0,1] range. You would thus need to change the threshold from 80 to 80/255 as the threshold of 80 was originally designed for uint8 images.

最后,当你展示原版时图像你可以摆脱 uint8 投射。

Finally, when you show the original image you can get rid of the uint8 casting.

为了完整性:

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

这篇关于检测图像的边缘在Matlab中不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆