Laser light detection with OpenCV and C++
I want to track a laser light dot(which is on a wall) with a webcam and i am using openCV to do this task. can anybody suggest me a way开发者_JAVA技巧 to do it with C++.
Thank you !
You have three options depending on the stability of your background, and the things you want to do with the image.
You can make your image so dark that the only thing you can see is the laser-point. You can do this by closing the diaphragm and/or reducing the shutter time. Even with cheap webcams this can usually be done in the driver. Once you've done this the job of finding the laser point is very easy. You make the image as dark as possible because usually the point where the laser shines is way too bright for the camera to pick up. This means (as you have experienced) that you cant discern between the light laser dot and other light objects in the image. By making it darker you now can do this.
If you have other uses for your image (showing it to people) and your background is stable you can also use the average of the last few video images as a "background" and then find the spot where there is a large difference between that background and the newest image. This is usually where the laser is pointed (again, if your background is stable enough) .
Finally, if your background is not stable and you don't want to make your image very dark your final option is to look for all pixels that are both very bright, and brighter in the red channel than they are in green and blue (if you are using a red laser). This system will still be distracted by white spots, but not as much as just finding the bright pixels. If the center of your laser-pointer spot is indeed showing up as bright white regardless of laser color then this technique will allow you to find "rings" around this bright spot (the outer part of the dot where the laser is not as bright as it is in the center so that it shows up with the actual color of the laser in the image). You can then use simple morphological operations, (probably closing is enough) to fill these circles.
Let say you use a laser of one of these colors: red, green, blue. If the laser dot appears very bright (at least in one channel, e.g. red) then simply thresholding the image/channel at, say greyvalue of 200, will leave you with a few candidates for the laser light. If the other channels are dark(er) in this area, then you know it is a bright light of the right color. A little filtering by size, and you have a good chance of finding the spot.
If you stick a IR filter on your webcam, your projection will not be picked up, making the detection of the laser point much easier (using simple background subtraction e.t.c) That's assuming the laser pointer emits IR light...
As suggested in other answers, searching for the color might be a good idea. You should consider to look for a specific color range. Best way to do this is to convert the picture to HSL or HSV color space.
cv::cvtColor(src, hsv, COLOR_BGR2HSV);
More information on Wikipedia.
Then you have three channels: hue (=color), saturation and lightness( or value).
With cv::inRange(hsv, cv::Scalar(159, 135, 165), cv::Scalar(179, 255, 200), inRange);
you can now generate a Black and white image, which shows what pixels are in the color range.
The scalars are the low and high values for each channel.
In this example you will get pixels with a color between 159 and 179 (hue), saturation between 135 and 255 and value between 165 and 200.
Maybe this can improve your tracking.
How about this code
https://www.youtube.com/watch?v=MKUWnz_obqQ
https://github.com/niitsuma/detect_laser_pointer
In this code, observed HSV color is compared to registered color using Hotelling's t square test
try Template Maching. first you "point the pointer" to an specific place so the temple can be done. Then you just look for it.
Or, as jilles de wit said, you can take the difference of the last 2 frames, probably the difference will show you the pointer.
Convert the last 2 frames do gray scale, then apply the SUB function.
精彩评论