Ask Your Question

Identify the best angle to orient a map

asked 2017-03-17 23:58:04 -0500

cpagravel gravatar image

updated 2017-03-20 22:06:18 -0500

This is the image I am working with: Robotics map

My goal is to rotate this (within a hundredth of a degree) so that the longest-lines/most-lines are completely horizontal.

First Attempts

The first thing I did was look into using Houghlines for this, but it doesn't help me find the "best" lines in my image. It just produces a set of lines and angles; this is a problem because there may be a lot of lines in my map and I need to know the length and angle of each of them to evaluate the best map orientation. After a lot of tinkering I wasn't able to get the function to properly detect precise location of my lines, even after giving rho and theta a precision of 0.01 and np.pi/18000 respectively.

My second attempt was to count the pixels individually and analyze them statistically. This was very computationally intensive and lead me down a rabbit hole trying to organise shared memory between multiple processors in Python. The original code is in the first version of my post (I've removed it to keep things clean).

Using HoughLinesP

As suggested I have tried using HoughLinesP.

import cv2                                                  # used for image processing functions
import numpy as np                                          # used for matrix calculations with opencv
class align_map():

  def __init__(self, map_name):
    image = cv2.imread(map_name)
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    th, bw_image = cv2.threshold(image, 150, 255, cv2.THRESH_BINARY)
    # cv2.imshow("bw_image", bw_image)
    edges = cv2.Canny(bw_image, 50, 150, apertureSize=7)

    threshold = 60
    min_line_length = 10
    max_line_gap = 30
    lines = cv2.HoughLinesP(edges, 1, np.pi/180, threshold=threshold, maxLineGap=max_line_gap, minLineLength=min_line_length)

    count = 50
    for x in range(0, len(lines)):
        for x1,y1,x2,y2 in lines[x]:
            count = count + 20
            if (count > 255):
                count = 40

    cv2.imshow("HoughLinesP_Result", image)

map_name = "example.png"


I've managed to detect the lines reasonably well. The different colours are there just to identify individual lines

Now I need to sort these into respective bins according to their angle, but I have a slight problem because I am getting duplicates--you can see this by the red and green neighbouring lines. I believe this is because I'm using Canny() for my edge detection. It's a problem because it will skew my weightings for each line.

Canny Edge Detection

edit retag flag offensive close merge delete


Well, some simple pre-processing should help quite a bit. Threshold so you only keep the pure white, then only keep a one pixel boundary. That should give you edges without the double lines.

Tetragramm gravatar imageTetragramm ( 2017-03-20 22:54:44 -0500 )edit

1 answer

Sort by ยป oldest newest most voted

answered 2017-03-18 15:11:45 -0500

Tetragramm gravatar image

I think you had the right idea when you were looking at HoughLines. However, you would be better served with HoughLinesP. This is precisely the sort of thing that the Hough transform is for.

The reason to use the HoughLinesP is that it gives you a measure of length as well as angle. You can just add up the length of the lines in each rotation bin. You'll have to do a bit of math to figure out which bin it's in, but you shouldn't have any trouble with that.

To get a high resolution, go back with a second iteration (or more!) over the bin with the highest number of votes at a much narrower range and higher precision.

Here's the python tutorial for HoughLinesP.

edit flag offensive delete link more


I've went through the tutorial of HoughLinesP and I was not getting very good results... The results I were getting indicate that my lines were not being detected where I believe that they should have been detected (i.e. from the middle of the line instead of from end to end). And not all lines were detected. You make a very good point though about using a broad detection phase first. I will try again and update and I will also take some time to earn some more reputation so I can add pictures.

cpagravel gravatar imagecpagravel ( 2017-03-20 11:05:54 -0500 )edit

The key parameters are the last three. Threshold, length, and gap. Remember to start coarse and work your way in, or it could cut lines apart because they have slightly different orientations.

Also, I gave you some extra karma. I think you can post links and pictures now.

Tetragramm gravatar imageTetragramm ( 2017-03-20 17:53:08 -0500 )edit

Thank you for the support. I've edited my question to reflect the new approach (I got rid of my old code to avoid clutter). I am getting results with HoughLinesP as you've suggested. The only part of your answer that I don't understand is how to set a range when I repeat the algorithm for a higher resolution. Are you suggesting just making a bounding box ROI over the lines I'm interested in an increasing the resolution? I don't see a HoughLinesP function that allows specifying a range.

cpagravel gravatar imagecpagravel ( 2017-03-20 22:12:17 -0500 )edit

I've been successful! Some pre-processing on the image helped with the Canny() double line problem. I did use bins and some statistical analysis, however I didn't find that I could specify a range when processing. Is it possible to limit the computations required by specifying a range for HoughLinesP?

cpagravel gravatar imagecpagravel ( 2017-03-22 19:25:04 -0500 )edit

Ahh... Hmm. You're right, for some reason the HoughLinesP doesn't have the limits that HoughLInes does. If you're willing to modify the code, it doesn't look very hard to add the arguments. Pretty straightforward, though you wouldn't be able to use the IPP library.

Tetragramm gravatar imageTetragramm ( 2017-03-22 21:18:24 -0500 )edit

Thanks for the answer. I will probably do just that and make custom function. Cheers!

cpagravel gravatar imagecpagravel ( 2017-03-27 11:17:07 -0500 )edit

Question Tools

1 follower


Asked: 2017-03-17 23:57:12 -0500

Seen: 1,305 times

Last updated: Mar 20 '17