2013-05-10 5 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

Try Лоо king ad частотный контент: 'fft2' сетка очень регулярная, вы должны иметь возможность определять пики в частотной области. – Shai

+5

Если вы отредактируете всю информацию из приведенных выше комментариев в свой вопрос, вы сможете восстановить ее. –

+5

wow, это привлекло много downvotes в короткий промежуток времени. Я понимаю, почему он был закрыт, но действительно ли он заслужил -20 downvotes ... – Amro

ответ

38

вот способ использования fft в 1D по х и у проекция:

Во-первых, я размыть изображение немного, чтобы сгладить высокий 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'); 

тогда я взять сл т проекции каждой оси:

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

Таким образом, мы можем видеть обе оси дают пик при котором 0.07422 перевести на период 1/0,07422 пикселей или ~ 13.5 пикселей.

Лучший способ получить также информацию угла идти 2D, то есть:

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

enter image description here

, а затем применить инструменты, такие как простая геометрия или regionprops, если вы хотите, вы можете получить угол и размер квадратов. Размер квадрата равен 1/размер большого поворотного квадрата на фоне (бит нечеткий, потому что я размыл изображение, поэтому попробуйте сделать это без этого), а угол - atan(y/x). Расстояние между квадратами составляет 1/расстояние между сильными пиками в центральной части до центра изображения.

так что если вы пороговая ml образ правильно сказать

imagesc(ml>11) 

вы можете получить доступ к пики центр для этого ...

еще один подход будет морфологическая операция на бинарном изображении, например, Я порою размытое изображение и сжимаю объекты до точек. Она удаляет пиксели так, чтобы объекты без отверстий сжиматься до точки:

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

enter image description here

Тогда вы практически есть один пиксель за решетку сайта решетки! так что вы можете кормить его решение Amro в с помощью преобразования поджилки, или анализировать ее с FFT, или установить блок, и т.д. ...

26

Вы могли бы применить Hough transform для обнаружения линий сетки.После того, как мы те, которые вы можете сделать вывод, расположение сетки и угол поворота:

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

Вот аккумуляторная матрица с пиками, соответствующими выделенным линиям:

accumulator_peaks


Теперь мы можем восстановить угол поворота путем вычисления среднего наклона обнаруженных линий, фильтруют тем, в одном из двух направлений (горизонтали или вертикалей):

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

Здесь это изображение повернуто так, что сетка совмещаются с XY-осями:

aligned_img

Смежные вопросы