本篇博文用于记录 OpenCV 库提供的直方图统计功能,并给出图像灰度直方图提取与灰度均衡两个简例。
直方图统计
先对直方图概念进行阐述。
最常见的直方图为灰度直方图:对给定的灰度图像进行统计,自变量为灰度x(x取值0-255),因变量为灰度为x的像素个数。
更广义地,直方图本质是一种统计操作。给定元素集 S ,每一元素都有 channels 个属性。直方图统计操作为:以元素属性的可能取值为自变量x(x可以是多个维度构成的属性向量),统计具有属性x的元素个数。
以下介绍 OpenCV 提供的计算直方图的函数: cv::calcHist() 。
void calcHist( const Mat* images, //样本集S,为多个相同size的Mat构成的数组。
//其中每一像素为一个元素,具有channals个属性。
//images中不同的Mat中相同位置的元素按channals进行拼接,形成一个元素。
int nimages, //images数组长度(统计几个image)
const int* channels, //需要用作统计自变量的属性维度下标索引(如{0,1}即以第0,1两维度属性值为自变量)
InputArray mask, //掩膜,用于指定只统计特定区域的元素,若为空(cv::Mat())时,统计全部像素元素
OutputArray hist, //统计直方图输出,为通道数1的dims维Mat数据,汇总了给定对应属性下的元素个数
int dims, //统计直方图维度,与channels数组长度相同
const int* histSize, //histSize[i]为第i统计维度区分间隔数量(自变量可取离散值数量,也称bins数量)
const float** ranges, //ranges[i]数组给定了第i统计维度bins的划分情况,若为均匀划分,则只需给出首尾
bool uniform = true, //bins是否均匀分布的标志位,若为true,则ranges数组只需给出统计范围首尾
bool accumulate = false //hist是否累加(控制hist需不需要清零)
);
以下给出一个直方图统计应用案例。
//lena图为rgb三色图,即每一像素视为一个元素,
//每一元素具有rgb三个属性
cv::Mat srcImg = cv::imread("lena.jpg");
//统计lena图的第1,2两个维度
int histDim[] = { 1, 2 };
//两个统计维度的bins区分数量,第一维度和第二维度都是划分为4个区间
int histSize[] = { 4, 4 };
//给出两个统计维度取值范围划分情况,由于使用均匀划分,这里只需要给出首尾
float range1[] = { 0, 256 };
float range2[] = { 0, 256 };
float* ranges[2];
ranges[0] = range1;
ranges[1] = range2;
//最后生成的统计直方图
cv::Mat hist;
//注意第一个参数为&srcImg,只统计一张图,所以直接取图的首地址,给定mask为空,统计全图。
cv::calcHist(&srcImg, 1, histDim, cv::Mat(), hist, 2, histSize, (const float**)ranges, true);
灰度图像直方图提取
这里给出灰度直方图的统计代码作为实例。
cv::Mat srcImg = cv::imread("lena.jpg");
cv::Mat grayImg;
cv::cvtColor(srcImg, grayImg, cv::ColorConversionCodes::COLOR_BGR2GRAY);
//统计lena对应灰度图,仅灰度这一属性
int histDim[] = { 0 };
//灰度bins区分数量
int histSize[] = { 256 };
//使用均匀划分,这里只需要给出首尾
float range[] = { 0, 256 };
float* ranges[1];
ranges[0] = range;
//最后生成的统计直方图
cv::Mat hist;
//注意第一个参数为&srcImg,只统计一张图,所以直接取图的首地址,给定mask为空,统计全图。
cv::calcHist(&grayImg, 1, histDim, cv::Mat(), hist, 1, histSize, (const float**)ranges, true);
灰度均衡
OpenCV 提供了直接,简便的灰度均衡函数 cv::equalizeHist() 。
void equalizeHist( InputArray src, //输入灰度图像
OutputArray dst //均衡后输出灰度图像
);
尾注以上阐述为学习过程笔记,如有错误,敬请指正。