用于opencv对象跟踪的边界框定义

gus*_*avz 6 python opencv video-tracking

如何定义采用opencv的tracker.init()函数的boundingbox对象?是(xcenter,ycenter,boxwidht,boxheight)(xmin,ymin,xmax,ymax)(ymin,xmin,ymax,xmax) 或完全不同的东西?

我正在使用python和OpenCV 3.3,我基本上对要跟踪视频每一帧的每个对象执行以下操作:

tracker = cv2.trackerKCF_create()
ok = tracker.init(previous_frame,bbox)
bbox = tracker.update(current_frame)
Run Code Online (Sandbox Code Playgroud)

gus*_*avz 7

The Answer is: (xmin,ymin,boxwidth,boxheight)


Dan*_*šek 6

另一篇文章将答案陈述为事实,所以让我们看看如何自己找出答案。

OpenCV 的 Python 版本是主要 C++ API 的包装器,因此当有疑问时,查阅主要文档,甚至源代码总是有用的。有一个简短的教程提供了有关 Python 绑定的一些基本信息。

首先,我们来看一下cv::TrackerKCF。该init成员将边界框作为以下实例cv::Rect2d(即,其变体cv::Rect_使用值表示参数double):

bool cv::Tracker::init(InputArray image, const Rect2d& boundingBox)
Run Code Online (Sandbox Code Playgroud)

现在的问题是,a cv::Rect2d(或者一般来说,a的变体cv::Rect_)在Python中是如何表示的?我还没有找到文档的任何部分明确说明这一点(尽管我认为教程中暗示了这一点),但前面提到的绑定教程中有一些有用的信息:

...
但是可能有一些基本的 OpenCV 数据类型,例如 Mat、Vec4i、Size。它们需要手动扩展。例如,Mat 类型应扩展为 Numpy 数组,Size 应扩展为两个整数的元组等
。...
所有此类手动包装函数都放在modules/python/src2/cv2.cpp.

不多,所以让我们看看他们指向我们的代码。第941 - 954行是我们所追求的:

template<>
bool pyopencv_to(PyObject* obj, Rect2d& r, const char* name)
{
    (void)name;
    if(!obj || obj == Py_None)
        return true;
    return PyArg_ParseTuple(obj, "dddd", &r.x, &r.y, &r.width, &r.height) > 0;
}

template<>
PyObject* pyopencv_from(const Rect2d& r)
{
    return Py_BuildValue("(dddd)", r.x, r.y, r.width, r.height);
}
Run Code Online (Sandbox Code Playgroud)

第一个函数中的内容PyArg_ParseTuple是不言自明的。双精度(浮点)值的 4 元组,按 x、y、宽度和高度的顺序排列。