我想用网络摄像头跟踪激光点(在墙上),我正在使用openCV来完成这项任务。任何人都可以建议我用C ++来做到这一点。
谢谢!
答案 0 :(得分:8)
您有三种选择,具体取决于背景的稳定性以及您想要对图像执行的操作。
你可以让你的图像变暗,你唯一能看到的就是激光点。您可以通过关闭光圈和/或减少快门时间来完成此操作。即使使用廉价的网络摄像头,通常也可以在驱动程序中完成完成这项工作后,找到激光点的工作非常简单。您可以使图像尽可能暗,因为通常激光照射的点太亮而不能让相机拾取。这意味着(正如您所经历的那样)您无法辨别光激光点和图像中的其他光对象。通过使它变暗,你现在可以做到这一点。
如果您对图像有其他用途(向人们展示)并且背景稳定,您还可以将最后几张视频图像的平均值用作“背景”,然后找到存在较大差异的地方在那个背景和最新的图像之间。这通常是激光指向的地方(同样,如果背景足够稳定)。
最后,如果你的背景不稳定并且你不想让你的图像非常暗,你的最终选择是寻找所有非常明亮的像素,并且红色通道中的像素比绿色和蓝色(如果您使用的是红色激光)。这个系统仍然会被白点分散注意力,但不会像找到明亮的像素那么多。如果激光指针点的中心确实显示为亮白色而不管激光颜色如何,那么这种技术将允许您在该亮点周围找到“环”(激光不如光亮的点的外部)它位于中心位置,以便显示图像中激光的实际颜色。然后,您可以使用简单的morphological operations,(可能closing就足够了)来填充这些圈子。
答案 1 :(得分:4)
假设您使用以下颜色之一的激光:红色,绿色,蓝色。 如果激光点看起来非常明亮(至少在一个通道中,例如红色),那么简单地对图像/通道进行阈值处理,比如200的灰度值,将为您留下一些激光的候选者。如果此区域中其他通道较暗(呃),那么您就知道它是正确颜色的明亮光线。根据尺寸进行一点过滤,您很有可能找到该位置。
答案 2 :(得分:3)
如果您在网络摄像头上粘贴红外线滤镜,则无法拾取投影,使激光点的检测更加容易(使用简单的背景减法等)假设激光指示器发出红外光...
答案 3 :(得分:1)
正如其他答案中所建议的,搜索颜色可能是一个好主意。 您应该考虑寻找特定的颜色范围。最好的方法是将图片转换为HSL或HSV色彩空间。
cv::cvtColor(src, hsv, COLOR_BGR2HSV);
有关Wikipedia的更多信息。
然后你有三个渠道: 色调(=颜色),饱和度和亮度(或值)。
使用cv::inRange(hsv, cv::Scalar(159, 135, 165), cv::Scalar(179, 255, 200), inRange);
,您现在可以生成黑白图像,该图像显示颜色范围内的像素。
标量是每个频道的低值和高值。
在此示例中,您将获得颜色介于159和179之间(色调),饱和度介于135和255之间,值介于165和200之间的像素。
也许这可以改善您的跟踪效果。
答案 4 :(得分:1)
这段代码怎么样
https://www.youtube.com/watch?v=MKUWnz_obqQ
https://github.com/niitsuma/detect_laser_pointer
在此代码中,使用Hotelling&t方形测试将观察到的HSV颜色与注册颜色进行比较
答案 5 :(得分:0)
尝试模板缓存。 首先,你将“指针”指向一个特定的地方,这样就可以完成太阳穴。然后你就去寻找它。
或者,正如jilles de wit所说,你可以得到最后2帧的差异,可能差异会显示指针。
转换最后2帧做灰度,然后应用SUB功能。