2013-05-10 4 views
12

私は、バイナリイメージ(回転されている可能性があります)にグリッドを持っています。 MATLABを使用してそのグリッドの近似計算式を知るにはどうすればよいですか?matlabのグリッド検出

例の画像:

http://www.pami.sjtu.edu.cn/people/wyg/images/print5.jpg

時には、これらの黒いドットが欠けているので、私はこれらの黒い点の可能性の中心を推定する式や「道」を必要とします。

私は regionpropsを使って試してみました

、それは私がこれらの中心を取得するのに役立ち黒点が存在しますが、全く分からない黒いドットが

clear all 
im = imread('print5.jpg'); 
im = im2bw(im); 
[sy,sx] = size(im); 
im = imcomplement(im); 
im(150:200,100:150) = 0; % let some dots missing! 
im = imclearborder(im); 
st = regionprops(im, 'Centroid'); 

imshow(im) hold on; 
for j = 1:numel(st) 
    px = round(st(j).Centroid(1,1)); 
    py = round(st(j).Centroid(1,2)); 
    plot(px,py,'b+') 
end 
+1

LOOを試しますキングの広告の周波数の内容: 'fft2'グリッドは非常に規則的です、あなたは周波数領域でピークを見つけることができるはずです。 – Shai

+5

上記のコメントのすべての情報をあなたの質問に編集すると、その情報を再度開くことができるはずです。 –

+5

うわー、これは短い時間で多くのdownvotesを引き付けました。私はそれがなぜ閉鎖されたのか理解していますが、実際には-20のダウンボートが必要ですか? – Amro

答えて

38

が欠落している場合は、ここでは、xとyの上に1Dでfftを使用しての方法です投影:

まず、私はガウスで畳み込むことによって高FREQノイズを平滑化するために画像を少しぼかします:

m=double(imread('print5.jpg')); 
m=abs(m-max(m(:))); % optional line if you want to look on the black square as "signal" 
H=fspecial('gaussian',7,1); 
m2=conv2(m,H,'same'); 

私はFFを取りますよ各軸の投影のT:

delta=1; 
N=size(m,1); 
df=1/(N*delta);  % the frequency resolution (df=1/max_T) 
f_vector= df*((1:N)-1-N/2);  % frequency vector 

freq_vec=f_vector; 
fft_vecx=fftshift(fft(sum(m2))); 
fft_vecy=fftshift(fft(sum(m2'))); 
plot(freq_vec,abs(fft_vecx),freq_vec,abs(fft_vecy)) 

enter image description here

そこで、両方の軸は、1/0.07422ピクセル又は〜13.5画素の周期に変換される0.07422ピークを得る見ることができます。

ml= log(abs(fftshift (fft2(m2)))+1); 
imagesc(ml) 
colormap(bone) 

enter image description here

、あなたは、あなたが得ることができますしたいならば、このような単純な形状やregionpropsなどのツールを適用します。

また、角度情報を取得するためのより良い方法は、2Dを行くことである、つまり正方形の角度と大きさ。正方形の大きさは1 /背景に大きな回転した正方形のサイズです(私は画像がぼやけているので少しぼやけていますので、それを使わないようにしてください)、角度はatan(y/x)です。正方形の間の距離は、1 /中央部分の強いピークと画像中心との間の距離である。

ので、あなたは、しきい値ml適切に画像を使用すると、そのために中央ピークにアクセスすることができます

imagesc(ml>11) 

を言うならば...

さらに別のアプローチは、例えば、バイナリイメージに形態学的操作になります私は、ぼやけた画像を閾値処理し、オブジェクトをポイントに縮小します。穴のないオブジェクトがポイントに縮小するようにそれはピクセルを削除します。

BW=m2>100; 
BW2 = bwmorph(BW,'shrink',Inf); 
figure, imshow(BW2) 

enter image description here

次に、あなたは実質的に格子サイトのグリッドごとに1つのピクセルを持っています!あなたはあなたがグリッド線を検出するためのHough transformを適用することができ

26

...等、ハフ変換を用いてアムロのソリューション にそれを養う、またはFFTとそれを分析し、またはブロックを収めることができます。

%# load image, and process it 
img = imread('print5.jpg'); 
img = imfilter(img, fspecial('gaussian',7,1)); 
BW = imcomplement(im2bw(img)); 
BW = imclearborder(BW); 
BW(150:200,100:150) = 0; %# simulate a missing chunk! 

%# detect dots centers 
st = regionprops(BW, 'Centroid'); 
c = vertcat(st.Centroid); 

%# hough transform, detect peaks, then get lines segments 
[H,T,R] = hough(BW); 
P = houghpeaks(H, 25); 
L = houghlines(BW, T, R, P); 

%# show image with overlayed connected components, their centers + detected lines 
I = imoverlay(img, BW, [0.9 0.1 0.1]); 
imshow(I, 'InitialMag',200, 'Border','tight'), hold on 
line(c(:,1), c(:,2), 'LineStyle','none', 'Marker','+', 'Color','b') 
for k = 1:length(L) 
    xy = [L(k).point1; L(k).point2]; 
    plot(xy(:,1), xy(:,2), 'g-', 'LineWidth',2); 
end 
hold off 

(私はファイル交換からimoverlay機能を使用しています)

結果:

grid_lines_overlayed

私たちは、あなたが格子位置や回転角度を推測することができ、それらを持っていたら、

ここでは、検出された行に対応するピークが強調表示されたアキュムレータ行列を示します。

0123ここ

%# filter lines to extract almost vertical ones 
%# Note that theta range is (-90:89), angle = theta + 90 
LL = L(abs([L.theta]) < 30); 

%# compute the mean slope of those lines 
slopes = vertcat(LL.point2) - vertcat(LL.point1); 
slopes = atan2(slopes(:,2),slopes(:,1)); 
r = mean(slopes); 

%# transform image by applying the inverse of the rotation 
tform = maketform('affine', [cos(r) sin(r) 0; -sin(r) cos(r) 0; 0 0 1]); 
img_align = imtransform(img, fliptform(tform)); 
imshow(img_align) 

accumulator_peaks


今我々は2つの方向(水平位置または垂直型)のいずれかのものに濾過検出された線の平均勾配を計算することによって回転角度を回復することができグリッドをXY軸と整列するように画像バック回転さ:

aligned_img

関連する問題