cv :: goodFeaturesToTrack不会返回任何功能

时间:2012-06-05 18:34:24

标签: c++ opencv computer-vision opticalflow

我正在尝试使用cv::calcOpticalFlowPyrLK但有时在该函数中的内部断言失败。断言是npoints = prevPtsMat.checkVector(2, CV_32F, true)) >= 0。我正在使用OpenCV 2.3.1。此功能的源代码可用here

很难绕过他们的代码,特别是因为我对计算机图形学的经验有限以及缺乏评论。为什么这个断言被触发,它对我的​​问题说了什么?

编辑:我按如下方式调用该函数:

cv::calcOpticalFlowPyrLK(curBwFrame, prvFrame, features, newFeatures, trackingStatus, errors);

我发现features向量是通过调用cv::goodFeaturesToTrack(curBwFrame, features, 5, 0.2, 0.5, skinMask);获得的非空掩码获得的,该掩码看起来足够大且有效图像,不包含任何特征。怎么会发生这种情况?

curBwFrame

curBwFrame

skinMask

skinMask

我可以使用以下代码段重现问题:

#include <vector>
#include <cassert>
#include <opencv2\opencv.hpp>
using std::vector;
using namespace cv;

int main() {
    vector<Point2f> features;
    cv::Mat curBwFrame = imread("curBwFrame.png");
    cv::cvtColor(curBwFrame, curBwFrame, CV_RGB2GRAY);
    imwrite("test.png", curBwFrame);

    cv::Mat skinMask = imread("skinMask.png");
    cv::cvtColor(skinMask, skinMask, CV_RGB2GRAY);
    imwrite("test.png", skinMask);

    cv::goodFeaturesToTrack(curBwFrame, features, 5, 0.2, 0.5, skinMask);
    assert(features.size() > 0);

    return 0;
}

4 个答案:

答案 0 :(得分:4)

主要问题是你的参数。在OpenCV 2.3.2 documentation(2.3.1之间没有兼容性变化)这是方法参数的描述:

void goodFeaturesToTrack(InputArray image, OutputArray corners, int maxCorners, double qualityLevel, double minDistance, InputArray mask=noArray(), int blockSize=3, bool useHarrisDetector=false, double k=0.04 )

参数:

  • image - 输入8位或浮点32位单通道图像。
  • corner - 检测到的角落的输出矢量。
  • maxCorners - 要返回的最大角数。如果有更多 角落比找到的,最强的是返回。
  • qualityLevel - 表征最低接受质量的参数 图像角落。参数值乘以最佳值 拐角质量测量,这是最小的特征值(见 cornerMinEigenVal())或Harris函数响应(参见 cornerHarris())。质量角度小于的角落 产品被拒绝。例如,如果最佳角落具有质量 measure = 1500,而qualityLevel = 0.01,然后是所有角落 不到15的质量标准被拒绝。
  • minDistance - 最小可能的欧几里德距离 回来了。
  • mask - 可选的感兴趣区域。如果图像不是空的(它 它需要具有类型CV_8UC1和与图像相同的大小) 指定检测角落的区域。
  • blockSize - 用于计算导数的平均块的大小 每个像素邻域上的共变矩阵。看到 cornerEigenValsAndVecs()。
  • useHarrisDetector - 指示是否使用Harris的参数 探测器(见cornerHarris())或cornerMinEigenVal()。
  • k - Harris探测器的自由参数。

我建议您使用qualityLevel和minDistance来玩一点,以满足您的需求。

答案 1 :(得分:1)

您是否尝试过goodFeaturesToTrack 没有遮罩来查看它是否检测到遮罩区域内的功能?有可能因为图像很暗,而且区域有点无纹理,所以goodFeaturesToTrack无法在那里找到特征。

您也可以尝试ORB or FAST而不是goodFeaturesToTrack。我已成功使用ORB和calcOpticalFlowPyrLK(但没有尝试使用掩码)。

或者您可以尝试使图像变亮或甚至增强对比度。不确定这是否会带来改进,因为我认为你的场景中最大的问题是场景中的物体没有足够的纹理或角落,这些是这些探测器更合适的特征。 我建议您尝试ORB并查看是否获得更多积分。

答案 2 :(得分:0)

图像是否以彩色开始?在转换为灰色之前,使用cv :: transform增强颜色对比度。拍摄全范围的灰色,从0到255.不要担心屏幕外的图像饱和。

答案 3 :(得分:0)

如果您的代码类似于:

 Imgproc.goodFeaturesToTrack(mCurrentFrame, initial, NUMBER_OF_FEATURES, 0.1, 10); 
 //The OpenCV opticalFlow will crash if the feature vector does not include any elements
 if (initial.elemSize() == 0) {
     return;
 }
 initial.convertTo(mPrevPts, CvType.CV_32FC2);

 Video.calcOpticalFlowPyrLK(mPreviousFrame, mCurrentFrame, mPrevPts, mNextPts, status,err);

确保不要忘记检查特征向量大小的语句(initial.elemSize()== 0)。

如果此向量为空,则不会发生由initial.convertTo()行完成的从点矩阵到浮点的转换,并且在调用calOpticalFlowPyrLK时将显示断言