OpenCV CascadeClassifier detectMultiScale导致Rect外部输入Mat边界

时间:2016-05-06 16:32:42

标签: c++ windows opencv

我遇到的问题是detectMultiScale在输入Mat的边界之外返回矩形。

所以我正在做的是一种优化技术,其中视频输入的第一帧被传递到其中的detectMultiScale。

如果检测到一个物体,我会创建一个临时垫,我从当前的整帧中克隆前一帧检测到的对象的矩形。

然后我将此临时Mat传递给detectMultiScale,因此只有前一帧检测到对象的矩形周围区域。

我遇到的问题是,当传递临时Mat时,来自detectMultiScale的结果会产生超出输入温度Mat界限的矩形。

大多数情况下,我只想知道这里发生了什么。我对可能发生的事情有两个想法,但我无法确定。

  1. 将矩形从全帧克隆到临时Mat的克隆操作在Mat对象内部的某处设置克隆区域在整帧的行和列。例如,我有一个100x100的完整帧,我试图在80x80位置克隆一个10x10的矩形。然后得到的垫子的尺寸为10x10,但也许在垫子的某个地方,它说垫子是从80x80开始的?

  2. CascadeClassifier将状态保持在我之前传递给它的完整帧的某个位置?

  3. 我当然不知道这里发生了什么,但希望有人可以解释一下。

    以下是我尝试做的一些代码示例,其中的评论解释了我看到的结果:

    std::vector<cv::Rect> DetectObjects(cv::Mat fullFrame, bool useFullFrame, cv::Rect detectionRect)
    {
        // fullFrame is 100x100
        // detectionRect is 10x10 at position 80x80 eg. cv::Rect(80,80,10,10)
        // useFullFrame is False
    
        std::vector<cv::Rect> results;
        if(useFullFrame)
        {
            object_cascade.detectMultiScale(fullFrame,
                    results,
                    m_ScaleFactor,
                    m_Neighbors,
                    0 | cv::CASCADE_SCALE_IMAGE | cv::CASCADE_DO_ROUGH_SEARCH  | cv::CASCADE_DO_CANNY_PRUNING,
                    m_MinSize,
                    m_MaxSize);
        }
        else
        {
            // useFullFrame is false, so we run this block
    
            cv::Mat tmpMat = fullFrame(detectionRect).clone();
            // tmpMat is size 10,10
    
            object_cascade.detectMultiScale(tmpMat,
                    results,
                    m_ScaleFactor,
                    m_Neighbors,
                    0 | cv::CASCADE_SCALE_IMAGE | cv::CASCADE_DO_ROUGH_SEARCH  | cv::CASCADE_DO_CANNY_PRUNING,
                    m_MinSize,
                    m_MaxSize);
        }
    
        if(results.size() > 0)
        {
            // this is the weird part. When looking at the first element of
            // results, (result[0]), it is at position 80,80, size 10,10
            // so it is cv::Rect(80,80,10,10)
            // even though the second detectMultiScale was ran with a Mat of 10x10
    
            // do stuff
        }
    }
    

    这非常接近我在代码中所拥有的,除了我在评论中提到的实际示例值,我使用的是容易的值,而不是像1920x1080那样的全帧值和实际结果,例如367x711

    那么为什么我从detectMultiScale获得超出输入Mat界限的结果呢?

    修改

    我原本是为嵌入式Linux发行版编写了这个程序,不会出现这个问题(我总是得到预期的结果)。这个问题发生在Windows发布和opencv的构建上,所以我现在正在浏览opencv代码,看看是否有任何与此相关的内容。

1 个答案:

答案 0 :(得分:0)

我认为这是一个简单的逻辑错误。这样:

if(fullFrame)

应该是这样的:

if(useFullFrame)