1

我发布了另一个关于 Roberts 运算符的问题,但我决定发布一个新问题,因为从那时起我的代码发生了重大变化。

我的代码运行,但它没有生成正确的图像,而是图像变得稍微亮一些。

我没有在算法中发现错误,但我知道这不是正确的输出。如果我将此程序的输出与edge(<image matrix>,'roberts',<threshold>);wikipedia 上的图像或图像进行比较,它看起来与此处显示的 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
4

3 回答 3

3

我认为您可能误解了 Roberts Cross 运算符的工作原理。使用此页面作为指南。请注意,它声明您使用 X 和 Y 运算符分别对原始图像进行卷积。然后,您可以通过取特定像素的两个(x 和 y)梯度值的平方和的平方根来计算最终梯度(即“总边缘内容”)值。您目前正在将 x 和 y 值相加成一个图像,这不会给出正确的结果。

编辑

我会试着解释得更好一点。求和而不是平方/平方根的问题在于您最终可能会得到负值。负值很自然地使用此运算符,具体取决于边缘方向。这可能就是您认为图像“变亮”的原因——因为当您在 MATLAB 中显示图像时,负值变为黑色,零值变为灰色,正值变为白色。这是我在运行您的代码时得到的图像(进行了一些更改-主要设置NewImg为,zeros(size(Img))因此它是一种double类型而不是.types 不允许负值...这是我得到的图像uint8:.uint8生成的图像

尝试保存文件时也必须非常小心。而不是打电话imwrite,打电话imshow(NewImg,[])。这将自动重新缩放double-valued 图像中的值以正确显示它们,其中最负数等于黑色,最正数等于白色。因此,在边缘内容很少的区域(如天空),我们会期待灰色,这就是我们得到的!

于 2011-07-12T16:49:18.687 回答
1

我运行了你的代码,得到了你描述的效果。看看一切看起来如何更轻:

在此处输入图像描述 图 1 - 左侧为原始,右侧为原始 roberts 变换

我系统上的图像实际上是饱和的。我的图像是 uint8 并且操作将图像推到超过 255 或低于 0(对于负侧),一切都变得更轻了。

通过更改 imread 中的代码行以转换为 double ,如

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

对于以下结果:

在此处输入图像描述

于 2011-07-12T17:07:05.757 回答
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

坡度 方向 向量场 binary_edges

于 2011-07-14T17:37:44.430 回答