为什么这些直方图函数不同,为什么一个是不确定的?
Why do these histogram functions differ, and why is one nondeterministic?
注意:这是一个家庭作业问题,教授明确禁止从 Whosebug 征求答案,因此请将您的回答限制在我提出的具体问题上,不要试图提供可行的解决方案。
我被要求实现一个函数来计算表示为类型为 CV_U8
.
的 OpenCV Mat
的单通道 8 位图像的直方图
在这种情况下,直方图使用 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<0.05,n=66)。有一次它失败了,我检查了结果,没有发现任何可辨别的模式。所有试验都在同一张测试图像上进行。
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;
}
为什么第一次实施的结果与第二次实施的结果不同,第一次实施的不确定性在哪里引入?
初始化直方图矩阵应该有效:
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;
}
注意:这是一个家庭作业问题,教授明确禁止从 Whosebug 征求答案,因此请将您的回答限制在我提出的具体问题上,不要试图提供可行的解决方案。
我被要求实现一个函数来计算表示为类型为 CV_U8
.
Mat
的单通道 8 位图像的直方图
在这种情况下,直方图使用 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<0.05,n=66)。有一次它失败了,我检查了结果,没有发现任何可辨别的模式。所有试验都在同一张测试图像上进行。
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;
}
为什么第一次实施的结果与第二次实施的结果不同,第一次实施的不确定性在哪里引入?
初始化直方图矩阵应该有效:
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;
}