Laser Tracking Camera

Description

In my last article, we saw how a stepper motor could be controlled with a computer by connecting it to its parallel port. This article will extend it to build laser following camera panner, which tracks and turns towards any laser dot in the camera's field of view. I'm assuming that you have already built a computer controlled stepper motor. If not, go through my previous article for information on how to build one. After you successfully build your laser following camera, you could use your own ideas and creativity to build even cooler things. For example, you could extend this project and build a cool laser following robot, or maybe even an autonomous laser guided turret which shoots down targets you point at!

Mounting your webcam on the motorI have simply mounted my webcam on a plastic cap. I used a heated nail for poking a hole through the cap's center:

Then, I fixed it on the motor by pushing the motor shaft through the hole:

I taped my webcam on the cap..and that was it.

My setup looks very sloppy, and I'm sure yours will look much better than mine. Anyway, let's move on to the fun part!Finding the laser dot...

Our code will locate the laser dot by finding the brightest pixel in the webcam's field of view. If something in its view is brighter than the laser, the camera will simply turn towards that point instead of the laser dot. The program captures images from a webcam, using Andrew Kirillov's motion detection code for image acquisition. Then, it scans the pixels in the bitmaps captured. Based on their respective RGB (Red Green Blue) values, it determines how bright they are. We could use the Bitmap.GetPixel() function for accessing pixels and calculating the brightness of any pixel in a bitmap:

using System.Drawing;

Color c = someBitmap.GetPixel(x,y);

float b = c.GetBrightness();

Wow, that's easy! This code was simple to write, and easy to understand. However, unfortunately, it is VERY slow. If you use this code, it might take several seconds to process a single image becase the GetPixel()/SetPixel() methods are too slow for iterating through bitmaps of any real size. So, in this project, we'll make use of the BitmapData class in GDI+ to access the information we want. The BitmapData only allows us to access the data it stores through a pointer. This means that we'll have to use the unsafe keyword to scope the block of code which accesses the data. Based on an article by Eric Gunnerson, here's a class which will perform very quick unsafe image processing:

Be sure to check Eric's article on unsafe image processing.This class can be used for retrieving the red, green and blue values of any pixel as shown below:

UnsafeBitmap uBitmap = new UnsafeBitmap (original_bitmap);

uBitmap.LockBitmap();

PixelData pixel = uBitmap.GetPixel (x,y);

uBitmap.UnlockBitmap();

You can also alter the red, green and blue values of any pixel in your bitmap:

UnsafeBitmap.PixelData pData = new UnsafeBitmap.PixelData();

pData.red = value;

pData.green = value;

pData.blue = value;

uBitmap.SetPixel (x, y, pData);

To find a laser dot in a bitmap, we have to go through the pixels in the bitmap and calculate each pixel's brightness to find the brightest one. Based on a pixel's RGB values, you can calculate brightness using this formula:

Brightness = (299 * red + 587 * green + 114 * blue) / 1000

This would give a value between 0 to 255.Here's a sample code to check the brightness of each pixel in a 320 x 240 bitmap:

for (int y = 0; y < 240; y++)

{

for (int x = 0; x < 320; x++)

{

byte red, green, blue;

red = uBitmap.GetPixel(x, y).red;

green = uBitmap.GetPixel(x, y).green;

blue = uBitmap.GetPixel(x, y).blue;

float brightness = (299 * red + 587 * green + 114 * blue) / 1000;

if (brightness > certainValue)

// Do something

}

}

After our program has the x and y coordinates of the laser dot, it can calculate the number of steps required to turn the webcam towards that point.

Using the SoftwareSince the program searches for the brightest pixel in the camera's field of view, the lighting conditions of your room can affect its performance. So, adjust the brightness threshold and lighting conditions so that nothing (except the laser) exceeds the brightness threshold.

If your stepper motor doesn't align your webcam with the laser dot properly, try adjusting the pixels-per-step track bar. It tells the program how much your stepper motor moves with each step. My stepper does 40 pixels/step (20 pixels while half stepping). Even though this isn't necessary, you can actually measure how many pixels your stepper moves in one step. Just comment out the calls to the MoveStepper() event in MotionDetector1.cs and run the program. Keep a laser dot fixed somewhere in your webcam's field of view and check its x coordinate in the Output window. After that, move the stepper one step in any direction with your mouse wheel, and see how much its x coordinate changes. Read my previous article for information on how to move a stepper with a mouse wheel, or simply download the code for doing it from here. Well, I still think it's not necessary that you actually measure how much your stepper moves using this tedious technique. Just play with the pixels-per-step track bar until you get things working perfectly.

Now what?

Now that you can track laser, and have a camera actually follow it, here are some interesting ideas to try:

Wire two stepper motors to your computer. Then, you could make a dual axis, pan/tilt assembly and have your camera follow laser dots in any direction.

ConclusionWe've reached end of this article. I hope you enjoyed reading it. Use your imagination and ideas to extend this project. If you come up with something interesting, I'd love to hear about it. Happy coding.

About the Author

Ashish Derhgawen is an IT student, currently living in New Delhi, India. He has been coding since fourth grade. Some of his other interests are harmonica playing, wildlife and cricket. When he's not at school, he spends his time working on unusual projects related to robotics, webcams, and electronics besides others. You can reach Ashish through his blog at http://ashishrd.blogspot.com.

The threshold helps calibrate the camera to the background light conditions.

Idealistically there should be a way to calibrate the detector to the laser color, and filter-out the non-laser hot spots. The real challenge is that red (like the red laser) is a component of white light, so you can't just look for the hottest red spot because the hottest white spot is likely to also be the hottest red spot. In the event that there is bright white light and or a warm background, this becomes challenging.

A fuzzy algorithm "Where hotspot is mostly red and the pixels surrounding the hot spot are not" would be ideal.

Your project is very good. I found the code for controlling a stepper motor with mouse wheel but could not find out how did you control the stepper motor to move along the laser pointer.Can you please help me with and send the solution for this project if possible through email.Please find my email ID : leelavaree@gmail.com

Hello Ashish, I have been reading all your articles with great pleasure. I am looking for a method to control a spotlight with servos to follow performers on theater stage. Your method seems to be the most ideal I have come across yet.

However, I am considering using Infra Red Laser as the point light source.....and IR camera....so that the laser is not visible to the audience