Introduction

These days, there are many range finder devices which are used almost everywhere from robotics to country's defence system. All these devices work well, but there are portability and cost concerns for general purpose robotics applications. From my previous articles, I've been creating cool programs related to webcam and now I've come up with a laser-web cam range finder. It could tell how far an object is by just using a very cheap laser pen and an ordinary web cam.

How It Works

First, we need to arrange the laser pen exactly below the web cam so that it's parallel to the optical axis of the camera's lens. Practically, it's not possible even a minor error would give a huge error at greater distances, but this technique works good at short distances (~2 meters). Let's see why we arranged it in this way, check out the ray diagram below:

When the laser beam is projected at some surface, it makes a laser dot on it and then image of that laser dot is formed at focal plane of web cam. Assuming that angle of view of camera is parallel, then by applying laws of similar triangles, we get:

Since focus of the camera doesn't change much at small distances, laser is fixed and it's height won't change so everything is constant here except h'(image height). We get our relation that D is inversely proportional to h'.

We know that a pixel is a unit of measurement so we want to re-define h' then we could say that h' is directly proportional to number pixels of laser dot from center of image or mathematically:

h' = k * (pixels of laser dot from center)

where k is some constant depends on type of web cam and computer used. Now our final equation to find distance has reduced to a simple equation below:

D = K / (pixels of laser dot from center)

To find constant K we could choose experimental approach. We use known values to calculate constant of proportionality. It's just needed once and I've included this option in my program. All you need is to hold a piece of paper at a known distance, let's say 10cm from webcam and simply press a button and the computer will calculate the constant of proportionality.

Image Processing

Before reading further, please take a look at my previous article for "how to include webcam within your C# application".

Now we know that distance is inversely proportional to pixels of laser dot from the center of image. But first of all, we need to extract the laser dot from image. Well it's fairly easy using a computer vision library called AForge. In my case, laser dot is a highly red blob, so it could be extracted using color filter:

I've included a color tune form where you could play around with filters and visually see how changing values of certain filters could change the original image. You may find this option in Filters>>Edit.

Once we have a white blob on laser dot, we use blob counter class to detect its location and geometric center. See the code below:

Once we have the location of laser dot, then we could easily calculate the number of pixels from center of image by simple code:

Math.Abs((float)(previous_image.Height/2) - y_cord)

where y_cord is y coordinate of laser dot.

Now we are left with one more thing that is constant of calibration, we find this value experimentally. We choose a surface which is at a known distance from the camera and then we flash laser. Computer detects that laser light, finds the pixels from center and multiplies it with known distance and we get a constant. I've included this feature in the program, you may find it in Tools>>calibrate.

That's it! We are done building our laser range finder.

Using the Program

You may first need to adjust the color filter to detect the laser light. When you are adjusting the settings of filter, remember that the white region is considered as a blob and black is rejected. Also you need to calibrate, it's pretty simple just go to Tools>>Calibrate and after that, the program will instruct you accordingly.

You could also change the source code to detect the edges of moving object. Basically, edges mean sudden change of range and we could also build some kind of robots that would follow some object by detecting its edges. It may also be used in autonomous robotics. For now, have fun with it. If you like it or found any error or need to give any suggestion, then share it with me though comments.

Update

Just updated the program, I found that sometimes it's not able to detect laser dot or at least not with full precision. So I added a manual mode to define laser dot on its own. You can download it from the link at the top of this article.

References

This article is greatly based on work and article written by Todd Danko. Make sure you read his article.

Share

About the Author

Comments and Discussions

Great Job! I am also working on the same thing but still unable to figure out the most accurate formula to translate the pixels into actual distance. I am under the impression that for some reason the image distance in pixels is not proportional (not linear response) to the actual physical distance. I tried figuring out your diagram above but still i didn't get it. I'm terrible with math. Any help would be appreciated.

I am working on the same setup but with multiple laser dots projected to an uneven surface and a single camera watching the red dots. A motor will then move the whole set of laser pointers together with the camera (as sensors) along the plane and reads the location of every dot as it moves along the surface for every centimeter which will result to a surface contour being scanned and then recreated digitally on the screen. There are lots of real world applications once I get this whole thing working. :P

If you angle the camera down slightly, you'll be able to use more of the vertical pixel range in the camera for a bit better resolution. Since you're range limited anyhow, pick the angle so the top of the viewing frustrum coincides with the maximum range at the level of the laser point.

Also, for robotics you can use a similar setup for not only detecting obstacles range but determining their width. Replace the laser pointer with a laser line generator and you have multiple points where the beam intersects obstacles. By looking at lit pixels in adjacent columns, you get an idea of the width of the obstacle, at least in the plane of the laser beam and even a gross idea of the cross section if you want to go that far. It gets a little trickier when you have one obstacle occluding another if you're doing path planning.

Once you agree to clans, tribes, governments...you've opted for socialism. The rest is just details.