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

时间:2015-03-13 19:55:39

标签: c++ vector global-variables computer-vision local-variables

我正在使用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。 -Tyler

2 个答案:

答案 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)

的参数

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

  1. 从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]);
    
  2. 将新的xcenter和ycenter成员添加到ObjectBox结构中,并在processFrame方法的计算过程中存储中心值。为此,您需要访问ObjectBox源代码并需要重新编译它。只需添加头文件

    中的ObjectBox类(或结构)定义即可
    float centerx; 
    float centery;
    
  3. 然后您可以从:

    更改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对象的创建和存储位置,以了解如何访问它。

    也许您可以添加更多代码来更准确地解释问题的来源。