# How to find the count of vertical lines in an image using Fourier Transform in MATLAB?

25 views (last 30 days)

Show older comments

I have taken an image of a grid and have obtained the vertical lines from the grid image using the following code.

But I now want to calculate the number of lines present using Fourier Transform on the "ver.jpeg" file.

clc

clear

close all

warning off

x=im2gray(imread('img-grid.png'));

x=~imbinarize(x);

%line structuring element

%2nd param- line length = 20px

%3rd param- angle = 90 for vertical lines

SE = strel('line',20,90);

%applying erosion to remove horizontal lines

s=imerode(x,SE);

%erosion shrinks vertical lines as well so applying dilation

s=imdilate(s,SE);

imwrite(s, 'ver.jpeg');

imshow(x)

title("Original")

imshow(s)

title("Vertical lines")

The below code I have used fft() function to get corresponding values for the 1st pixel row of image "ver.jpeg" but I am unable to make sense of the output.

%fourier transform

x=im2gray(imread('ver.jpeg'));

f=imbinarize(x);

row1 = f(1, :);

imshow(row1)

Y = abs(fft(row1));

plot(Y)

hold on;

plot(row1)

hold off;

subplot(2, 1, 1);

plot(Y)

title("fft(row1)")

subplot(2, 1, 2);

plot(row1)

title("row1 of ver.jpeg")

Can someone please help me how to get the count of lines from the image?

Thank you in advance.

##### 0 Comments

### Answers (3)

Jonas
on 28 Nov 2022

% create sample image

imgLine=repmat([ones(1,5) zeros(1,20)],[1 10]);

% shift it a bit to force broken (incomplete) lines

imgLine=circshift(imgLine,8);

tiledlayout(3,1);

nexttile();

imshow(imgLine)

fMax=numel(imgLine)/2;

freq=-numel(imgLine)/2:numel(imgLine)/2-1;

nexttile()

plot(freq,abs(fftshift(fft(imgLine))))

nexttile()

% without mean (DC) value

plot(freq,abs(fftshift(fft(imgLine-mean(imgLine)))))

xlabel('oscillations per image')

xlim([-15 15])

% first Peak seems to be near 10 -> 10 complete lines per image

as you can see, the question is how you want to count not cemplete lines. In itself, there were 9 complete lines and 2 divided, but 2 divided give 1 complete

##### 2 Comments

Jonas
on 28 Nov 2022

yes, thats possible, e.g. like that

imgLine=repmat([ones(1,5) zeros(1,20)],[1 10]);

% shift it a bit to force broken (incomplete) lines

imgLine=circshift(imgLine,8);

tiledlayout(4,1);

nexttile();

imshow(imgLine)

fMax=numel(imgLine)/2;

freq=-numel(imgLine)/2:numel(imgLine)/2-1;

nexttile()

plot(freq,abs(fftshift(fft(imgLine))))

nexttile()

% without mean (DC) value

withoutMean=abs(fftshift(fft(imgLine-mean(imgLine))));

plot(freq,withoutMean)

xlabel('oscillations per image')

xlim([-15 15])

withoutMean(freq<0)=[];

freq(freq<0)=[];

nexttile

findpeaks(withoutMean,freq,'NPeaks',1,'MinPeakHeight',0.8*max(withoutMean))

% you could use the output of findpeaks to get location or, if the value is

% the biggest

[~,idx]=max(withoutMean);

freq(idx)

Bjorn Gustavsson
on 28 Nov 2022

Why in the world do you want to use the Fourier transform to do that? You might be OK-ish for this specific pattern since it (superficially) seems regular, for that you could just check the first non-zero-frequency peak in the fft-spectrum. You know that the first component corresponds to an intensity-variation with a period-length of the full sequence, the second 2 component corrsponds to intensity-variations with 2 full periods over the entire sequence and on and on.

BUT: Why in the world do you want to use the Fourier transform to do this? In every non-classroom situation you can count on the signal being quasi-periodic - and in that case this is going the extra step to create a far more tricky problem.

##### 3 Comments

Bjorn Gustavsson
on 29 Nov 2022

Image Analyst
on 29 Nov 2022

I'd make a mask of the white. Then erase that part of the image. Then I'd sum the image vertically. You should get a signal with a bunch of peaks. Use findpeaks to locate their coordinates. Seems pretty easy but let us know if you have problems. Doing it in the spatial domain like this will let you locate every stripe even if they are not evenly spaces.

If you want to use Fourier you can take the 1-D fft of the sum signal and look for the dominant (non-DC) peak. Or take the 2D fft and look for the dominant peak along the y axis (since vertical stripes will diffract horizontally).

You could do a similar process on the white mask if you want the frequency of the white threads.

Doing it in the Fourier domain will give you the average frequency of the stripes, but not each one individually.

##### 0 Comments

### See Also

### Categories

### Community Treasure Hunt

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

Start Hunting!