我如何将这些局部变量用于我的主函数中的对象位置?

How could I use these local variables for object position in my main function?

我正在使用 C++ 中的一些计算机视觉代码,在围绕对象绘制边界框后跟踪对象,并且它可以跟踪具有多个边界框的多个对象。在其中一个头文件中有一个处理帧并将对象中心像素坐标定义为变量 centerxcentery 的函数,但我需要能够在主 cpp 文件中使用这些变量.

在这部分函数中定义了oldcenterxoldcentery

编辑:添加了 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;

然后centerxcentery在本节后面定义:

// 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;

到目前为止我所做的一件事是在头文件的顶部全局定义 centerxcentery。这暂时很好用,我可以使用我需要的数据,但这只给出了最近绘制的边界框中对象的位置数据,所以我只能得到一个对象的像素坐标。

我也试过像这样定义一个全局向量:

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)

我认为你最好的两个选择是:

  1. 从 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]);
    
  2. 将新的 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 函数之前创建和存储的位置,以了解如何访问它。

也许您可以添加更多代码以更好地准确解释问题出在哪里。