2011-07-12 13 views
1

Robertsオペレーターについて別の質問を投稿しましたが、その時からコードが大幅に変更されたため、新しいものを投稿することにしました。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 

答えて

3

私はあなたがどのようにロバーツ・クロスの演算子の作品を誤って解釈することができると思います。ガイドとしてthis pageを使用してください。元の画像とXとY演算子を別々に入れてを畳み込んだことに注意してください。次に、特定のピクセルの2つの(xとy)勾配値の二乗和の平方根をとることによって、最終的な勾配(つまり、「総エッジコンテンツ」)値を計算することができます。現在、xとyの値を1つの画像に合計していますが、正しい結果は得られません。私は少し良く説明しよう

EDIT

。正方形/平方根の代わりに総和の問題は、負の値に終わる可能性があることです。負の値は、エッジ方向に応じてこの演算子を使用すると自然です。これは、イメージが「明るくなる」と思う理由です。なぜなら、MATLABでイメージを表示すると、負の値は黒になり、ゼロの値はグレーになり、正の値は白になります。ここで私はあなたのコードを実行したときに画像を取得します(ほとんど変更はありません)。はzeros(size(Img))になります。

だけでなく、ファイルを保存しようとするとき。あなたは非常に注意しなければならない。その代わりimwriteを呼び出す、imshow(NewImg,[])を呼び出します。それは、自動的に最も負の数があることで、それらを正しく表示するためにdouble -valued画像内の値を再スケールします黒と同等で、白とほぼ同じです。したがって、エッジコンテンツが少ない(空のような)領域では、グレーが予想され、それがわかります。

+0

ていますか?記事は理にかなっていますが、クラスで学んだことから、特定のピクセルの2つのxとyの勾配値を追加するだけです。おそらく2つの勾配行列には平方根が組み込まれているでしょうか?編集 - ソーベルオペレーターの勾配値を二乗する必要があると聞いたことがありますが、ロバーツはそうではありません。 – superlazyname

+0

ここに - それを少し説明するかもしれない編集を追加します... – aardvarkk

+0

ありがとう、私は今理解して、それはネガになると推測したことはありませんでした。 – superlazyname

1

あなたのコードを実行し、あなたが説明した効果を得ました。すべてが軽いどのように見えるかを参照してください:

enter image description here 図1 - 私のシステム上の左のオリジナル、右

上の元ロバーツ変換画像が実際に飽和しました。私の画像はuint8で、操作は画像を255以上、0以下(マイナス側)に押すとすべてが明るくなりました。

Img = double(rgb2gray(imread(filename))); 

のように二重に変換する関数imreadのコードの行を変更することにより

は(私も、RGB変換をしたので、私の画像がカラーだった注意してください。、左の

enter image description here オリジナル右側にコードを修正:あなたは、私が改善された画像を得た

Img = double((imread(filename))); 

使用することがあります。次の結果について

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 

:ここ

enter image description here

+0

また、これはあなたのコードを修正しますが、合計ではなく結果の標準を取ることについてaardvarkkのアドバイスを検討してください。 – Steve

+4

何かにも注意してください。 2次元畳み込みコードは、元のポスターの結果と逆の高低を生成します(これは、修正後)。これは、元のポスターが2d畳み込みの代わりに2d相互相関を実装したためです。これに対する修正は、畳み込みを実装するために、Robertのクロス演算子を原作のポスターコードで反転しなければならないということです。 2D畳み込みの適切な定義については、任意の信号テキストまたはWikipediaを参照してください。 –

+0

@Chris A.良い目! – aardvarkk

0

は実装例である私も、2Dコンボリューションではなく、あなたのループを使用して、この結果を生み出すことができると

注意。あなたは簡単に独自の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 

gradient direction vectorField binary_edges

関連する問題