图像直方图是图像处理中的重要分析工具,它通过统计像素值分布揭示图像的亮度、对比度等关键特性。本章将深入探讨直方图的各种操作及其应用,并延伸至模板匹配与几何变换等核心技术,为图像分析与处理提供强大工具集。
一、像素统计信息
在分析图像之前,获取基本的像素统计信息(如均值、方差、最值等)是理解图像特性的第一步,这些统计量能帮助我们快速判断图像质量与内容特征。
1.1 基本统计量计算
OpenCV 提供meanStdDev函数一次性计算图像的均值与标准差,结合minMaxLoc可获取像素最值:
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main() {
Mat img = imread("test.jpg", IMREAD_GRAYSCALE);
if (img.empty()) {
cout << "图像加载失败!" << endl;
return -1;
}
// 1. 计算均值与标准差
Scalar mean, stddev;
meanStdDev(img, mean, stddev); // 单通道图像返回Scalar(mean, 0, 0, 0)
// 2. 计算最大最小值及位置
double minVal, maxVal;
Point minLoc, maxLoc;
minMaxLoc(img, &minVal, &maxVal, &minLoc, &maxLoc);
// 3. 输出统计结果
cout << "均值: " << mean[0] << endl;
cout << "标准差: " << stddev[0] << endl;
cout << "最小值: " << minVal << " 位置: " << minLoc << endl;
cout << "最大值: " << maxVal << " 位置: " << maxLoc << endl;
return 0;
}
1.2 多通道图像统计
对于彩色图像(BGR 三通道),可分别计算各通道的统计信息:
Mat img = imread("test.jpg"); // 加载BGR彩色图像
vector<Mat> channels;
split(img, channels); // 分离三通道
for (int i = 0; i < 3; ++i) {
Scalar mean, stddev;
meanStdDev(channels[i], mean, stddev);
double minVal, maxVal;
minMaxLoc(channels[i], &minVal, &maxVal);
cout << "通道 " << i << " (BGR中对应" << (i==0?"B":i==1?"G":"R") << "):" << endl;
cout << " 均值: " << mean[0] << ", 标准差: " << stddev[0] << endl;
cout << " 最小值: " << minVal << ", 最大值: " << maxVal << endl;
}
1.3 统计信息的应用价值
- 均值:反映图像整体亮度,均值过高(接近 255)说明图像过曝,过低说明过暗;
- 标准差:反映像素值离散程度,标准差小说明图像对比度低,细节不明显;
- 最值位置:可快速定位图像中最亮 / 最暗区域,用于分析高光或阴影区域。
二、直方图绘制
直方图是像素值分布的可视化表示,X 轴为像素值(0-255),Y 轴为对应值的像素数量。OpenCV 提供calcHist函数计算直方图数据,结合绘图工具可实现可视化。
2.1 直方图计算(calcHist 函数)
Mat calcGrayHistogram(const Mat& img) {
// 直方图参数设置
int histSize = 256; // 直方图分箱数
float range[] = {0, 256}; // 像素值范围
const float* histRange = {range};
Mat hist;
// 计算直方图
calcHist(&img, 1, 0, Mat(), hist, 1, &histSize, &histRange, true, false);
return hist;
}
参数说明:
&img:输入图像指针(支持多图像)1:图像数量0:通道索引(单通道为 0)Mat():掩码(为空表示使用全部像素)hist:输出直方图(256×1 的 Mat)1:直方图维度&histSize:每个维度的分箱数&histRange:每个维度的像素值范围true:直方图是否归一化false:是否累积直方图
2.2 直方图可视化
结合 OpenCV 的绘图函数将直方图数据可视化为图像:
Mat drawHistogram(const Mat& hist, int histHeight = 200) {
int histS

1286

被折叠的 条评论
为什么被折叠?



