罗伯茨算子只是让图像更明亮
我发布了关于 Roberts 运算符的另一个问题,但我决定发布一个新问题,因为自那时以来我的代码发生了显着变化。
我的代码运行,但它没有生成正确的图像,而是图像变得稍微更亮。
我没有发现算法中的错误,但我知道这不是正确的输出。如果我将此程序的输出与 edge(
或维基百科上的图像进行比较,它看起来与所示的 roberts 运算符的效果完全不同那里。,'roberts',
代码:
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
I posted another question about the Roberts operator, but I decided to post a new one since my code has changed significantly since that time.
My code runs, but it does not generate the correct image, instead the image becomes slightly brighter.
I have not found a mistake in the algorithm, but I know this is not the correct output. If I compare this program's output to edge(<image matrix>,'roberts',<threshold>);
, or to images on wikipedia, it looks nothing like the effect of the roberts operator shown there.
code:
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我认为您可能误解了 Roberts Cross 运算符的工作原理。使用此页面作为指南。请注意,它指出您使用 X 和 Y 运算符单独对原始图像进行卷积。然后,您可以通过取特定像素的两个(x 和 y)梯度值的平方和的平方根来计算最终梯度(即“总边缘内容”)值。您目前正在将 x 和 y 值求和到单个图像中,这不会给出正确的结果。
编辑
我会尽力解释得更好一些。使用求和而不是平方/平方根的问题是您最终可能会得到负值。根据边缘方向,使用此运算符自然会出现负值。这可能就是您认为图像“变亮”的原因 - 因为当您在 MATLAB 中显示图像时,负值变为黑色,零值变为灰色,正值变为白色。这是我运行代码时得到的图像(进行了一些更改 - 主要将
。
NewImg
设置为zeros(size(Img))
所以它是一个double
类型而不是uint8
类型不允许负值...这是我得到的图像:尝试保存文件时也必须非常小心,而不是调用
imwrite
。 ,调用 imshow(NewImg,[]),这将自动重新调整双值图像中的值以正确显示它们,其中最大的负数等于黑色。因此,在具有白色的区域中,最正值等于白色。边缘内容很少(例如天空),我们期望灰色,这就是我们得到的!I think you may be misinterpreting how the Roberts Cross operator works. Use this page as a guide. Notice that it states that you convolve the original image separately with the X and Y operator. Then, you may calculate the final gradient (i.e. "total edge content") value by taking the square root of the sum of squares of the two (x and y) gradient values for a particular pixel. You're presently summing the x and y values into a single image, which will not give the correct results.
EDIT
I'll try to explain a bit better. The problem with summation instead of squaring/square root is that you can end up with negative values. Negative values are natural using this operator depending on the edge orientation. That may be why you think the image 'lightens' -- because when you display the image in MATLAB the negative values go to black, the zero values go to grey, and the positive values go to white. Here's the image I get when I run your code (with a few changes -- mostly setting
.
NewImg
to bezeros(size(Img))
so it's adouble
type instead ofuint8
.uint8
types don't allow negative values... Here's the image I get:You have to be very careful when trying to save files as well. Instead of calling
imwrite
, callimshow(NewImg,[])
. That will automatically rescale the values in thedouble
-valued image to show them correctly, with the most negative number being equal to black and most positive equal to white. Thus, in areas with little edge content (like the sky), we would expect grey and that's what we get!我运行了你的代码并得到了你描述的效果。看看一切看起来如何更轻:
图 1 - 左侧为原始图像,右侧为原始罗伯茨变换图像
我系统上的图像实际上已饱和。我的图像是 uint8,操作将图像推过 255 或低于 0(负值),一切都变得更亮。
通过更改 imread 中的代码行以转换为双精度
(请注意,我的图像是彩色的,因此我也进行了 rgb 转换。您可以使用
我得到了改进的图像:
左边是原始代码,右边是更正后的代码。
请注意,我也可以使用 2d 卷积而不是循环来生成此结果:
对于以下结果:
I ran your code and got the effect you described. See how everything looks lighter:
Figure 1 - Original on the left, original roberts transformation on the right
The image on my system was actually saturated. My image was uint8 and the operations were pushing the image past 255 or under 0 (for the negative side) and everything became lighter.
By changing the line of code in the imread to convert to double as in
(note my image was color so I did an rgb conversion, too. You might use
I got the improved image:
Original on left, corrected code on right.
Note that I could also produce this result using 2d convolution rather than your loop:
For the following result:
这是一个示例实现。您可以轻松地将 CONV2/IMFILTER 替换为您自己的 2D 卷积/相关函数:
Here is an example implementation. You could easily replace CONV2/IMFILTER with your own 2D convolution/correlation function: