Remove Grid Lines from a Graph

15 vues (au cours des 30 derniers jours)
Carl Youel
Carl Youel le 11 Juin 2021
Commenté : Carl Youel le 6 Juil 2021
Hello,
I'm trying to write a script that can remove grid lines from a graph. This question is very similar to this unanswered question.
I've attached an example below:
I'm pretty new to MATLAB, so this question may have an easy/obvious answer. But how do I use the image processing toolkit to identify and then manipulate lines (by manipulate, I mean delete, color, etc.)?
  1 commentaire
DGM
DGM le 11 Juin 2021
Are you just trying to get an approximation of the data represented by the graph, or are you just trying to edit the image?

Connectez-vous pour commenter.

Réponse acceptée

DGM
DGM le 11 Juin 2021
Modifié(e) : DGM le 11 Juin 2021
It depends what you want and what you expect. If all you want is one or two pictures, it's by far easier to do this manually outside of Matlab.
That said, here's a passing attempt to get rid of the lines.
inpict = rgb2gray(imread('testgraph.jpg'));
% process with a really wide edge filter
w = 100;
fk = repmat([-1 1],[w 1])./w;
a = imfilter(inpict,fk);
b = imfilter(inpict,fk.');
t = 20; % pick some threshold
% only pick N largest objects
c = bwareafilt(a>t,13,4) | bwareafilt(b>t,11,4);
% reduce line widths
c = bwmorph(c,'skel',100);
% make sure line ends don't touch image boundary
c([1 end],:) = 0;
c(:,[1 end]) = 0;
% make a mask to cover line ends and outer box
d = imdilate(bwareafilt(~c,1),ones(7));
% exclude ends & box, dilate wide enough to cover lines
c = imdilate(c&~d,ones(4));
outpict = inpict;
outpict(c) = 255; % apply mask
If you want to convert the image to numeric data, that's something else. Considering how almost every single graph I've ever tried to process or transcribe has been a tiny JPG with thick ambiguous lines and a crust of artifacts, I can't imagine any automated approach that isn't an exercise in frustration.
Here's an example, continuing from above:
% isolate plot box, get location
c = bwmorph(inpict<128,'skel',100);
c = bwareafilt(c,1,4);
S = regionprops(c,'boundingbox');
xl = [S.BoundingBox(1) sum(S.BoundingBox([1 3]))];
yl = [S.BoundingBox(2) sum(S.BoundingBox([2 4]))];
% isolate the curve only, find points
lpict = (255-outpict).*uint8(~d);
lpict = bwmorph(lpict>128,'thin',100);
lpict(1:100,:) = 0; % get rid of that number on top
[y x] = find(lpict);
% data range from graph
xrange = [-50 250];
yrange = [0 1E4];
% rescale to fit data range
x = xrange(1) + diff(xrange)*(x-xl(1))./diff(xl);
y = yrange(2) - diff(yrange)*(y-yl(1))./diff(yl);
% get rid of nonunique points; smooth
[x,idx,~] = unique(x);
y = y(idx);
xn = smooth(x);
yn = smooth(y);
plot(xn,yn); grid on
xlim(xrange)
ylim(yrange)
  3 commentaires
DGM
DGM le 14 Juin 2021
Modifié(e) : DGM le 14 Juin 2021
There can be plenty of improvements to the above code to improve accuracy. For instance, instead of using BoundingBox properties to define the plot box, you could filter to find the grid lines from a and b. Then you could use their Centroid properties to sort them and find the outermost four. That would make the calculation of the plot box (and consequently the data scaling) less susceptible to influence from spur defects on the lines. Like I said though, I don't really trust anything to automatically process the original images without tedious levels of oversight anyway
Personally, I tend to just throw the image in Inkscape and redefine the plot box with fine lines (or a rectangle) and trace over the curve with a bezier. I can then export the image at whatever resolution I want and use a similar technique to process it in Matlab. I suppose it would make more sense to process the SVG to get the curve more directly, but using a high-res raster copy is plenty adequate given the expected accuracy limitations of the source material.
For example, this image is a lot easier to process:
The SVG from which that was exported is attached. I had to put it in a zip archive because the editor doesn't know what an SVG is. Note that Matlab no longer needs to programmatically find the plot box; it's simply defined by the image geometry.
Carl Youel
Carl Youel le 6 Juil 2021
Thanks much, I'll certainly look into these methods. I was able to get some pretty good results, at least with the one graph I shared above, but I can definitely see how making this process automated would be pretty difficult

Connectez-vous pour commenter.

Plus de réponses (0)

Catégories

En savoir plus sur Images dans Help Center et File Exchange

Produits


Version

R2020a

Community Treasure Hunt

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

Start Hunting!

Translated by