1

I have a bw image made up of lines, and am trying to extract "critical" points from it. That is, I am trying to extract an ordered list of points, such that connecting adjacent points should give something back that is close to the original input.

I first tried detecting corners using C = corner(I) and variants. These detected good points, however were unordered, so didn' accomplish what i was looking for.

I have a piece of code currently that gives me the ordered list, however does not extract enough points to describe the image. Attached is the sample image, and code:

I = imbinarize(rgb2gray(imread('rightRaw.png'))); % Read image ad convert to binary

J = padarray(I, [1, 0], 1, 'post'); % Insert row of ones at the bottom

J = imfill(J, 'holes'); % Fill inner pixels.
J(end, :) = J(end, :) & J(end-1, :); % Keep only the closing line at the bottom 

% Get X,Y coordinates of all white points 
[Y, X] = find(J > 0);

% Get boundary of the set of points
k = boundary(X, Y);

% Get x,y coordinates of the boundary
x = X(k);
y = Y(k);

% Remove coordinated of bottom line
x = x(y < size(J, 1));
y = y(y < size(J, 1));

The result is as follows (line in white, points in blue)enter image description here

As you can see, connecting adjacent points will not describe the image well at all. I believe the issue is that I am using boundary. Is there a way to preserve information about all of the edges so that I get internal lines as well? There will be multiple shapes and lines possibly inside of them.

I essentially want the same points retrieved by corner, however with ordering preserved.

Here is a copy of my original:

enter image description here

@beaker:

enter image description here

  • I seem to have seen this question before. Can you post your original image? What ordering do you expect for the left side of your image where two arcs connect? – beaker Mar 19 '20 at 16:09
  • I have added a copy of the original. Ideally this would be split into 3 separate sets of points. The first representing the curve on the left, the next representing the arc, and finally the last representing the curve on the right. Once I have the 3 list of points, for each list I should be able to connect adjacent points, and the result should be something "similar" to the original as in the description –  Mar 19 '20 at 16:33
  • @beaker updates have been made :) –  Mar 19 '20 at 19:27
  • My first thought would be to do a depth-first search on the binarized image (or possibly the points returned by `corner`), choosing the closest point first at each step. Your image is *almost* a single path, so this might leave some stray pixels as their own path. If you don't want those, you can always filter out paths under a certain length. – beaker Mar 19 '20 at 21:46
  • interesting. Is there a way to do this in a way that would give me multiple sets of points. I am not too sure what this would look like exactly, but your idea sounds like it could be promising. Everything i have tried only gives the boundary. Do you have an idea of what the binary search may look like? Also, the image itself can be much more complicated than the one shown. It can have boundaries, with shapes inside of boundaries etc –  Mar 19 '20 at 21:52
  • I think if you perform the depth-first search, every time you pop a point from the stack, if it is *not* connected to the previous pixel in the path, it must be a new path. That will certainly work on the disconnected loop on the right, and it should separate the left loop from the middle one, but again, it might introduce paths of just a couple of pixels if you have little spurs coming off the main path. – beaker Mar 19 '20 at 21:55
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/209959/discussion-between-iza-and-beaker). –  Mar 19 '20 at 22:21
  • Is [this](https://stackoverflow.com/questions/29317202/detect-corner-coordinates-of-a-non-convex-polygon-in-clockwise-order-matlab/29336470#29336470) the kind of thing you are looking for? – Cecilia Mar 19 '20 at 23:31
  • @Cecilia, Similar, except I am not working with polygons. In that post, the user is getting corner points and then sorting them, which is exactly what I want to do, however using convex hull to sort wont work because I have line drawings. –  Mar 20 '20 at 01:31
  • Perhaps there may be a way to continuously call convex hull to get the correct results? –  Mar 20 '20 at 01:32
  • My answer on that post does not use convex hull to sort the points. It uses `bwdistgeodesic` which only works on lines. I actually show how to first convert from a filled polygon to a perimeter line. I think the challenge of converting that answer for your use case will be the multiple line intersections that you have. How do you want ordering to be handled around an intersection? – Cecilia Mar 20 '20 at 16:59
  • Whatever would be most convenient for intersection points will be fine. All that matters is that after the algorithm is finished, I can connect adjacent points in order to recreate something similar to the original. @Cecilia :) –  Mar 20 '20 at 19:36

0 Answers0