藉助OpenCV創建自己的直方圖類--畫出灰度圖像的直方圖


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




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章