How may one digitize a curve from an image
12 views (last 30 days)
Show older comments
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
0 Comments
Accepted Answer
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().
0 Comments
More Answers (1)
See Also
Categories
Find more on Interpolation in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!