标记点的识别与定位

从红外相机的图像中,识别和提取出2D点是动捕系统的第一步。在动捕的红外影像中,Marker点以斑点的形式出现。 这里介绍两种斑点检测的方法,两种方法在OpenCV中都提供了接口。

有两种方式从图像中提取斑点:

  • 高斯拉普拉斯算子:斑点中与LOG算子大小相近的会在输出图像中有强响应
  • 图像分割算法:OpenCV提供SimpleBlobDetector,其中提供了基于边缘轮廓的分割

不应当使用 OpenCV 中提供的 GoodFeaturesToTrack 接口。因为该接口是 角点检测 算法接口。

角点是菱角分明的边缘(Edge), 斑点是与周围存在色差的区域(Area):

上图左边是角点,右边是斑点。角点检测会在Marker的边缘响应,不能对Marker整体进行检测。我们需要检测的是整个斑点,圆形斑点越大,越有利于子像素级定位。

标记点

光学动捕中常使用的Marker点是这样的:

贴在人体上是这样的:

用红外相机拍下来的2D图像是这样的:

高斯拉普拉斯算子

高斯拉普拉斯算子(Laplacian of Gaussian,LOG)是一种常见的圆形对称算子,用于检测图像中的圆形斑点。

对图像用高斯拉普拉斯算子滤波后,原始图像中,一定大小的圆形斑点会有最大响应。当半径是标准差的根号2倍时,响应值最大:

拉普拉斯的计算稍微有一点复杂,可以用高斯差分算子(Difference of Gaussians,DOG)代替:

基于边缘轮廓的分割

SimpleBlobDetector的算法流程:

  1. 取若干阈值对输入图像进行二值化,得到若干二值图像;
  2. 对每一张二值图像查找边缘,计算每一个轮廓的中心;
  3. 上一步中所有二值图得到的轮廓中心进行融合,如果距离小于阈值,就被视为一个组合;
  4. 计算上一步中所有组合的中心和相应半径,并将每一个组合作为一个输出的blob。

基于CUDA的改进

OpenCV的GpuMat模块(createLinearFilter)可以调用GPU执行线性滤波器,但效率不高,且没有查找局部极值的函数。

局部极值检测