OpenCV级联分类器检测输入Mat边界外的MultiScale结果Rect

OpenCV CascadeClassifier detectMultiScale resulting Rect outside input Mat bounds

本文关键字:MultiScale 结果 Rect 边界 Mat 级联 分类器 检测 输入 OpenCV      更新时间:2023-10-16

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

所以我正在做的是一种优化技术,通过视频馈送的第一帧来检测整个MultiScale。

如果检测到一个对象,我会创建一个临时Mat,我会从当前完整帧中克隆先前帧检测到的对象的rect。

然后,我将这个temp Mat传递给detectMultiScale,所以只有上一帧检测到对象的矩形周围的区域。

我遇到的问题是,当通过temp Mat时,detectMultiScale的结果给出的矩形超出了输入temp Mat.的边界

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

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

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

我不确定这里发生了什么,但我希望有人能给我一些启示。

下面是我尝试做的一个小代码示例,注释解释了我看到的结果:

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发行版编写这个程序的,在那里没有出现这个问题(我一直得到预期的结果)。这个问题发生在opencv的windows版本和构建中,所以我目前正在查看opencv代码,看看是否有与此相关的突出内容。

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

if(fullFrame)

应该是这样的:

if(useFullFrame)