OpenCV(cv::calcHist())
cv::calcHist()
是 OpenCV 中用于计算图像或图像集合的直方图的函数。直方图是一个图像的像素值的分布统计,它表示图像中每个像素强度值的频率。
1. 函数定义
cv::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)
参数:
-
images
:
指向源图像(或图像数组)的指针,通常是一个cv::Mat
类型对象的数组。例如,对于单通道灰度图像,它通常是指向一个图像的指针。 -
nimages
:
这是图像的数量,通常为 1。如果你要计算多幅图像的直方图,可以传递多个图像。 -
channels
:
这是需要计算直方图的通道索引。例如,对于彩色图像,可以分别计算 B、G、R 三个通道的直方图。对于灰度图像,通道索引通常为 0。 -
mask
:
用于选择计算直方图的区域。可以是一个掩码图像,该掩码通常是一个单通道的 8 位图像,非零值的区域表示参与直方图计算的区域。传递cv::Mat()
可以忽略掩码。 -
hist
:
这是输出的直方图,通常是一个cv::Mat
对象。该对象包含直方图数据。 -
dims
:
直方图的维度。对于一维直方图,dims = 1
;对于二维直方图(例如,用于分析颜色分布),dims = 2
。 -
histSize
:
每个维度的直方图 bin 数量。对于一维直方图,它是一个包含 bin 数量的数组。例如,histSize = {256}
表示每个通道有 256 个 bin。 -
ranges
:
每个维度的取值范围。通常,它是一个二维数组,每个维度都有一个[minValue, maxValue]
的范围。例如,对于 8 位图像,通常范围是[0, 256]
。 -
uniform
:
布尔值,表示 bin 的宽度是否均匀分布。如果为true
,则范围被均匀划分为histSize
个区间。 -
accumulate
:
布尔值,表示是否累加直方图。如果为true
,则将新的计算结果累加到已有的直方图中,而不是重新计算。
2. 示例
计算灰度图像的一维直方图的简单示例:
#include <opencv2/opencv.hpp>
#include <iostream>
int main() {
cv::Mat image = cv::imread("image.jpg", cv::IMREAD_GRAYSCALE);
if (image.empty()) {
std::cout << "Could not load image!" << std::endl;
return -1;
}
// 初始化直方图参数
int histSize = 256; // bin 数量
float range[] = {0, 256}; // 范围
const float* histRange = {range};
// 输出直方图
cv::Mat hist;
// 计算直方图
cv::calcHist(&image, 1, 0, cv::Mat(), hist, 1, &histSize, &histRange);
// 输出结果
std::cout << "Histogram values: " << hist << std::endl;
return 0;
}
3. 功能说明
- 单通道图像直方图:通常用于灰度图像,计算每个像素强度值(0-255)的分布频率。
- 多通道图像直方图:可以用于彩色图像,通过指定不同的
channels
参数来分别计算 B、G、R 通道的直方图。 - 掩码直方图:可以指定掩码,只计算图像中感兴趣区域的直方图。
- 多维直方图:可以通过设置
dims
和histSize
来计算多维直方图,例如,二维直方图用于表示颜色组合的分布。
4. 典型应用
- 图像分析:通过直方图可以分析图像的亮度、对比度、颜色分布等特性。
- 直方图均衡化:通过直方图进行均衡化,可以改善图像的对比度。
- 图像分割:利用直方图信息可以帮助进行图像阈值分割或其他分析任务。