使用OpenCV和C++进行激光光线检测

7
我想使用OpenCV来追踪墙上的激光点。请问有没有人能向我介绍一种用C++实现此任务的方法?
谢谢!

在网络摄像头前是否可以使用某种筛选器?如果是,那些筛选器是什么? - Keshan
对你来说,光源是激光这一事实真的很重要吗?还是你只是因为它是一个方便制造亮点的方式而使用它?也就是说,你是否有某些理由关心源是单色的和相位匹配的?如果是这样,那么点投影在其表面上的光学特性是什么(平整度等)? - dmckee --- ex-moderator kitten
你能否只扫描图像中红色分量明显增强的小区域,与相邻区域进行比较? - Dialecticus
@Dialecticus:请注意,现在廉价二极管激光器有多种颜色可选。因此,请使用s/red/you laser's color/ - dmckee --- ex-moderator kitten
@dmckee:我有一堵墙,我将我的电脑投影到那堵墙上,我想从那个表面过滤激光点(当我把激光点对准它时)。 - Keshan
6个回答

8
你有三种选择,取决于你的背景稳定性和想要使用图像的目的。你可以使图像变得非常暗,以至于只能看到激光点。你可以通过关闭光圈和/或减少快门时间来实现这一点。即使使用廉价的网络摄像头,通常也可以在驱动程序中完成此操作。一旦你完成了这个步骤,找到激光点的工作就非常容易了。你尽可能让图像变暗,因为通常情况下激光照射的位置对相机来说太亮了,无法捕捉到。这意味着(正如你所经历的那样),你无法区分图像中的光点和其他光物体。通过让它变暗,现在你可以做到这一点。
如果你有其他用途(向人展示)并且你的背景稳定,你还可以使用最近几个视频图像的平均值作为“背景”,然后找到该背景与最新图像之间巨大差异的位置。通常情况下这就是激光指向的位置(再次强调,如果你的背景足够稳定)。
最后,如果你的背景不稳定,而且你不想让图像变得非常暗,那么你的最后选择是寻找所有非常明亮的像素,并且在红色通道比绿色和蓝色通道更亮(如果你使用的是红色激光)。这个系统仍然会被白点干扰,但不会像只查找亮像素那样严重。如果你的激光笔点中心确实显示为明亮的白色,无论激光颜色如何,那么这种技术将允许你找到这个明亮点周围的“环”(点的外部,在这里激光的亮度不如在图像中它的实际颜色中那么明亮)。然后,你可以使用简单的形态学操作(可能闭合就足够了)来填充这些圆圈。

我想我最好尝试前两个选项,看起来是可行的:)。非常感谢。 - Keshan

4

假设你使用了以下其中一种颜色的激光:红色,绿色,蓝色。 如果激光点非常明亮(至少在一个通道,比如红色通道),那么将图像/通道阈值设置为200的灰度值,将留下一些激光光线的候选项。如果其他通道在该区域内较暗,则知道这是正确颜色的亮光。进行一些大小过滤,你就有很好的机会找到这个点。


感谢回复。我有一面墙,并正在投影,因此当我对图像进行阈值处理并寻找红色通道时,投影表面的红色可能会引起一些麻烦。 - Keshan

3

如果你在网络摄像头上贴上红外过滤器,那么你的投影将不会被捕捉到,这样就更容易检测激光点(使用简单的背景减法等)。前提是激光笔发出红外光...


1

如其他答案所建议的那样,搜索颜色可能是一个好主意。 您应该考虑寻找特定的颜色范围。最好的方法是将图片转换为HSL或HSV颜色空间。

cv::cvtColor(src, hsv, COLOR_BGR2HSV);

更多关于维基百科的信息。

然后你有三个通道:色调(=颜色),饱和度和亮度(或值)。

使用 cv::inRange(hsv, cv::Scalar(159, 135, 165), cv::Scalar(179, 255, 200), inRange); 现在可以生成一张黑白图像,显示哪些像素位于颜色范围内。 标量是每个通道的低值和高值。

在这个例子中,你将得到颜色介于159和179之间(色调),饱和度介于135和255之间,亮度介于165和200之间的像素。

也许这可以改善你的跟踪。


1

0

尝试模板匹配。首先,您需要“指向指针”到特定位置,以便可以完成模板。然后,您只需寻找它。

或者,正如jilles de wit所说,您可以取最后2帧的差异,可能会显示出指针。

将最后2帧转换为灰度,然后应用SUB函数。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接