2013-05-10 2 views
12

Ich habe ein Raster in einem Binärbild (kann gedreht werden). Wie kann ich mithilfe von MATLAB eine ungefähre Formel für dieses Raster ermitteln?Gittererkennung in Matlab

Beispiel Bild:

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

Manchmal sind diese schwarzen Punkte fehlen, so muss ich Formel oder ‚einen Weg‘ möglich Mitte dieser schwarzen Punkte zu schätzen.

Ich habe versucht, durch regionprops verwenden, helfen sie mir Zentrum von diesen existieren schwarze Punkte zu bekommen, aber keine Ahnung, ob schwarze Punkte ein

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

Try loo: zurück, so dass das Gitter mit den XY-Achsen-ausgerichtet ist, ist das Bild gedreht König und der Frequenzinhalt: 'fft2' das Gitter ist sehr regelmäßig, Sie sollten Spitzen im Frequenzgebiet aufspüren können. – Shai

+5

Wenn Sie alle Informationen aus den obigen Kommentaren in Ihre Frage bearbeiten, sollten Sie sie wieder öffnen können. –

+5

Wow, das hat in kurzer Zeit viele Downvotes angezogen. Ich verstehe, warum es geschlossen war, aber hat es wirklich verdient -20 downvotes ... – Amro

Antwort

38

hier eine Möglichkeit, fft in 1D über die x- und y fehlt mit Projektion:

Zuerst werde ich das Bild ein wenig verwischen die hohe Freq Lärm durch Faltung mit einem Gaußschen zu glätten:

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'); 

dann nehme ich die ff t eines Vorsprungs jeder Achse:

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

So können wir beide Achsen sehen einen Peak bei 0,07422 ergeben, die sich auf einen Zeitraum von 1/0,07422 Pixel oder ~ 13.5 Pixel übersetzen.

Eine bessere Möglichkeit, auch die Winkel Informationen zu bekommen, ist 2D zu gehen, das heißt:

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

enter image description here

und dann Werkzeuge wie einfache Geometrie oder regionprops gelten, wenn Sie möchten, können Sie bekommen der Winkel und die Größe der Quadrate. Die Größe des Quadrats ist 1/die Größe des großen gedrehten Quadrats auf dem Hintergrund (ein bisschen unscharf, weil ich das Bild verwischt habe, also versuche, das ohne das zu tun), und der Winkel ist atan(y/x). Der Abstand zwischen den Quadraten beträgt 1/der Abstand zwischen den starken Spitzen im mittleren Teil zur Bildmitte.

so, wenn Sie Schwelle ml richtig sagen Bild

imagesc(ml>11) 

Sie die zentralen Spitzen für das zugreifen kann ...

noch ein weiterer Ansatz wird morphologische Operation auf einem binären Bild, zum Beispiel Ich schwelle das unscharfe Bild und verkleinere Objekte zu Punkten. Es entfernt Pixel, so dass Objekte ohne Löcher bis zu einem Punkt schrumpfen:

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

enter image description here

Dann praktisch Sie einen Pixel pro Gitterplatz Gitter haben! so können Sie es auf der Amro füttern Lösung Hough-Transformation verwenden oder es mit fft analysieren oder einen Block passen, etc ...

26

Sie Hough transform anwenden könnten die Gitterlinien zu erkennen.

%# 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 

(Ich verwende imoverlay Funktion aus dem File Exchange)

Das Ergebnis:

grid_lines_overlayed

Sobald wir diese haben, können Sie die Gitterstellen und den Drehwinkel schließen

Hier ist die Akkumulatormatrix mit den Spitzen, die den erkannten Linien entsprechen, hervorgehoben:

accumulator_peaks


Jetzt können wir den Drehwinkel durch Berechnung der mittleren Steigung der erfassten Linien, gefiltert, um diejenigen, die in einer der beiden Richtungen (Waagrechten oder Senkrechten) wiederherzustellen:

%# 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) 

Hier

aligned_img