在Matlab中无法检测图像的边缘 [英] Detecting edges of an image doesn't work in Matlab

查看:64
本文介绍了在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.

您能帮我发现我的错误吗?

Could you please help me to find my mistake?

推荐答案

在应用噪声之前,您的代码中的问题是正确的.您正在调用 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 未定义,建议您在使用之前预先分配图像.只需在双 for 循环之前执行 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 精度,这还将把数据转换为 [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天全站免登陆