How may one digitize a curve from an image

3 views (last 30 days)
The attached jpeg contains battery discharge curves at various discharge currents (0.68 to 10 A).
I'd like to create arrays (stored in a .mat file) which contains these discharge curves (voltage vs capacity).
Ideally I just need the data for the 0.68 A curve.
How would one "digitize" the 0.68A curve into X and Y coordinates/values given a minimum step size?
Thank you

Accepted Answer

DGM
DGM on 14 Jun 2022
Edited: DGM on 14 Jun 2022
These two answers are relevant and contain links to other related answers.
Long story short, accuracy will be limited, and trying to write something that will automagically find the right curve is almost always going to be a waste of time, especially if you only have one plot to transcribe. Just manually transcribe the curve as described. I've attached an SVG file that's already had a spline fit to it. The SVG processing is as described in the answers above.
% using the following FEX tools:
% https://www.mathworks.com/matlabcentral/fileexchange/72225-load-svg-into-your-matlab-code
% filename of manually-fit svg file
fname = 'discharge_curves.svg';
% data range from original image axis labels
xrange = [0 4000];
yrange = [0 5];
% spline discretization parameter [0 1]
coarseness = 0.001;
% get plot box geometry
str = fileread(fname);
str = regexp(str,'((?<=<rect)(.*?)(?=\/>))','match');
pbx = regexp(str,'((?<=x=")(.*?)(?="))','match');
pby = regexp(str,'((?<=y=")(.*?)(?="))','match');
pbw = regexp(str,'((?<=width=")(.*?)(?="))','match');
pbh = regexp(str,'((?<=height=")(.*?)(?="))','match');
pbrect = [str2double(pbx{1}{1}) str2double(pby{1}{1}) ...
str2double(pbw{1}{1}) str2double(pbh{1}{1})];
% get coordinates representing the curve
S = loadsvg(fname,coarseness,false);
x = S{1}(:,1); % assuming the first path is the correct one
y = S{1}(:,2);
% if there are multiple paths you want to extract
% you'll need to do do the rescaling, etc for each element of S
% rescale to fit data range
x = xrange(1) + diff(xrange)*(x-pbrect(1))/pbrect(3);
y = yrange(1) + diff(yrange)*(pbrect(4) - (y-pbrect(2)))/pbrect(4);
% get rid of nonunique points
[x,idx,~] = unique(x);
y = y(idx);
% plot
plot(x,y); grid on; hold on
xlim(xrange)
ylim(yrange)
At this point, x and y will be relatively finely sampled. If you want to resample the curve on a coarser abcissa, you can use interp1().

More Answers (1)

Image Analyst
Image Analyst on 14 Jun 2022
Lots of File Exchange submissions on digitizing a graph:

Products


Release

R2021b

Community Treasure Hunt

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

Start Hunting!