【问题标题】:Why do these histogram functions differ, and why is one nondeterministic?为什么这些直方图函数不同,为什么一个是不确定的?
【发布时间】:2018-02-10 20:08:23
【问题描述】:

注意:这是一个家庭作业问题,教授明确禁止从 StackOverflow 征求答案,因此请限制您对我提出的具体问题的回答,不要试图提供可行的解决方案。

我被要求实现一个函数,该函数计算单通道 8 位图像的直方图,该图像表示为类型为 CV_U8 的 OpenCV Mat

在这种情况下,直方图使用 256 个均匀分布的桶。这是我们打算复制的参考(使用 OpenCV 3.4):

Mat reference;

/// Establish the number of bins
int histSize = 256;

/// Set the ranges ( for B,G,R) )
float range[] = { 0, 256 } ;
const float* histRange = { range };

bool uniform = true;
bool accumulate = false;

cv::calcHist(&bgr_planes[0], 1, 0, Mat(), reference, 1, &histSize, &histRange,
             uniform, accumulate);

// reference now contains the canonical histogram of the input image's
// blue channel

我编写了以下函数来计算直方图,它在 45-69% 的时间内产生正确的结果(p

Mat myCalcHist(const Mat& input) {
  assert(input.isContinuous());

  Mat res(256, 1, CV_32F);
  for (const uint8_t* it = input.datastart; it != input.dataend; ++it) {
    ++res.at<float>(*it);
  }

  return res;
}

另一方面,以下函数更接近 OpenCV 的内部实现,因为它使用惯用访问器并将 float 结果从 int 工作矩阵转换,但在 n=66 次试验中它没有产生一次正确的结果。同样,我在数据中没有发现可辨别的模式。

Mat myCalcHist(const Mat& input) {

  Mat ires(256, 1, CV_32S);
  for (int i = 0; i < input.total(); ++i) {
    ++ires.at<int>(input.at<uint8_t>(i));
  }

  Mat res(256, 1, CV_32F);
  ires.convertTo(res, CV_32F);
  return res;
}

为什么我的第一个实现的结果与我的第二个实现的结果不同,第一个实现在哪里引入了不确定性?

【问题讨论】:

  • res 初始化了吗?
  • 您应该使用(构造函数)cv::Mat::zeros(size, type) 或 cv::Mat(size,type,cv::Scalar::all(0) 初始化矩阵数据))
  • 使用 cv::Mat::zeros() 或 cv::Mat::setTo() 来初始化 res。如果只调用mat的构造函数,则只分配内存,不初始化零。
  • 在第二个代码中,必须初始化ires,而不是res
  • @hxtk:这里有一个很好的教训:如果你的代码是无意“随机”的,你很可能会读取未启动的内存!

标签: c++ opencv image-processing histogram non-deterministic


【解决方案1】:

初始化直方图矩阵应该可以工作:

Mat myCalcHist(const Mat& input) 
{
    Mat ires = cv::Mat::zeros(256, 1, CV_32S);
    for (int i = 0; i < input.total(); ++i) 
    {
         ++ires.at<int>(input.at<uint8_t>(i));
    }

   Mat res(256, 1, CV_32F);
   ires.convertTo(res, CV_32F);
   return res;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-30
    • 2018-07-06
    • 1970-01-01
    • 1970-01-01
    • 2020-09-18
    • 1970-01-01
    • 2014-11-18
    • 2017-12-30
    相关资源
    最近更新 更多