Remove Grid Lines from a Graph

15 views (last 30 days)
Carl Youel
Carl Youel on 11 Jun 2021
Commented: Carl Youel on 6 Jul 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 Comment
DGM
DGM on 11 Jun 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?

Sign in to comment.

Accepted Answer

DGM
DGM on 11 Jun 2021
Edited: DGM on 11 Jun 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 Comments
DGM
DGM on 14 Jun 2021
Edited: DGM on 14 Jun 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 on 6 Jul 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

Sign in to comment.

More Answers (0)

Categories

Find more on Images in Help Center and File Exchange

Products


Release

R2020a

Community Treasure Hunt

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

Start Hunting!