I'm using some computer vision code in c++ that tracks an object after you draw a bounding box around it, and it can track multiple objects with multiple bounding boxes. In one of the header files there is a function that processes the frame and defines the objects center pixel coordinates as variables centerx and centery, but I need to be able to use these variable in the main cpp file.
In this part of the function oldcenterx and oldcentery are defined:
EDIT: Added 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;
And then centerx and centery are defined later in this section:
// 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;
One thing I have done so far is defined centerx and centery globally at the top of the header file. This works great for the time being and I can use the data I need, but this only gives position data for the object in the most recently drawn bounding box so I can only get the pixel coordinates of one object.
I also tried defining a global vector like this:
std::vector<ObjectCenter> objcenter;
so then
objcenter[obj].objcenterx = centerx;
But I would keep getting errors that the vector is not initialized, or the code would unexpectedly quit running with no errors.
EDIT: Here is the ObjectBox struct:
/// 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: Thank you for the help. I'm a n00b. -Tyler
Aucun commentaire:
Enregistrer un commentaire