我正在使用c ++中的一些计算机视觉代码,在您绘制一个边界框后跟踪一个对象,它可以跟踪多个边界框的多个对象。在其中一个头文件中有一个函数处理框架并将对象中心像素坐标定义为变量centerx
和centery
,但我需要能够在主cpp文件中使用这些变量
在函数oldcenterx
和oldcentery
的这一部分中定义了:
编辑:已添加bool LKTracker::processFrame(const Matrix& curImage, ObjectBox& bbox, bool dotracking)
bool LKTracker::processFrame(const Matrix& curImage, ObjectBox& bbox, bool dotracking)
{
std::vector<ObjectBox> boxes;
std::vector<bool> isDefined;
boxes.push_back(bbox);
isDefined.push_back(dotracking);
processFrame(curImage, boxes, isDefined);
bbox = boxes[0];
return isDefined[0];
}
void LKTracker::processFrame(const Matrix& curImage, std::vector<ObjectBox>& bbox, std::vector<bool>& isDefined)
{
int nobs = bbox.size();
if (nobs > 0 && !ivPrevPyramid)
initFirstFrame(curImage);
#if DEBUG
std::cout << "#" << (ivIndex+1) << " LKTracker: ";
#endif
ivDebugPoints.clear();
LKPyramid* curPyramid = new LKPyramid(MAX_PYRAMID_LEVEL+1);
curPyramid->I[0] = curImage;
for (int i = 0; i < MAX_PYRAMID_LEVEL; ++i)
{
curPyramid->I[i].halfSizeImage(curPyramid->I[i+1]);
#if DEBUG > 1
char filename[255];
sprintf(filename, "output/img%05d-%d.ppm", ivIndex, i);
curPyramid->I[i].writeToPGM(filename);
#endif
}
#pragma omp parallel sections
{
#pragma omp section
{
//#pragma omp parallel for
for (int i = 0; i <= MAX_PYRAMID_LEVEL; ++i)
curPyramid->I[i].scharrDerivativeX(curPyramid->Ix[i]);
}
#pragma omp section
{
//#pragma omp parallel for
for (int i = 0; i <= MAX_PYRAMID_LEVEL; ++i)
curPyramid->I[i].scharrDerivativeY(curPyramid->Iy[i]);
}
}
#if DEBUG > 1
Matrix debugFlow(ivWidth, ivHeight, 0);
#endif
// loop over all object boxes
for (int obj = 0; obj < nobs; obj++)
{
#if DEBUG
std::cout << "\tObj" << obj << ": ";
#endif
if (isDefined[obj])
{
float oldwidth = bbox[obj].width,
oldheight = bbox[obj].height,
oldcenterx = bbox[obj].x + oldwidth*0.5,
oldcentery = bbox[obj].y + oldheight*0.5;
然后在本节后面定义centerx
和centery
:
// Compute median flow
std::vector<float> deltax;
std::vector<float> deltay;
int num = 0;
for (int i = 0; i < count; ++i)
{
if (status[i] > 0)
{
deltax.push_back(points1[i].x - points0[i].x);
deltay.push_back(points1[i].y - points0[i].y);
++num;
#if DEBUG > 1
debugFlow.drawLine(points0[i].x, points0[i].y, points1[i].x, points1[i].y, 255);
debugFlow.drawCross(points1[i].x, points1[i].y, 255);
#endif
}
}
if (num < 4)
{
#if DEBUG
std::cout << "n=" << num << " => FAILURE: lost object" << std::endl;
#endif
isDefined[obj] = false;
continue;
}
//else
float dx = median(&deltax),
dy = median(&deltay);
// Remove outliers
/*
for (int i = 0; i < count; ++i)
if (status[i] > 0)
if ((points1[i].x - points0[i].x - dx) * (points1[i].x - points0[i].x - dx)
+ (points1[i].y - points0[i].y - dy) * (points1[i].y - points0[i].y - dy) > 5*5)
{
status[i] = 0;
num--;
}
*/
// Resize bounding box (compute median elongation factor)
float s = 1;
if (num >= 16){
std::vector<float> d2;
float dpx,dpy,ddx,ddy;
for (int i = 0; i < count; ++i)
if (status[i] > 0)
for (int j = i + 1; j < count; ++j)
if (status[j] > 0)
{
ddx = points0[i].x - points0[j].x;
ddy = points0[i].y - points0[j].y;
dpx = points1[i].x - points1[j].x;
dpy = points1[i].y - points1[j].y;
d2.push_back((dpx*dpx + dpy*dpy) / (ddx*ddx + ddy*ddy));
}
if (!d2.empty())
{
s = median(&d2, true);
//upper bound for enlargement
//s = std::min(1.1, s);
}
}
//delete[] points0; delete[] points1; delete[] points2;
//delete[] status; delete[] fb; delete[] ncc;
float centerx = oldcenterx + dx,
centery = oldcentery + dy;
bbox[obj].x = (centerx - s * oldwidth * 0.5);
bbox[obj].y = (centery - s * oldheight * 0.5);
bbox[obj].width = s * oldwidth;
bbox[obj].height = s * oldheight;
到目前为止我做的一件事是在头文件的顶部全局定义centerx
和centery
。这暂时很好用,我可以使用我需要的数据,但这只能在最近绘制的边界框中给出对象的位置数据,所以我只能得到一个对象的像素坐标。
我也尝试过这样定义一个全局向量:
std::vector<ObjectCenter> objcenter;
那么
objcenter[obj].objcenterx = centerx;
但我会不断收到错误,导致向量未初始化,或者代码意外退出运行且没有错误。
编辑:这是ObjectBox
结构:
/// datastructure linking objects to their (possible) location
struct ObjectBox
{
/// x-component of top left coordinate
float x;
/// y-component of top left coordinate
float y;
/// width of the image section
float width;
/// height of the image section
float height;
/// identifies object, which is represented by ObjectBox
int objectId;
};
PS:谢谢你的帮助。我是n00b。 -Tyler
答案 0 :(得分:0)
在函数processFrame()中添加参数objcenter,以便main函数可以获取数据。 void LKTracker :: processFrame(const Matrix&amp; curImage,std :: vector&amp; bbox,std :: vector&amp; isDefined, vector&amp; objcenter )
答案 1 :(得分:0)
我假设您可以访问传递给此函数void LKTracker::processFrame(const Matrix& curImage, std::vector<ObjectBox>& bbox, std::vector<bool>& isDefined)
我认为你最好的两个选择是:
从bbox(ObjectBox)x,width和y,height值计算中心。您可以创建功能以使其更清洁:
// add these functions to your code
float getCenterX(ObjectBox bbox)
{
float centerx = bbox.x + bbox.width * 0.5;
return centerx;
}
float getCenterY(ObjectBox bbox)
{
float centery = bbox.y + bbox.height * 0.5;
return centery;
}
在main中使用它,如果变量在main
中类似地命名为bbox int index = 0;
float centerX = getCenterX(bbox[index]);
float centerY = getCenterY(bbox[index]);
将新的xcenter和ycenter成员添加到ObjectBox结构中,并在processFrame方法的计算过程中存储中心值。为此,您需要访问ObjectBox源代码并需要重新编译它。只需添加头文件
中的ObjectBox类(或结构)定义即可float centerx;
float centery;
然后您可以从:
更改processFrame方法中的代码 //delete[] points0; delete[] points1; delete[] points2;
//delete[] status; delete[] fb; delete[] ncc;
float centerx = oldcenterx + dx,
centery = oldcentery + dy;
bbox[obj].x = (centerx - s * oldwidth * 0.5);
bbox[obj].y = (centery - s * oldheight * 0.5);
bbox[obj].width = s * oldwidth;
bbox[obj].height = s * oldheight;
为:
//delete[] points0; delete[] points1; delete[] points2;
//delete[] status; delete[] fb; delete[] ncc;
bbox[obj].centerx = oldcenterx + dx,
bbox[obj].centery = oldcentery + dy;
bbox[obj].x = (bbox[obj].centerx - s * oldwidth * 0.5);
bbox[obj].y = (bbox[obj].centery - s * oldheight * 0.5);
bbox[obj].width = s * oldwidth;
bbox[obj].height = s * oldheight;
然后你也可以改进oldcenterx代码:
oldcenterx = bbox[obj].x + oldwidth*0.5,
oldcentery = bbox[obj].y + oldheight*0.5;
为:
oldcenterx = bbox[obj].centerx,
oldcentery = bbox[obj].centery;
希望这有帮助!可能存在语法错误......
编辑:从为BoundingBox结构提供的代码中,实现上面的选项2.您应该从以下位置编辑它:
/// datastructure linking objects to their (possible) location
struct ObjectBox
{
/// x-component of top left coordinate
float x;
/// y-component of top left coordinate
float y;
/// width of the image section
float width;
/// height of the image section
float height;
/// identifies object, which is represented by ObjectBox
int objectId;
};
到
/// datastructure linking objects to their (possible) location
struct ObjectBox
{
/// x-component of top left coordinate
float x;
/// y-component of top left coordinate
float y;
/// width of the image section
float width;
/// height of the image section
float height;
/// identifies object, which is represented by ObjectBox
int objectId;
/// x-component of center coordinate
float centerx;
/// y-component of center coordinate
float centery;
};
如果您随后在processFrame代码中进行了更改,那么您应该可以从任何边界框中获取centerx和centery coordenates。
您遇到的问题似乎是如何访问实际的边界框。我建议您搜索代码以获取对processFrame函数的所有调用,并在将ObjectBox对象传递给processFrame函数之前查看ObjectBox对象的创建和存储位置,以了解如何访问它。
也许您可以添加更多代码来更准确地解释问题的来源。