色调(Hue),饱和度(Saturation),H-S直方图也就是色调-饱和度直方图。
统计学中,直方图(Histogram)是一种对数据分布情况的图形表示,是一种二维统计图表,它的两个坐标分别是统计样本和该样本对应法的某个属性的度量。
图像直方图(Image Histogram)是用以表示数字图像中亮度分布的直方图,标绘了图像中每个亮度值的像素数。可以借助观察该直方图了解需要如何调整亮度分布。直方图中,横坐标的左侧为纯黑,较暗的区域,而右侧为较亮,纯白的区域。因此,一张较暗图片的图像直方图中的数据多集中于左侧和中间部分,而整体明亮/只有少量阴影的图像则相反。计算机视觉领域常借助图像直方图来实现图像的二值化。
直方图的意义:
(1)直方图是图像中像素强度分布的图形表达方式
(2)直方图统计类每一个强度值所具有的像素个数
#include <opencv2/opencv.hpp>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
using namespace cv;
int main( int argc, const char* argv[])
{
Mat srcImage, hsvImage;
srcImage = imread("…/data/1.jpg");
cvtColor(srcImage, hsvImage, COLOR_BGR2HSV);
int hueBinNum = 30; //色调的直方图直条数量
int saturationBinNum = 32; //饱和度的直方图直条数量
int histSize[] = {hueBinNum, saturationBinNum};
//定义色调的变化范围为0到179
float hueRanges[] = {0, 180};
//定义饱和度的变化范围0(黑,白,灰)到255(纯光谱颜色)
float saturationRanges[] = {0, 256};
const float* ranges[] = {hueRanges, saturationRanges};
MatND dstHist;
//参数准备,calcHist函数中将计算第0通道和第1通道的直方图
int channels[] = {0, 1};
//正式调用calcHist,进行直方图计算
calcHist(&hsvImage, //输入的数组
1, //数组个数为1
channels, //通道索引
Mat(), //不使用掩膜
dstHist, //输出的目标直方图
2, //需要计算的直方图的维度为2
histSize, //存放每个维度的直方图尺寸的数组
ranges, //每一维数值的取值范围数组
true, //指示直方图是否均匀的标识符,true表示均匀的直方图
false//累计标识符,false表示直方图在配置阶段会被清零
);
//为绘制直方图准备参数
double maxValue = 0; //最大值
minMaxLoc(dstHist, 0, &maxValue, 0, 0); //查找数组和子数组的全局最小值和最大值存入maxValue中
int scale = 10;
Mat histImg = Mat::zeros(saturationBinNum*scale, hueBinNum*10, CV_8UC3);
//双层循环进行直方图绘制
for(int hue = 0; hue < hueBinNum; hue++)
{
for(int saturation = 0; saturation < saturationBinNum; saturation++)
{
float binValue = dstHist.at<float>(hue, saturation); //直方图直条的值
int intensity = cvRound(binValue*255/maxValue); //强度
//正式进行绘制
rectangle(histImg, Point(hue*scale, saturation*scale), Point((hue+1)*scale - 1, (saturation+1)*scale - 1),
Scalar::all(intensity), FILLED);
}
}
imshow("素材图", srcImage);
imshow("H-S直方图", histImg);
waitKey();
return 0;
}