Histogram.h
#pragma once #include <opencv2/opencv.hpp> #include <iostream> using namespace cv; class Histogram { public: Histogram(void); ~Histogram(void); void getHist(Mat& srcImage, Mat& dstHist, int bins = 256, float minHistSize = 0.0, float maxHistSize = 255.0); void paintHist(Mat& distHist, bool isSaveHist = false, int width = 800, int high = 400); double getMinValue(); double getMaxValue(); private: int histSize[1]; //bin数量,只是OpenCV源代码中解释可以存储多个数组(图像),建议声明成数组形式 float hranges[2]; //直方图的最小值与最大值,比如,对于灰度值可以取0-255分成10组,也可以取100-200分成10组 const float* range[1]; //hranges的地址值要赋给ranges[0] int channel[1]; //灰度图像只有一个通道 double minValue; //所有bin中,最低的那个bin的值 double maxValue; //所有bin中,最高的那个bin的值 };Histogram.cpp
#include "Histogram.h" Histogram::Histogram(void) { histSize[0] = 256; hranges[0] = 0.0; hranges[1] = 255.0; range[0] = hranges; channel[0] = 0; minValue = 0.0; maxValue = 0.0; } Histogram::~Histogram(void) { } //计算直方图(原图像,输出直方图,bin数量(默认256),bin范围(默认0.0-255.0)) void Histogram::getHist(Mat& srcImage, Mat& dstHist, int bins, float minHistSize, float maxHistSize) { histSize[0] = bins; hranges[0] = minHistSize; hranges[1] = maxHistSize; //计算直方图(原图像,原图像数量,原图像通道数,掩膜(不使用),输出直方图,直方图维数) calcHist(&srcImage, 1, &channel[0], Mat(), dstHist, 1, histSize, range); //获取直方图最小值与最大值 minMaxLoc(dstHist, &minValue, &maxValue, NULL, NULL); std::cout << "最小值:" << minValue << std::endl; std::cout << "最大值:" << maxValue << std::endl; imshow("srcImage", srcImage); waitKey(30); } //绘制直方图(直方图,是否保存绘制的直方图(默认不保存),绘制的直方图宽度(默认800像素),绘制的直方图高度(默认400像素)) void Histogram::paintHist(Mat& distHist, bool isSaveHist, int width, int high) { //创建单通道图像,像素值为0 Mat histImg = Mat::zeros(high, width, CV_8UC1); //计算bin的宽度 int bin_w = static_cast<int>(static_cast<double>(width) / static_cast<double>(histSize[0])); //计算缩放因子f double f = static_cast<double>(high) / maxValue; //遍历直方图 for (int i = 0; i < histSize[0]; i++) { //计算每个bin的高度 int h = static_cast<int>(f * distHist.at<float>(i)); //计算每个bin的左上顶点坐标 int x = i * bin_w; int y = high - h; //画出每个bin rectangle(histImg, Rect(x, y, bin_w+1, h), Scalar(150)); } Point pstart(histSize[0]*bin_w, high-1); Point pend(histSize[0]*bin_w, 0); line(histImg, pstart, pend, Scalar(255)); //是否保存绘制的直方图 if (isSaveHist) { imwrite("histImg.png", histImg); } imshow("Histogram", histImg); waitKey(0); } double Histogram::getMinValue() { return minValue; } double Histogram::getMaxValue() { return maxValue; }main.cpp
#include "Histogram.h" int main() { Mat img = imread("1.jpg", 0); Mat dst; Histogram hist; hist.getHist(img, dst); hist.paintHist(dst, true); return 0; }