赞
踩
直方图
直方图是数值数据分布的精确图形表示。为了构建直方图,第一步是将值的范围分段,即将整个值的范围分成一系列间隔,然后计算每个间隔中有多少值。 这些值通常被指定为连续的,不重叠的变量间隔。 间隔必须相邻,并且通常是(但不是必须的)相等的大小。
图像直方图
图像直方图统计的可以是对描述图像有用的任何特征,如灰度值,梯度等。
直方图是图像的一个统计特征,它具有旋转、缩放、平移不变性,被应用于灰度图像的阈值分割,对比度调整,颜色匹配等等。下面以灰度图像灰度直方图说明统计的原理:
考虑以上灰度值图像,我们如何统计这些数据呢?我们知道灰度值在0 - 255范围之间总共 256 个值,可以将我们的范围划分为子部分(称为bins),例如:
计算每个bini范围内像素的数量。得到下图(x轴表示bin,y轴表示每个箱子中的像素数)。
直方图重要概念:
dim:希望收集数据的参数数量。在上面例子中,dims = 1是因为我们只计算每个像素(在灰度图像中)的强度值。
bin:在上面例子的示例中,bins = 16
range:要测量的值的限制。在本例中:range = [0,255]
计算一组数组的直方图。函数原型,三个重载函数:
CV_EXPORTS void calcHist( const Mat* images, int nimages, const int* channels, InputArray mask, OutputArray hist, int dims, const int* histSize, const float** ranges, bool uniform = true, bool accumulate = false ); /** @overload this variant uses %SparseMat for output */ CV_EXPORTS void calcHist( const Mat* images, int nimages, const int* channels, InputArray mask, SparseMat& hist, int dims, const int* histSize, const float** ranges, bool uniform = true, bool accumulate = false ); /** @overload */ CV_EXPORTS_W void calcHist( InputArrayOfArrays images, const std::vector<int>& channels, InputArray mask, OutputArray hist, const std::vector<int>& histSize, const std::vector<float>& ranges, bool accumulate = false );
参数说明:
images:源数组。它们都应该具有相同的深度,CV_8U, CV_16U或CV_32F,以及相同的大小。它们中的每一个都可以有任意数量的通道。
nimages:源图像个数。
channels:要测量的通道。
mask:源数组上使用的掩码(0表示要忽略的像素)。如果没有定义,则不使用
hist:输出直方图数组。
dims:直方图维度,必须是正的,不大于CV_MAX_DIMS(在当前OpenCV版本中等于32)。
histSize:每个维度bind的数量
ranges:每个维度要测量的值的范围
uniform:表示直方图是否均匀的标志(见上)。
accumulate:积累标志。如果设置了,则分配直方图时,一开始不清除。该特性使您能够从多个数组集合中计算出一个直方图,或者及时更新直方图。
cv::Mat image = cv::imread("D:\\QtProject\\Opencv_Example\\Hist\\Hist.png", cv::IMREAD_GRAYSCALE); if (image.empty()) { cout << "Cannot load image" << endl; return; } imshow("image",image); const int bins[1] = { 256 }; float hranges[2] = { 0,255 }; const float* ranges[1] = { hranges }; Mat hist; // 计算直方图 calcHist(&image, 1, 0, Mat(), hist, 1, bins, ranges); // 显示直方图 int hist_w = 500; int hist_h = 600; int bin_w = cvRound((double)hist_w / bins[0]); //两个灰度级之间的距离 Mat histImage = Mat::zeros(hist_h, hist_w, CV_8UC3); //直方图画布 // 归一化直方图数据 normalize(hist, hist, 0, histImage.rows, NORM_MINMAX, -1, Mat()); //将数据规皈依到0和hist_h之间 // 绘制直方图曲线 for (int i = 1; i < bins[0]; i++) { line(histImage, Point(bin_w*(i - 1), hist_h - cvRound(hist.at<float>(i - 1))), Point(bin_w*(i), hist_h - cvRound(hist.at<float>(i))), Scalar(0, 255, 0), 2, 8, 0); } // 显示直方图 namedWindow("Histogram", WINDOW_AUTOSIZE); imshow("Histogram", histImage);
运行效果:
原图:
直方图:
参考文章:https://docs.opencv.org/4.x/d8/dbc/tutorial_histogram_calculation.html
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。