finding edge/ plot from image/ maze

2 views (last 30 days)
Soroush Sabbaghy
Soroush Sabbaghy on 28 Mar 2023
Edited: DGM on 28 Mar 2023
I want to extract plot form this image. what approch works the best?

Answers (3)

KSSV
KSSV on 28 Mar 2023
You can use contour.

Image Analyst
Image Analyst on 28 Mar 2023
I'd try using
indexedImage = rgb2ind(rgbImage, 8);
to get an indexed image. Then find out the index for each color and ignore the ones for black and white.
Then scan your image column-by-column finding the first row where each index occurs. For any missing columns (like where one color went underneath a different color, use interp1 to interpolate the value. Something like
[rows, columns, numberOfColorChannels] = size(rgbImage);
brownCurve = nan(1, columns);
redCurve = nan(1, columns);
purpleCurve = nan(1, columns);
greenCurve = nan(1, columns);
orangeCurve = nan(1, columns);
blueCurve = nan(1, columns);
for col = 1 : columns
thisColumn = indexedImage(:, col);
% Find if there is a red curve in this column.
row = find(thisColumn == redIndex, 1, 'first');
if ~isempty(row)
redCurve(col) = row;
end
% Find if there is a brown curve in this column.
row = find(thisColumn == brownIndex, 1, 'first');
if ~isempty(row)
brownCurve(col) = row;
end
end
% Interpolate missing data points
missingIndexes = isnan(redCurve);
x = 1 : columns;
redCurve = interp1(x(~missingIndexes), y(~missingIndexes), x);
% Etc.
Of course there is a lot missing there but I'm confident you'll be able to finish it, right?

DGM
DGM on 28 Mar 2023
Edited: DGM on 28 Mar 2023
I'm assuming that the goal is to take the second image and reduce it to plottable data such as would generate a plot like the first one. I'm just going to do this the same way I always do it, so see the links for explanations, examples, and more links to the same. The same commentary applies here, with the additional caveat that I have no idea what this plot actually means.
See the attached SVG file.
% 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 = 'drawing.svg';
% data range from original image axis labels
% this is where the rectangle is drawn in the SVG
xrange = [0 1]; % this is arbitrary
yrange = [0 60];
% spline discretization parameter [0 1]
coarseness = 0.01;
% 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);
% if there are multiple paths you want to extract
% you'll need to do do the rescaling, etc for each element of S
for k = 1:numel(S) % there are multiple curves
x = S{k}(:,1);
y = S{k}(:,2);
% 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,'stable');
y = y(idx);
% shove the prepared data back into S for later
S{k} = [x y];
end
% the last two curves are actually just marker lines used to locate M,K
% in order for these to be the "last two", they must have the highest
% z-order of the curves. Use "bring to front", "raise selection", or
% simply draw them last.
xM = mean(S{k-1}(:,1));
xK = mean(S{k}(:,1));
S = S(1:end-2); % get rid of markers
% plot the curves
for k = 1:numel(S)
x = S{k}(:,1);
y = S{k}(:,2);
plot(x,y); hold on
end
% plot the marker lines
xline(xM);
xline(xK);
grid on;
xlim(xrange)
ylim(yrange)
% set xticks and labels
xticks([0 xM xK 1])
xticklabels({'\Gamma' 'M' 'K','\Gamma'})
It's difficult to tell which curves are which when they intersect, but I am assuming that the final curve ordering is simply based on height. If the curve trajectories need to be done differently, then simply edit the attached SVG.
%% split and order curves based on height
% interpolate each curve on to a common abcissa
npoints = 1000;
xnew = linspace(xrange(1),xrange(2),npoints);
ynew = zeros(numel(S),npoints);
for k = 1:numel(S)
x = S{k}(:,1);
y = S{k}(:,2);
ynew(k,:) = max(interp1(x,y,xnew),yrange(1));
end
ynew = sort(ynew,1,'descend');
% plot the curves
clf
plot(xnew,ynew)
% plot the marker lines
xline(xM);
xline(xK);
grid on;
xlim(xrange)
ylim(yrange)
% set xticks and labels
xticks([0 xM xK 1])
xticklabels({'\Gamma' 'M' 'K','\Gamma'})
If instead, the goal is to extract the curves from both images, then simply perform the same transcription on the first image using a vector graphics editor.

Community Treasure Hunt

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

Start Hunting!