Line Points

3 posts / 0 new
Last post
SZapatero
Line Points

Hi, I've just seen this project, and I realised that it is pretty similar to something I'm building. While I was looking at the pictures posted on the racing code, I saw that this robots are capable of distinguish the edges of the road and extracting the points that belong to them.

What I'm building is kind of an autonomous car, and I am able to extract the lines of the road from the rest of the image, but now I need a way to transform that lines (or curves) of the image into a set of points, in order to use them.

Could you please tell me how to do that? Or tell me what kind of cv functions should I use?

Thank you very much, I'm waiting for your response ^^

Images: 
piborg
piborg's picture
Getting points from a line

I presume you are starting from a masked image, say something like this:

There are a few different ways of doing this, this is one of the methods we have used.

Before doing either you will want a grayscale image of the line.
We can get this using:

# Libraries we will need
import cv2
import numpy

# 'image' gets loaded with the line(s) of interest as an image

# Convert from colours (BGR) to grayscale
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

This method involves getting OpenCV to find contours in our image.
These are places where the level changes.

We can do this with:

contours, hierarchy = cv2.findContours(gray, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_TC89_KCOS)

To see what was found we can plot the contours like this:

contourImage = image.copy()
plotColour = (0,0,255) # Red
cv2.drawContours(contourImage, contours, -1, plotColour, 1)
cv2.imwrite('contours1.jpg', contourImage)

In our case we get this:

We can do a bit better by removing low-level noise from the image first:

gray[gray < 10] = 0  # Change any values below 10 to be 0
contours, hierarchy = cv2.findContours(gray, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_TC89_KCOS)

This gives us:

which is a lot cleaner.

The contours list is actually a set of points, but it is rather complicated.
First we want the longest contour only:

bestMatch = contour[0]
for contour in contours:
    if len(contour) > len(bestMatch):
		bestMatch = contour

We can make a simple plotting function like this:

def plotPoints(image, points, (b, g, r)):
	for point in points:
		x = point[0][0]
		y = point[0][1]
		image.itemset((y, x, 0), b)
		image.itemset((y, x, 1), g)
		image.itemset((y, x, 2), r)

And what we get is:

pointsImage = numpy.zeros_like(image) # Gives a black image of the right size
plotPoints(pointsImage, bestMatch, plotColour)
cv2.imwrite('points.jpg', pointsImage)

The good things about this approach:

  • The calls are very simple
  • It will pick up lines at any angle
  • Curves and straight lines are equally accurate
  • Higher resolution images will give more points
  • The points can be simplified to polygons using the cv2.approxPolyDP function

The bad things about this approach:

  • It can be slow with large images
  • With two lines in the image it can get confused
    This can be fixed by changing the 'bestMatch' logic
  • Often it will generate many more points than are needed
    This can make subsequent processing more accurate but much slower
  • Sometimes it will draw points on the image boundaries which will need to be excluded

Our blog will have some more posts about how we can get parts of the image processing to work over time.
Alternatively posts tagged with image-processing will contain details either about processing in general or our standard example code.
From any of the articles you can subscribe to email notifications for new content.

SZapatero
Road detection

Thank you very much for your response! Now I see why you work with a road made of changes of colours.

At this moment, I'm working with 2 stripes, through which the car has to drive. But now I realise this is not the best way to make a road easier to be detected.

Add new comment

Filtered HTML

  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <blockquote> <code> <ul> <ol> <li> <dl> <dt> <dd> <pre>
  • Syntax highlight code surrounded by the <pre class="brush: lang">...</pre> tags, where lang is one of the following language brushes: bash, cpp, perl, python.
  • Lines and paragraphs break automatically.

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
Comment Images
Files must be less than 10 MB.
Allowed file types: png gif jpg jpeg.
Comment Attachments
Files must be less than 10 MB.
Allowed file types: txt pdf nfo doc docx rtf jpg png gif bmp zip tar gz csv xls.
CAPTCHA
This question is for testing whether or not you are a human visitor and to prevent automated spam submissions.