为了刻画图像中颜色的直观特性,常常需要分析图像的HSV空间下的直方图特性。HSV空间是由色调、饱和度、以及亮度构成,因此在进行直方图计算时,需要先将源RGB图像转化为HSV颜色空间图像,然后将对应的H和S通道进行单元划分,再其二维空间上计算相对应直方图,再次在通过计算直方图空间上的最大值,归一化绘制相应的直方图信息。色相饱和度直方图通常应用在目标检测、特征分析以及目标特征跟踪等场景。
代码如下:
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/opencv.hpp"
#include "opencv2/core/core.hpp"
#include <stdio.h>
#include <string>
using namespace std;
using namespace cv;
int main()
{
cv::Mat hsvMat;
cv::Mat srcImage = cv::imread("C:\\Users\\LP\\Desktop\\C++\\ConsoleApplication4\\ConsoleApplication4\\RGBFlower4.jpg");
if (srcImage.empty())
{
return -1;
}
cv::imshow("原图像", srcImage);
//灰度转换
cv::Mat srcGray;
cv::cvtColor(srcImage, hsvMat, CV_BGR2HSV);
cv::imshow("hsvMat", hsvMat);
//初始化灰度阶参数
int hbins = 30;
int sbins = 32;
int histSize[] = {hbins, sbins};
//灰度变化范围设置
float hranges[] = {0, 180};
//饱和度变化范围
float sranges[] = {0, 256};
const float* ranges[] = {hranges, sranges};
cv::MatND hist;
//选取计算直方图通道
int channels[] = {0, 1};
//计算当前通道直方图
cv::calcHist(&hsvMat, 1, channels, cv::Mat(), hist, 2, histSize, ranges, true, false);
double maxVal = 0;
//找到直方图最大值
cv::minMaxLoc(hist, 0, &maxVal, 0, 0);
int scale = 10;
cv::Mat histImage = cv::Mat::zeros(sbins*scale, hbins*10, CV_8UC3);
//遍历H、S通道
for (int h = 0; h < hbins; h++)
{
for (int s = 0; s < sbins; s++)
{
float binVal = hist.at<float>(h, s);
//根据最大值计算变化范围
int intensity = cvRound(binVal*255/maxVal);
//绘图显示
cv::rectangle(histImage, cv::Point(h*scale, s*scale),
cv::Point((h+1)*scale-1, (s+1)*scale-1), cv::Scalar::all(intensity), CV_FILLED);
}
}
cv::imshow("H-S Histogram", histImage);
cv::waitKey(0);
return 0;
}