在Matlab中无法检测图像的边缘 [英] Detecting edges of an image doesn't work in 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屋!