Fit a polynimial function on a image curve
32 views (last 30 days)
Show older comments
In image analysis, how can I fit a five or six order polynomial on a waved curve? And how can I determine that polynomial function?
0 Comments
Accepted Answer
Image Analyst
on 21 Jun 2020
How about this:
% Demo to find fitted curve.
% By Image Analyst
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
clear; % Erase all existing variables. Or clearvars if you want.
workspace; % Make sure the workspace panel is showing.
format long g;
format compact;
fontSize = 22;
%--------------------------------------------------------------------------------------------------------
% READ IN IMAGE
folder = pwd;
baseFileName = 'image.jpeg';
% Get the full filename, with path prepended.
fullFileName = fullfile(folder, baseFileName);
% Check if file exists.
if ~exist(fullFileName, 'file')
% The file doesn't exist -- didn't find it there in that folder.
% Check the entire search path (other folders) for the file by stripping off the folder.
fullFileNameOnSearchPath = baseFileName; % No path this time.
if ~exist(fullFileNameOnSearchPath, 'file')
% Still didn't find it. Alert user.
errorMessage = sprintf('Error: %s does not exist in the search path folders.', fullFileName);
uiwait(warndlg(errorMessage));
return;
end
end
grayImage = imread(fullFileName);
% Get the dimensions of the image.
% numberOfColorChannels should be = 1 for a gray scale image, and 3 for an RGB color image.
[rows, columns, numberOfColorChannels] = size(grayImage);
if numberOfColorChannels > 1
% It's not really gray scale like we expected - it's color.
% Use weighted sum of ALL channels to create a gray scale image.
grayImage = rgb2gray(grayImage);
% ALTERNATE METHOD: Convert it to gray scale by taking only the green channel,
% which in a typical snapshot will be the least noisy channel.
% grayImage = grayImage(:, :, 2); % Take green channel.
end
%--------------------------------------------------------------------------------------------------------
% SEGMENTATION OF IMAGE
% Get a binary image
binaryImage = imbinarize(grayImage);
subplot(3, 1, 1);
imshow(binaryImage, []);
impixelinfo;
title('Binary Image', 'FontSize', fontSize, 'Interpreter', 'None');
hFig = gcf;
hFig.WindowState = 'maximized'; % May not work in earlier versions of MATLAB.
drawnow;
%--------------------------------------------------------------------------------------------------------
% REMOVE BOTTOM ARC
for col = 1 : columns
thisCol = binaryImage(:, col);
% Remove largest blob.
biggestBlob = bwareafilt(thisCol, 1);
thisCol(biggestBlob) = false;
binaryImage(:, col) = thisCol;
end
% Display it.
subplot(3, 1, 2);
imshow(binaryImage)
grid on;
title('Without bottom arc', 'FontSize', fontSize, 'Interpreter', 'None');
% Get (x,y) of what's left
[y, x] = find(binaryImage);
% Add a tiny bit of noise because sometimes there are multiple y for the same x.
x = x + 0.001 * rand(1, length(x));
% Sort them
[x, sortOrder] = sort(x, 'ascend');
y = y(sortOrder);
% Filter with movmean
ySmoothed = movmean(y, 5);
% Display it.
subplot(3, 1, 3);
imshow(binaryImage)
grid on;
title('With Fitted Curve in Red', 'FontSize', fontSize, 'Interpreter', 'None');
hold on
plot(x, ySmoothed, 'r-', 'LineWidth', 3);
0 Comments
More Answers (1)
Matt J
on 21 Jun 2020
Edited: Matt J
on 21 Jun 2020
A sixth order polynomial won't give a very good fit, but here is how you could code it:
load waveImage A
[I,J]=find(medfilt2(A,[7,1])-A==-1);
I=size(A,1)+1-I;
p=polyfit(J,I,6);
plot(J,I,'x',J,polyval(p,J),'-')
3 Comments
Image Analyst
on 21 Jun 2020
Why do you want a polynomial fit instead of just the smoothed data? You could use something like movmean() or sgolayfilt() to get a curve going through the noisy data. It won't be a perfect polynomial but it will be a better fit to the actual data.
Matt J
on 21 Jun 2020
Edited: Matt J
on 21 Jun 2020
How can I get the data of wave?
The raw wave data is J,I in my code. In addition to what Image Analyst suggested, you might also consider a cubic smoothing spline,
load waveImage A
[y,x]=find(medfilt2(A,[7,1])-A==-1);
y=size(A,1)+1-y;
[ yfit,ppfun,M ] = ezsplinefit( x(1:40:end),x,y);
p = 0.001;
sp = csaps(x,y,p);
clf
hold on
fnplt(sp);
plot(x,y,'co');
hold off
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!