【发布时间】:2016-09-01 19:39:46
【问题描述】:
detectMultiScale 返回输入 Mat 边界之外的矩形时遇到问题。
所以我正在做的是一种优化技术,其中视频源的第一帧被传递给完整的detectMultiScale。
如果检测到对象,我会创建一个临时垫,我会从当前完整帧克隆之前检测到对象的矩形。
然后我将这个临时垫传递给detectMultiScale,因此只有前一帧检测到对象的矩形周围的区域。
我遇到的问题是,在传递 temp Mat 时,detectMultiScale 的结果会给出输入 temp Mat 边界之外的矩形。
主要是我想知道这里到底发生了什么。我对可能发生的事情有两个想法,但我无法确定。
将矩形从完整帧克隆到临时 Mat 时的克隆操作位于 Mat 对象内部的某个位置,将克隆区域设置为完整帧的行和列。例如,我有一个 100x100 的全帧,我试图在 80x80 的位置从它克隆一个 10x10 的矩形。生成的 Mat 大小将是 10x10,但可能在 Mat 内部某处说 Mat 从 80x80 开始?
CascadeClassifier 是否将状态保持在我之前传递给它的全帧的某个位置?
我不确定这里发生了什么,但希望有人能解释一下。
这是我正在尝试做的一个小代码示例,cmets 解释了我看到的结果:
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
}
}
这与我在代码中的内容非常接近,除了我在上面提到的 cmets 中的实际示例值之外,我使用的值很简单,而不是像 1920x1080 和实际结果这样的全帧值,例如 367x711 .
那么为什么我从 detectMultiScale 得到的结果超出了输入 Mat 的范围?
编辑:
我最初为嵌入式 linux 发行版编写了这个程序,没有出现这个问题(我总是得到预期的结果)。这个问题发生在 Windows 版本和 opencv 的构建上,所以我目前正在查看 opencv 代码,看看是否有任何与此相关的突出内容。
【问题讨论】: