检测图像的边缘在 Matlab 中不起作用
Detecting edges of an image doesn't work in Matlab
我正在编写检测图像边缘的脚本。
这是脚本:
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 的值是多少,我实际上什么都得不到。
你能帮我找出我的错误吗?
你的代码中的问题就在你应用噪音之前。您在调用 imnoise
之前将图像投射到 double
。通过这样做,double
精度图像被假定具有 [0,1]
的动态范围,因此 imnoise
的输出将被裁剪到 [0,1]
范围。这意味着您的 80
阈值因此不合适,因为永远不会有任何梯度值超过 80 的值,因此所有内容都显示为黑色。
此外,thresh_grad
未定义,建议您在使用前先 pre-allocate 图片。只需在双 for
循环之前执行 thresh_grad = zeros(size(grad));
。
因此,在调用 imnoise
之后调用 double
,这将使图像仍然处于 uint8
,然后转换为 double
以达到目的的卷积。通过这样做,我设法获得了输出。我无法访问您的图像,但我使用了 cameraman.tif
图像,它是 built-into 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);
我得到:
至于未来的发展,我建议您使用 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);
我正在编写检测图像边缘的脚本。
这是脚本:
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 的值是多少,我实际上什么都得不到。
你能帮我找出我的错误吗?
你的代码中的问题就在你应用噪音之前。您在调用 imnoise
之前将图像投射到 double
。通过这样做,double
精度图像被假定具有 [0,1]
的动态范围,因此 imnoise
的输出将被裁剪到 [0,1]
范围。这意味着您的 80
阈值因此不合适,因为永远不会有任何梯度值超过 80 的值,因此所有内容都显示为黑色。
此外,thresh_grad
未定义,建议您在使用前先 pre-allocate 图片。只需在双 for
循环之前执行 thresh_grad = zeros(size(grad));
。
因此,在调用 imnoise
之后调用 double
,这将使图像仍然处于 uint8
,然后转换为 double
以达到目的的卷积。通过这样做,我设法获得了输出。我无法访问您的图像,但我使用了 cameraman.tif
图像,它是 built-into 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);
我得到:
至于未来的发展,我建议您使用 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);