我发布了另一个关于Roberts运算符的问题,但我决定发布一个新的问题,因为从那时起我的代码发生了重大变化。
我的代码运行,但它不会生成正确的图像,而是图像变得稍微亮一点。
我没有在算法中发现错误,但我知道这不是正确的输出。如果我将此程序的输出与edge(<image matrix>,'roberts',<threshold>);
或维基百科上的图像进行比较,它看起来就像在那里显示的罗伯茨运算符的效果。
代码:
function [] = Robertize(filename)
Img = imread(filename);
NewImg = Img;
SI = size(Img);
I_W = SI(2)
I_H = SI(1)
Robertsx = [1,0;0,-1];
Robertsy = [0,-1;1,0];
M_W = 2; % do not need the + 1, I assume the for loop means while <less than or equal to>
% x and y are reversed...
for y=1 : I_H
for x=1 : I_W
S = 0;
for M_Y = 1 : M_W
for M_X = 1 : M_W
if (x + M_X - 1 < 1) || (x + M_X - 1 > I_W)
S = 0;
%disp('out of range, x');
continue
end
if (y + M_Y - 1 < 1) || (y + M_Y - 1 > I_H)
S = 0;
%disp('out of range, y');
continue
end
S = S + Img(y + M_Y - 1 , x + M_X - 1) * Robertsx(M_Y,M_X);
S = S + Img(y + M_Y - 1, x + M_X - 1) * Robertsy(M_Y,M_X);
% It is y + M_Y - 1 because you multiply Robertsx(1,1) *
% Img(y,x).
end
end
NewImg(y,x) = S;
end
end
imwrite(NewImg,'Roberts.bmp');
end
答案 0 :(得分:3)
我认为你可能误解了Roberts Cross运算符的工作原理。使用this page作为指南。请注意,它声明您将原始图像单独与X和Y运算符进行卷积。然后,您可以通过取特定像素的两个(x和y)梯度值的平方和的平方根来计算最终梯度(即“总边缘内容”)值。您现在正在将x和y值相加到单个图像中,这将无法给出正确的结果。
修改强>
我会尝试更好地解释一下。求和而不是平方根/平方根的问题是你可以得到负值。根据边缘方向,使用此运算符的负值是自然的。这可能是您认为图像“变亮”的原因 - 因为当您在MATLAB中显示图像时,负值变为黑色,零值变为灰色,正值变为白色。这是我运行代码时获得的图像(有一些更改 - 主要是将NewImg
设置为zeros(size(Img))
,因此它是double
类型而不是uint8
。{{ 1}}类型不允许负值...这是我得到的图像:。
在尝试保存文件时,您必须非常小心。请致电uint8
,而不是致电imwrite
。这将自动重新调整imshow(NewImg,[])
- 值图像中的值以正确显示它们,其中最负数等于黑色,最正数等于白色。因此,在边缘内容很少的区域(如天空),我们会期待灰色,这就是我们得到的!
答案 1 :(得分:1)
我运行了你的代码并获得了你描述的效果。看看一切看起来如何轻松:
图1 - 左侧的原始,右侧的原始罗伯茨转换
我系统上的图像实际上已经饱和了。我的图像是uint8,操作将图像推过255或低于0(对于负面),一切都变得更轻。
通过更改imread中的代码行转换为双倍,如
Img = double(rgb2gray( imread(filename)));
(注意我的图像是彩色的,所以我也进行了rgb转换。你可以使用
Img = double(( imread(filename)));
我得到了改进的图像:
左边的原件,右边的修正代码。
请注意,我也可以使用2d卷积而不是循环来生成此结果:
Robertsx = [1,0;0,-1];
Robertsy = [0,-1;1,0];
dataR = conv2(data, Robertsx) + conv2(data, Robertsy);
figure(2);
imagesc(dataR);
colormap gray
axis image
以下结果:
答案 2 :(得分:0)
这是一个示例实现。您可以使用自己的2D卷积/相关函数轻松替换CONV2 / IMFILTER:
%# convolve image with Roberts kernels
I = im2double(imread('lena512_gray.jpg')); %# double image, range [0,1]
hx = [+1 0;0 -1]; hy = [0 +1;-1 0];
%#Gx = conv2(I,hx);
%#Gy = conv2(I,hy);
Gx = imfilter(I,hx,'conv','same','replicate');
Gy = imfilter(I,hy,'conv','same','replicate');
%# gradient approximation
G = sqrt(Gx.^2+Gy.^2);
figure, imshow(G), colormap(gray), title('Gradient magnitude [0,1]')
%# direction of the gradient
Gdir = atan2(Gy,Gx);
figure, imshow(Gdir,[]), title('Gradient direction [-\pi,\pi]')
colormap(hot), colorbar%, caxis([-pi pi])
%# quiver plot
ySteps = 1:8:size(I,1);
xSteps = 1:8:size(I,2);
[X,Y] = meshgrid(xSteps,ySteps);
figure, imshow(G,[]), hold on
quiver(X, Y, Gx(ySteps,xSteps), Gy(ySteps,xSteps), 3)
axis image, hold off
%# binarize gradient, and compare against MATLAB EDGE function
BW = im2bw(G.^2, 6*mean(G(:).^2));
figure
subplot(121), imshow(BW)
subplot(122), imshow(edge(I,'roberts')) %# performs additional thinning step