【问题标题】:What to do with negative rho values in hough transform?如何处理霍夫变换中的负 rho 值?
【发布时间】:2017-01-05 16:01:05
【问题描述】:

这是我为图像中的线条创建hough accumulator 的代码:

void hough_lines_acc(cv::Mat img_a_edges, std::vector<std::vector<int> > &hough_acc) {
  for (size_t r = 0; r < img_a_edges.rows; r++) {
    for (size_t c = 0; c < img_a_edges.cols; c++) {
      int theta = static_cast<int> (std::atan2(r, c) * 180 / M_PI);
      int rho = static_cast<int> ((c * cos(theta)) + (r * sin(theta)));
      if (theta < -90) theta = -90;
      if (theta > 89) theta = 89;

      ++hough_acc[abs(rho)][theta];
    }
  }

  cv::Mat img_mat(hough_acc.size(), hough_acc[0].size(), CV_8U);

  std::cout << hough_acc.size() << "  " << hough_acc[0].size() << std::endl;
  for (size_t i = 0; i < hough_acc.size(); i++) {
    for (size_t j = 0; j < hough_acc[0].size(); j++) {
      img_mat.at<int> (i,j) = hough_acc[i][j];
    }
  }

  imwrite("../output/ps1-­2-­b-­1.png", img_mat);
}

theta-90 to 89 不同。我得到负 rho 值。现在我只是用一个积极的人代替消极的人,但没有得到正确的答案。我对负 rho 怎么办?请解释答案。

theta = arctan (y / x)
rho = x * cos(theta) + y * sin(theta)

编辑代码:

bool hough_lines_acc(cv::Mat img_a_edges, std::vector<std::vector<int> > &hough_acc,\
   std::vector<double> thetas, std::vector<double> rhos, int rho_resolution, int theta_resolution) {
  int img_w = img_a_edges.cols;
  int img_h = img_a_edges.rows;

  int max_votes = 0;
  int min_votes = INT_MAX;

  for (size_t r = 0; r < img_h; r++) {
    for (size_t c = 0; c < img_w; c++) {
      if(img_a_edges.at<int>(r, c) == 255) {
        for (size_t i = 0; i < thetas.size(); i++) {
          thetas[i] = (thetas[i] * M_PI / 180);
          double rho = ( (c * cos(thetas[i])) + (r * sin(thetas[i])) );
          int buff = ++hough_acc[static_cast<int>(abs(rho))][static_cast<int>(i)];

          if (buff > max_votes) {
            max_votes = buff;
          }
          if (buff < min_votes) {
            min_votes = buff;
          }
        }
      }
    }
  }

  double div = static_cast<double>(max_votes) / 255;
  int threshold = 10;
  int possible_edge = round(static_cast<double>(max_votes) / div) - threshold;

  props({
    {"max votes", max_votes},
    {"min votes", min_votes},
    {"scale", div}
  });
  // needed for scaling intensity for contrast
  // not sure if I am doing it correctly
  for (size_t r = 0; r < hough_acc.size(); r++) {
    for (size_t c = 0; c < hough_acc[0].size(); c++) {
      double val = hough_acc[r][c] / div;
      if (val < 0) {
        val = 0;
      }

      hough_acc[r][c] = static_cast<int>(val);
    }
  }


  cv::Mat img_mat = cv::Mat(hough_acc.size(), hough_acc[0].size(), CV_8UC1, cv::Scalar(0));

  for (size_t i = 0; i < hough_acc.size(); i++) {
    for (size_t j = 0; j < hough_acc[0].size(); j++) {
      img_mat.at<uint8_t> (i,j) = static_cast<uint8_t>(hough_acc[i][j]);
    }
  }

  imwrite("../output/ps1-­2-­b-­1.png", img_mat);
  return true;
}

仍然不正确的输出。这里有什么错误?

【问题讨论】:

    标签: c++ opencv computer-vision


    【解决方案1】:

    两个正数的atan2...不应该给你负角度,它应该只给你0-90的范围

    对于霍夫变换,我认为您希望所有内容都相对于一个点(即在这种情况下为 0,0)。我认为为此你实际上想要制作 theta=90-atan2(r,c)

    诚然,我有点困惑,因为我认为您必须对行方向进行编码,而不仅仅是“边缘 pt”。即,我认为在每个边缘点,您必须提供猜测的线轨迹的离散数组并计算每个的 rho 和 theta,并将所有这些都放入累加器中。按原样...我不确定你在计算什么。

    【讨论】:

    • 我认为我不太了解算法:/ 在课程中教授说d = x * cos(theta) - y * sin(theta),作业说rho = x * cos(theta) + y * sin(theta)。有什么不同?从语言来看,d 和 rho 似乎与 prof 相同,将 hough acc 映射为 H[d, theta]。
    • 另外,我打算在算法中包含一个选项,其中允许使用 b/w -90 和 89 的值。我们正在计算 theta。我该如何允许?这就是它所说的:with one optional parameter specified (θ = integers ­90 to 89 , i.e. 180 values including 0 ).
    • 哦!我觉得我懂了!您不想从任何东西计算 theta,这将是我提到的离散列表。创建一个介于 -90 和 90 之间的值数组(例如 30 度增量)。然后对于数组中的每个边缘点,计算每个 theta 的 rho 并将每一个添加到您的累加器中。 ------- 为了更好地理解算法(en.wikipedia.org/wiki/Hough_transform):想象一下,在每一点你都在生成一个星形的线条图案(猜测)。线性相关的点应该添加到相同的猜测中,创建您的峰值!
    • 您的函数参数可能会指定猜测的范围(-90 到 90)或更多或更少,或增量步长(30 度)。这将允许在您的 rho theta 空间中提高分辨率。
    • d 和 rho 是一回事。基本上,rho-theta 组合是图像中唯一可能的线。因此,如果您在图像中描绘某条线,theta 将是该线与 x 轴之间的角度(交叉点左上角的角度)。现在的问题是有很多可能的线具有相同的角度,所以 rho 是从那条线到原点的垂直距离(即你可以认为它是从那条线到原点的最短距离)。有了这两个值,行描述符现在是唯一的
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-26
    相关资源
    最近更新 更多