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;
}