标记点的识别与定位
从红外相机的图像中,识别和提取出2D点是动捕系统的第一步。在动捕的红外影像中,Marker点以斑点的形式出现。 这里介绍两种斑点检测的方法,两种方法在OpenCV中都提供了接口。
有两种方式从图像中提取斑点:
- 高斯拉普拉斯算子:斑点中与LOG算子大小相近的会在输出图像中有强响应
- 图像分割算法:OpenCV提供SimpleBlobDetector,其中提供了基于边缘轮廓的分割
不应当使用 OpenCV 中提供的 GoodFeaturesToTrack 接口。因为该接口是 角点检测 算法接口。
角点是菱角分明的边缘(Edge), 斑点是与周围存在色差的区域(Area):
上图左边是角点,右边是斑点。角点检测会在Marker的边缘响应,不能对Marker整体进行检测。我们需要检测的是整个斑点,圆形斑点越大,越有利于子像素级定位。
标记点
光学动捕中常使用的Marker点是这样的:
贴在人体上是这样的:
用红外相机拍下来的2D图像是这样的:
高斯拉普拉斯算子
高斯拉普拉斯算子(Laplacian of Gaussian,LOG)是一种常见的圆形对称算子,用于检测图像中的圆形斑点。
对图像用高斯拉普拉斯算子滤波后,原始图像中,一定大小的圆形斑点会有最大响应。当半径是标准差的根号2倍时,响应值最大:
拉普拉斯的计算稍微有一点复杂,可以用高斯差分算子(Difference of Gaussians,DOG)代替:
基于边缘轮廓的分割
SimpleBlobDetector的算法流程:
- 取若干阈值对输入图像进行二值化,得到若干二值图像;
- 对每一张二值图像查找边缘,计算每一个轮廓的中心;
- 上一步中所有二值图得到的轮廓中心进行融合,如果距离小于阈值,就被视为一个组合;
- 计算上一步中所有组合的中心和相应半径,并将每一个组合作为一个输出的blob。
基于CUDA的改进
OpenCV的GpuMat模块(createLinearFilter)可以调用GPU执行线性滤波器,但效率不高,且没有查找局部极值的函数。