searching for a line of pixels in an image

13 vues (au cours des 30 derniers jours)
Timothy Dunning
Timothy Dunning le 15 Mar 2023
Modifié(e) : DGM le 12 Nov 2023
I have been set a task for which part is to read data from an image of a graph.
I have been able to detect the red line fairly simply by seaching for where the rgb valuse match the red on the graph (the image reads as a 3D array of uint8 type rgb values) but i need to be able to find the black axes lines for reference to calculate the values. This is more tricky as the numbers and labels are also black. I planned to search for a row and a column where most of the values are (0,0,0) and are consecutive. What is the best way to achieve this?

Réponse acceptée

DGM
DGM le 15 Mar 2023
Modifié(e) : DGM le 12 Nov 2023
There are FEX submissions that are meant for this, but I have my opinions.
This is my advice and an example of the basic approach I use for plot transcription. See the links therein for caveats.
Applied to the given image:
% 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 = 'redtemp.svg';
% data range from original image axis labels
xrange = [0 2000];
yrange = [0 2000];
% 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)
The SVG file is attached. You can tweak the spline as you see fit. As I mention in the other threads, the advantage of using external tools is largely the improved controls (both view controls and spline editing). Visual fitting is no loss when we accept that the source is grossly imprecise to begin with.
This thread includes a rough tutorial on how the SVG file is created (see the comments)
  3 commentaires
Timothy Dunning
Timothy Dunning le 16 Mar 2023
thanks for the help. May I ask a few very basic questions? Can you explain what is a plot box, a spline and what is the purpose of the svgload function?
DGM
DGM le 17 Mar 2023
Modifié(e) : DGM le 17 Mar 2023
The plot box is the rectangular region described by the extent of the x,y axis rulers. It's the green area in this image.
The location and extent of the plot box (or at least the box defined by the extreme axis ticks) is important because it essentially provides calibration information. Knowing where x=0 and x=2000 in pixels tells us what a given pixel's position is in data coordinates (i.e. seconds).
When I say "spline", I'm talking somewhat loosely. In the context of what would be done natively within MATLAB if building a curve from interactively selected points, you'd be creating some uncontrolled interpolating spline or smoothing spline. If you're using an actual graphics tool to do the work in a practical manner, you'd be creating a Bézier spline, where the control points are actually adjustable. In Inkscape, it would look like:
Node type and symmetry are configurable per-point. Again, note that the plot box is defined by the light orange rectangle.
As the original graph image is traced in Inkscape (or any competent vector editing program), the result is a vector graphics file. In this case, it's an SVG file. Correspondingly, svgload() is used to read the file and the properties of the vector objects therein. In this case, I'm only using it to read the spline (the trace) as xy data in image coordinates. Again, the light orange rectangle in the image above tells the script where the plot box is.
Can you use GRABIT or other MATLAB transcription tools? Yes. Most should work for a simple graph like this.
As I mentioned in the linked answer, I feel that anything that does the task in MATLAB is going to be a compromise. The view controls are universally cumbersome, laggy, and buggy. Depending on the specific tool, you constantly have to disable your cursor tool so that you can move or zoom without dumping errors and warnings to console. I also don't like that GRABIT has no real way to assert that the image is already grid-aligned. You're forced to carefully try to pick the box extents by hand without misaligning a single click, otherwise it will perform a projective transformation to the detriment of accuracy. I also don't like that there's no good way to say that the x and y axes begin in the same location -- which is something incredibly basic. There's also no way to adjust a point -- or even see where it's located after you click.
In the end, you just get a set of questionably selected points -- a simple rough polyline.
I prefer to just transcribe the curve with a spline in a vector image editor with actual view controls made for human use. The spline can be fit visually by you to whatever degree you feel best fits your particular JPG pixel salad. For a tiny low-res graph like this, the benefits of fitting a spline are questionable, but it's what I'm sticking with. Even if a rough polyline suffices, I'd rather have usable view controls.
Like I said, I have my opinions. As it's something that I don't tolerate myself, it's not something that I recommend beyond mere mention. It's ultimately up to you to decide what you are comfortable using. I admit that the solution I gave might not be comfortable to someone who isn't used to doing vector graphics.

Connectez-vous pour commenter.

Plus de réponses (1)

Image Analyst
Image Analyst le 16 Mar 2023
Here are some File Exchange submissions and you can see how they did it.

Catégories

En savoir plus sur Splines dans Help Center et File Exchange

Produits


Version

R2022a

Community Treasure Hunt

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

Start Hunting!

Translated by