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

标签 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 的值是多少,我实际上什么也得不到。

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

最佳答案

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

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

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

因此:

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

关于matlab - 检测图像的边缘在 Matlab 中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49678036/

相关文章:

python - R - 通过删除 x、y 和 z 维度的全零二维矩阵来调整 3D 数组的大小

algorithm - 开始学习边缘检测/图像识别的最佳文章

image - 区分单连通图形?

matlab - 绘制对数正态分布的 PDF

function - 如何在 Mathematica 和 Matlab 中查找已定义符号的类型和内存位置?

image-processing - ImageMagick:从不同尺寸的图 block 中剪辑图像

python - 使用 numpy 高效地将 16 位图像数据转换为 8 位显示,具有强度缩放

image-processing - 测量图像中弯管长度的特征检测技术

image-processing - 检测圆并测量像素

ruby - 用多边形近似形状