KCF跟踪算法中内存异常问题

跟踪和检测

检测是在全局内搜寻感兴趣对象的位置及类别等;
跟踪是基于先验位置的扩大范围周边搜寻对应目标的最佳匹配。
可以说,跟踪是局部检测。
一般迫于运算量,检测实时性不高,而跟踪能够保证良好的时效性。

KCF算法

这是国外一个人奇思妙想得到的算法,他通过目标先验位置,设置不同权重的样本:
即接近目标区域赋予较大权重,而远离目标位置的区域赋予较小权重,其实就是机器学习种话的正负样本。
关于样本数量扩增,他通过循环矩阵的方式;通过像素移位,将一个场景演变为M*N个样本。
在每一次的识别后,建立正负样本训练模型,从而在下一次能够寻找到最接近的匹配。
具体原理还在学习,在此不说瞎话。

调用KCF内存异常问题

这次调用跟踪算法出现如下报错:
这里写图片描述
显然是内存异常问题,可究竟是为什么?


还好VS直接定位到问题区域,报错定位在这个函数里:
这里写图片描述
这个函数位于作者自写的_OPENCV_RECTTOOLS_HPP_中。
是一个opencv的灰度转换,终于明白问题所在。
原来是输入图像为单通道灰度,而在RGB转灰度时,需要输入图像为三通道。

解决方法之一

因为笔者项目这块,QT端给的图像是单通道,工程项目中的原图,不可以随意改变。因此如果调用KCF跟踪算法,需要自己增加三通道操作,以满足调用函数入参需求。
单通道转为三通道代码如下:

//src为原单通道图像
cv::Mat FrameforTrace = cv::Mat::ones(src.size(), CV_8UC3);
if (src.channels() == 1)
{ 
    vector<cv::Mat> MergeMat;
    for (int i = 0; i < 3; i++) 
    {
      MergeMat.push_back(src); 
    }
cv::merge(MergeMat, FrameforTrace);
}
else
{ 
    src.copyTo(FrameforTrace);
}

经过上述操作,合并后的三通道图像就可以直接调用KCF了。

解决方法之二

我们观察到出错定位在源码灰度转换处,可以在此地作以判断:

  • 倘或原图为单通道,就不必做灰度转换操作,直接进入下一环节;

  • 而原图为三通道时,才会将RGB格式转为灰度单通道格式。

inline cv::Mat getGrayImage(cv::Mat img)
{
    if (img.channels()==3)
    {
        cv::cvtColor(img, img, CV_BGR2GRAY);
    }
    img.convertTo(img, CV_32F, 1 / 255.f);
    return img;
}

OK,KCF算法需要认真学习每一步骤,彻底了解原理才能灵活运用。
之前有被问过,关于是否调用FFT的问题,笔者一时疏忽。

猜你喜欢

转载自blog.csdn.net/weixin_39437164/article/details/82379770
今日推荐