借助OpenCV创建自己的直方图类--画出灰度图像的直方图

借助OpenCV创建自己的直方图类--画出灰度图像的直方图_第1张图片

借助OpenCV创建自己的直方图类--画出灰度图像的直方图_第2张图片

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




你可能感兴趣的:(opencv,直方图)