Laser pointer detect and track
I try to create an interactive projector using the method of laser pointer detecting by color, form and saturation. The projection itself is not static, it is dynamic and has a lot of white elements. It is also very important to exclude the possibility of a wrong response to the metallic light glares. Here is the code i tried to use to detect the laser with Visual C++:
#include <opencv2\core\core.hpp>
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\imgproc\imgproc.hpp>
#include <iostream>
#include <Windows.h>
int main() {
cv::VideoCapture capWebcam(0);
// get screen resolution, which will be used in future
int widthx = GetSystemMetrics(SM_CXSCREEN);
int heighty = GetSystemMetrics(SM_CYSCREEN);
std::cout << (widthx) << " X " << (heighty) << "\n\n";
// webcam access
if (capWebcam.isOpened() == false) {
std::cout << "Error: Webcam don't work or can't be accessed\n\n";
return(1);
}
// creating various necessary staff
cv::Mat matOriginal;
cv::Mat matOriginalHSV;
cv::Mat matProcessed;
std::vector<cv::Vec3f> vecCircles;
std::vector<cv::Vec3f>::iterator itrCircles;
char charEscKey = 0;
cv::namedWindow("Original", CV_WINDOW_AUTOSIZE);
cv::namedWindow("Processed", CV_WINDOW_AUTOSIZE);
// creating trackbars
cv::namedWindow("Trackbar", CV_WINDOW_AUTOSIZE);
int hmin = 0, smin = 0, vmin = 0,
hmax = 180, smax = 256, vmax = 256;
cv::createTrackbar("H min:", "Trackbar", &hmin, hmax);
cv::createTrackbar("H max:", "Trackbar", &hmax, hmax);
cv::createTrackbar("S min:", "Trackbar", &smin, smax);
cv::createTrackbar("S max:", "Trackbar", &smax, smax);
cv::createTrackbar("V min:", "Trackbar", &vmin, vmax);
cv::createTrackbar("V max:", "Trackbar", &vmax, vmax);
// main function
while (charEscKey != 27) {
if (capWebcam.read(matOriginal) == NULL) {
std::cout << "Error: frame not readed from Cam\n\n";
break;
}
// converting to HSV
cv::cvtColor(matOriginal, matOriginalHSV, CV_BGR2HSV);
// spliting channels, changing any channel from "matOriginalHSVchannels[0/1/2]" to "matZero" to remove it
cv::Mat matZero;
cv::Mat matOriginalHS;
matZero = cv::Mat::zeros(cv::Size(matOriginalHSV.cols, matOriginalHSV.rows), CV_8UC1);
cv::vector<cv::Mat> matOriginalHSVchannels(3);
cv::split(matOriginalHSV, matOriginalHSVchannels);
cv::vector<cv::Mat> channels;
channels.push_back(matOriginalHSVchannels[0]);
channels.push_back(matOriginalHSVchannels[1]);
channels.push_back(matZero);
cv::merge(channels, matOriginalHS);
// search of laser spot
cv::inRange(matOriginalHS, cv::Scalar(hmin, smin, vmin), cv::Scalar(hmax, smax, vmax), matProcessed);
// blur
cv::GaussianBlur(matProcessed,
matProcessed,
cv::Size(5, 5),
2.2);
// circles search
cv::HoughCircles(matProcessed,
vecCircles,
CV_HOUGH_GRADIENT,
1,
matProcessed.rows / 8,
100,
50,
7,
20);
// draw circles
for (itrCircles = vecCircles.begin(); itrCircles != vecCircles.end(); itrCircles++) {
std::cout << "position x = " << (*itrCircles)[0]
<< ", y = " << (*itrCircles)[1]
<< ", z = " << (*itrCircles)[2] << "\n";
cv::circle(matOriginalHS,
cv::Point((int)(*itrCircles)[0], (int)(*itrCircles)[1]),
1,
cv::Scalar(255, 0, 0),
CV_FILLED);
cv::circle(matOriginalHS,
cv::Point((int)(*itrCircles)[0], (int)(*itrCircles)[1]),
(int)(*itrCircles)[2],
cv::Scalar(255, 255, 0),
2);
// set mouse cursor on laser coordinates
int screenx = (int)((*itrCircles)[0] * 2.2);
int screeny = (int)((*itrCircles)[1] * 1.2);
SetCursorPos(screenx, screeny);
}
// show windows
cv::imshow("Original", matOriginalHS);
cv::imshow("Processed", matProcessed);
charEscKey = cv::waitKey(10);
}
return(0);
}
It is not possible to detect the laser pointer with this code even at the minimal brightness of the projector. All the more it will be necessary to use ...
"The screenshots are attached. "
No they aren't :)
now attached. just forgot to do it
Have you tried to subtract and image without laser from an image with laser? A presentation is normally very static so you try to do some tracking.
The problem is that the content will be dynamic, not only slides but also video and other moving content.
Does it have to be a red laserpointer? Or could you use a different wavelength than the projector, e.g. Infrared?
I need to use the projector with the presenter (laser pointer for presentations, in my case SpeedLink ACUTE Presenter).Doesn't the infrared pointer have a too high voltage to be used safely for presentations? The red pointers are easy to find and thus widespread. The green and blue lasers are not sold officially in my country. Are there any functions that allow to calibrate the webcam before detect the laser dot?
if you got a cheap webcam to spare,
try an infrared-lowpass (i.e a piece of an old diskette) between cam-sensor and lense.
So the problem of detection can be solved only by use some material filter on cam lense, I was thinking about it, but not sure what material to use. I will try to do as you said.
I think the same ... filter for ligh and some camera regulation (ex. light exposure etc etc).
Well.. most of red lasers pointers work in 650nm wavelength. I'm going to buy polarized filter, this one
Image
I will write the results here.