Find wavelength in an image

3 views (last 30 days)
Hendrik
Hendrik on 4 Nov 2020
Hello everybody,
I have a picture where I can see the wavelength with my eye quite clearly, but I want matlab to find it automatically.
I tried that by doing a fft of the center column but I couldn't see a high peak in the result besides the one at x = 0.
I know that 700 pixels equals 16mm.
The code:
grayImage = rgb2gray(myImage); %myImage is the Image I've attatched
Y = fft(grayImage(:,450));
P2 = abs(Y/675);
P1 = P2(1:675/2+1);
P1(2:end-1) = 2*P1(2:end-1);
f = (0:(675/2))/675;
plot(f,P1)
I know this probably is a very simple problem, but I'm new to matlab.
Regards, Hendrik Sorhage
  6 Comments
Rik
Rik on 4 Nov 2020
You can remove the 0 peak by subtracting the mean:
myImage=imread('FirstShot_klein.jpg');
grayImage = rgb2gray(myImage); %myImage is the Image I've attatched
data=grayImage(:,450);
data=double(data);data=data-mean(data);
Y = fft(data);
P2 = abs(Y/675);
P1 = P2(1:floor(675/2+1));
P1(2:end-1) = 2*P1(2:end-1);
f = (0:(675/2))/675;
plot(f,P1)
This still doesn't result in very pronounced peaks, but you could try this for every column of your image (be sure to only select the rows with relevant data and calculate a weighted average, using the number of relevant rows as weight factor).
Hendrik
Hendrik on 5 Nov 2020
Thanks to both of you, with your help I've managed to get get a significant peak. I've calculated the average over 20 columns in the middle. But I still have one problem, as I said 16mm equals 700 pixels, but how do I scale the x axis with that information correctly?

Sign in to comment.

Answers (1)

Bjorn Gustavsson
Bjorn Gustavsson on 4 Nov 2020
Ok, there are a couple of points to make.
1, Your selected column is not entirely filled with you object but also contains a bit of bright background. Since the fft is a circular fft that means that if the array is not periodic the intensity-jump from the last element to the first will give the fft a lot of high-frequency components.
2, your function contains a lot of noise at high frequencies, therefore you might benefit from smoothing your image. Something like this:
I = imfilter(I,conv2(ones(3)/9,ones(5)/25,'full'));
3, when you plot the column, you'll see that there is a lot of "almost-periodic" variations. This will give you a wide spectrum. I'd suggest that you find the row-indices for local maxima and minima. Then you can plot the difference between these indices - if your
wave has a wavelength-modulation along the column you might pick up that way.
HTH
  4 Comments
Hendrik
Hendrik on 5 Nov 2020
Yes I know, the x-axis is the frequency. But is it exactly 1\pixel? Because then it would be really easy to calculate the wavelength.
Bjorn Gustavsson
Bjorn Gustavsson on 6 Nov 2020
It should be something like this:
n_pix = numel(img_column);
dpix = 1;
k = [0:n_pix/2-1,-n_pix/2:-1] / (dpix*n_pix); % if you have an even number of pixels
k = [0:n_pix/2,-n_pix/2:-1] / (dpix*n_pix); % if you have an odd number of pixels
That is max wavenumber should be "2*pi/(2 pixels)" which is the Nyquist-limit.

Sign in to comment.

Products

Community Treasure Hunt

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

Start Hunting!