我如何将这些局部变量用于我的主函数中的对象位置?
How could I use these local variables for object position in my main function?
我正在使用 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。
-泰勒
在函数processFrame()中添加参数objcenter,使main函数可以获取数据。
void LKTracker::processFrame(const Matrix& curImage, std::vector& bbox, std::vector& isDefined, vector & objcenter)
我假设您可以访问传递给此函数的参数 void LKTracker::processFrame(const Matrix& curImage, std::vector<ObjectBox>& bbox, std::vector<bool>& isDefined)
我认为你最好的两个选择是:
从 bbox (ObjectBox) x、宽度和 y、高度值计算中心。您可以创建函数使其更清晰:
// 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 class(或结构)定义
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;
您还可以改进旧的 centerx 代码:
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 坐标。
看来您遇到的问题是如何访问实际的边界框。我建议您搜索对 processFrame 函数的所有调用的代码,并查看 ObjectBox 对象在传递给 processFrame 函数之前创建和存储的位置,以了解如何访问它。
也许您可以添加更多代码以更好地准确解释问题出在哪里。
我正在使用 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。 -泰勒
在函数processFrame()中添加参数objcenter,使main函数可以获取数据。 void LKTracker::processFrame(const Matrix& curImage, std::vector& bbox, std::vector& isDefined, vector & objcenter)
我假设您可以访问传递给此函数的参数 void LKTracker::processFrame(const Matrix& curImage, std::vector<ObjectBox>& bbox, std::vector<bool>& isDefined)
我认为你最好的两个选择是:
从 bbox (ObjectBox) x、宽度和 y、高度值计算中心。您可以创建函数使其更清晰:
// 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 class(或结构)定义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;
您还可以改进旧的 centerx 代码:
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 坐标。
看来您遇到的问题是如何访问实际的边界框。我建议您搜索对 processFrame 函数的所有调用的代码,并查看 ObjectBox 对象在传递给 processFrame 函数之前创建和存储的位置,以了解如何访问它。
也许您可以添加更多代码以更好地准确解释问题出在哪里。