Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Grid detection in matlab

I have a grid in a binary image (may be rotated). How can I know approximate formula for that grid using MATLAB?

Example image:


(source: sjtu.edu.cn)

Sometimes these black dots are missing, so I need formula or ‘a way’ to estimate possible center of these black dots.

I have tried by using regionprops, it help me to get center of these exist black dots, but no idea if black dots a missing

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
like image 372
user2368870 Avatar asked May 10 '13 06:05

user2368870


1 Answers

here's a way using fft in 1D over the x and y projection:

First, I'll blur the image a bit to smooth the high freq noise by convolving with a gaussian:

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

then I'll take the fft of a projection of each axis:

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 we can see both axis yield a peak at 0.07422 which translate to a period of 1/0.07422 pixels or ~ 13.5 pixels.

A better way to get also the angle info is to go 2D, that is:

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

enter image description here

and then apply tools such as simple geometry or regionprops if you want, you can get the angle and size of the squares. The size of the square is 1/ the size of the big rotated square on the background ( bit fuzzy because I blurred the image so try to do that without that), and the angle is atan(y/x). The distance between the squares is 1/ the distance between the strong peaks in the center part to the image center.

so if you threshold ml properly image say

 imagesc(ml>11)

you can access the center peaks for that...

yet another approach will be morphological operation on a binary image, for example I threshold the blurred image and shrink objects to points. It removes pixels so that objects without holes shrink to a point:

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

enter image description here

Then you practically have a one pixel per lattice site grid! so you can feed it to Amro's solution using Hough transform, or analyze it with fft, or fit a block, etc...

like image 104
bla Avatar answered Oct 21 '22 21:10

bla