# Get 2d corner coordinates / layout using edge detection

I'm new to Mathematica but I found an interesting usage of it: I'm programming a 2D game, with a top-view, where I'd like to have the edge coordinates of the walls. EdgeDetection delivers me quite a good result:

In this post, I saw a really impressing example of getting picture points into a (even) 3D plot. I found PixelValuePositions[background, 1] which delivers me all white pixels. However, I really don't understand how to get the 4 corners of after running EdgeDetect and creating a immense list of white pixels.

How can I (iterate) through the points, to get the 4 corners every wall has?

Update 1:

I view walls as simple rectangular shapes, given by two corners. The expected results are for each "wall rectangle" two points that define the rectangle (x1, y1) and (x2, y2).

Is it possible to get an output just like:

x1 y1 x2 y2
x1 y1 x2 y2


this means, just "printing out" the coordinates of a rectangle on a line, then give the next rectangle on a new line?

Update 2:

As s.s.o mentioned, it seems to be quite related to this post. The accepted answer uses ComponentMeasurements, but I simply don't get it how it works and if it does for my situation, too.

• @YvesKlett Do you think I need to use MorphologicalGraph as well? Nov 1, 2014 at 14:24
• Not neccessarily, but might be worth a try. Nov 1, 2014 at 14:34
• Mathematica stops calculating, before I can see a result. Might this be, because (at the moment) I only have a trial version of Mathematica 10? Nov 1, 2014 at 14:37
• you should see the post mathematica.stackexchange.com/questions/19546/… Nov 2, 2014 at 11:54

url = "https://i.stack.imgur.com/rM4LS.png";
img = MorphologicalBinarize@Import[url];
cornerslist = ImageCorners[img];

Show[
img2,
ListPlot[
{
cornerslist
}
, PlotStyle -> Red
, PlotMarkers -> Automatic
]
]


rectcorner = Join[
MinimalBy[cornerslist, First, 2],
MaximalBy[cornerslist, First, 2]
]

{{78.5, 46.5}, {79.5, 314.5}, {554.5, 311.5}, {554.5, 48.5}}

Show[
img,
Graphics[{Blue, Opacity[0.3], Polygon[rectcorner]}],
ListPlot[rectcorner], PlotStyle -> Red]
]


lines = ImageLines[EdgeDetect[img]];
Show[img, Graphics[{Thick, Orange, Line /@ lines}]]


• Wow, this is very impressive! If I follow your code and at the end, just type lines, I get a list of coordinates. These are coordinates you used to draw the orange lines on top of the image, aren't they? However, I'd like to get the coordinates of every wall segment. If you have a look at the left room at the bottom, you can see that the little wall forming the door, doesn't get recognized. Your approach is pretty close to my expected results! Nov 2, 2014 at 16:19
• @pentix look at the first lines where cornerslist is defined. Nov 2, 2014 at 16:28
• @pentix There are also parameters you can play with (see the documentation. For example: lines = ImageLines[EdgeDetect[img], 0.05, 0.005]; Show[img, Graphics[{Thick, Orange, Line@Select[lines, Min@Abs@Differences@# < 3 &]}]], where Select picks out lines whose difference in x or difference in y is less than 3 pixels. Nov 2, 2014 at 19:04
• @rhermans Thanks a lot! I get to same result, and it works so far. However, the last part what I'm looking for. (I'm sorry for noticing this that late!) I updated the original question, please have a look at it. Thank you very much! Nov 4, 2014 at 17:26
• @pentix you are moving the goal post! :) You need to explain better what do you mean with the 4 points per wall. Walls with thickness and shared regions with other walls makes this ambiguous. Nov 4, 2014 at 17:53