目录
1 概念讲解及用处
图像直方图(Image Histogram)是对图像中像素强度分布的统计信息的可视化表示。它将图像中各个灰度级别的像素数量进行统计,然后将这些统计结果绘制成直方图。直方图能够展示图像的亮度、对比度和颜色分布等特征,方便我们对图像进行分析和处理。
在计算机视觉和图像处理领域,图像直方图广泛应用于以下方面:
图像增强:通过调整直方图来改变图像的亮度和对比度。
图像分割:通常通过寻找直方图的峰值或阈值来实现。
目标检测与识别:通过直方图匹配来判断图像中是否存在特定对象。
2 函数详解
在OpenCV中,可以使用calcHist函数计算直方图,并使用plotHistogram函数绘制直方图。
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:输入图像的数组。
nimages:输入图像的数量。
channels:要计算直方图的通道索引数组。
mask:掩码图像,指定要计算直方图的区域。若为空,则计算整个图像的直方图。
hist:输出的直方图。
dims:直方图的维数,通常为1。
histSize:直方图每个维度的区间数量。
ranges:直方图每个维度的取值范围。
uniform:是否对直方图进行归一化,默认为true。
accumulate:是否累积直方图,默认为false。
3 原理
图像直方图是对图像中像素灰度级别的统计结果。对于灰度图像,直方图可以表示为一个一维数组H,其中H[i]表示灰度级别i出现的次数。对于彩色图像,可以对每个通道分别计算直方图。
4 用C++编写代码进行实现
下面是一个使用OpenCV绘制图像直方图的示例代码:
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main()
{
// 读取图像
Mat image = imread("lena.png", IMREAD_GRAYSCALE);
if (image.empty())
{
cout << "Failed to load image." << endl;
return -1;
}
// 计算直方图
Mat hist;
int histSize = 256; // 直方图的区间数量
float range[] = { 0, 256 }; // 取值范围
const float* histRange = { range };
bool uniform = true;
bool accumulate = false;
calcHist(&image, 1, 0, Mat(), hist, 1, &histSize, &histRange, uniform, accumulate);
// 绘制直方图
int histWidth = 512;
int histHeight = 400;
int binWidth = cvRound((double)histWidth / histSize);
Mat histImage(histHeight, histWidth, CV_8UC3, Scalar(0, 0, 0));
normalize(hist, hist, 0, histImage.rows, NORM_MINMAX, -1, Mat());
for (int i = 1; i < histSize; i++)
{
line(histImage, Point(binWidth * (i - 1), histHeight - cvRound(hist.at<float>(i - 1))),
Point(binWidth * (i), histHeight - cvRound(hist.at<float>(i))),
Scalar(255, 255, 255), 2, LINE_AA);
}
//完成代码的最后一部分是将直方图显示出来:
imshow("Histogram", histImage);
waitKey();
return 0;
}
在这个示例中,我们首先读取了一张灰度图像,并使用calcHist函数计算了图像的直方图。然后,我们创建了一个空白图像histImage用于绘制直方图。通过对直方图进行归一化和绘制线条,最后将结果显示出来。
请注意,上述示例代码中只针对灰度图像的直方图绘制做了说明,如果需要处理彩色图像,则需要对每个通道分别计算直方图,并将结果绘制到相应的颜色通道上。