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

28 ビュー (過去 30 日間)
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.

回答 (3 件)

Jonas
Jonas 2022 年 11 月 28 日
% 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);
imgLine = 1×250
0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
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 件のコメント
Jonas
Jonas 2022 年 11 月 28 日
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)
ans = 10

サインインしてコメントする。


Bjorn Gustavsson
Bjorn Gustavsson 2022 年 11 月 28 日
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 件のコメント
Bjorn Gustavsson
Bjorn Gustavsson 2022 年 11 月 29 日
Yup. What do you count as a vertical line in this weave (is it? Hopefully correct identification of cloth?)? To my eyes there seem to be at least 2 different coloured threads in the vertical direction, one yellow-orange and one dark green or brownish, do they count as 2 different vertical lines? One other idea is to count how many horizontal white dashes there is along one row, that would correspond to roughly half the number of vertical threads (possibly a quarter?).

サインインしてコメントする。


Image Analyst
Image Analyst 2022 年 11 月 29 日
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.

製品


リリース

R2022b

Community Treasure Hunt

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

Start Hunting!

Translated by