How to detect a thick grid in an image

30 views (last 30 days)
I need to determine the lattice constant in pixels and the angle with respect to the axes of the thick grid in a lot of images like the one below.
So i want to plot lines like in the image below and get the distance between two lines and the angle with respect to the axes.
This is my first try at image processing and my first idea was using fourier transformation because of the periodicity of the grid.
Without fully understanding how fourier works in 2D, i tried fft2() and filtered out frequencies with low amplitudes
%create image
I=imread('image','jpg');
I2= im2bw(I,0.2);
BW=-(I2-1);%invert image
%fourier
A=fft2(BW);
ma=max(abs(A),[],'all');
A(abs(A)<0.3*ma)=0;%remove small intensities
imagesc(ifft2(A))
Sadly after inverse fft for the frequencies with the highest amplitudes, the angles are always a little bit off.
The yellow lines are the invese fourier transformation of the frequency with the highest amplitude. As you can see the the yellow lines dont quite match the grid.
I alternativly tried to use hough() alongside edge(), but i only managed to properly detect thin lines this way.
I would be thankful for suggestions of better methods or corrections for the methods i used.

Accepted Answer

Image Analyst
Image Analyst on 6 Mar 2021
Try taking the radon transform to get projections at every angle, then use find peaks to determine the spacing of the dark gridlines.
clc; % Clear command window.
clear; % Delete all variables.
close all; % Close all figure windows except those created by imtool.
workspace; % Make sure the workspace panel is showing.
fontSize = 18;
markerSize = 20;
LineWidth = 2;
rgbImage = imread('blue grid.jpeg');
grayImage = rgbImage(:, :, 3);
subplot(2, 2, 1);
imshow(grayImage, []);
axis('on', 'image');
title('Blue Channel of Image', 'fontSize', fontSize);
% Do the radon transform to get projections at a bunch of angles.
theta = 0 : 359;
r = radon(grayImage, theta);
subplot(2, 2, 2);
imshow(r, []);
axis('on', 'image');
title('Radon Transform', 'fontSize', fontSize);
% find peak
maxValue = max(r(:));
[rows, cols] = find(r == maxValue);
hold on;
plot(cols, rows, 'r+', 'LineWidth', 2, 'markerSize', 17);
theProfile = r(:, cols(1));
subplot(2, 2, 3:4);
plot(theProfile, 'b-', 'LineWidth', 2);
grid on;
[peakValues, indexes] = findpeaks(-theProfile, 'MinPeakProminence', 1500)
hold on;
plot(indexes, -peakValues, 'r+', 'LineWidth', 2, 'markerSize', 17);
% Get the spacing between the peaks
spacings = diff(indexes)
% Get the mean grid spacing.
meanGridLineSpacing = mean(spacings);
caption = sprintf('Mean Grid Spacing = %.1f Pixels.', meanGridLineSpacing);
title(caption, 'fontSize', fontSize);
  3 Comments
KALYAN ACHARJYA
KALYAN ACHARJYA on 7 Mar 2021
@Image Analyst so nice sir, thanks for continuing to teach us.
Image Analyst
Image Analyst on 7 Mar 2021
Yes, the "x" coordinate of the radon transform in the image is the angle. I found the max of the radon transform because when the projections are going perfectly down all the bright squares, aligned with them, that's when the radon transform (sum along the projection angle) will be the greatest. And that angle is the column number of the radon transform, or whatever angle the column number represents (in the case where you did not do angles every 1 degree like I did, but maybe at every tenth or half degree or whatever). Thanks for Accepting and voting and compliments. 😊

Sign in to comment.

More Answers (0)

Products


Release

R2020b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!