绘制直方图Histogram


个人觉得这个比较麻烦,下一个简单些


#include<opencv2\opencv.hpp>
#include<iostream>

using namespace std;
using namespace cv;

class Historam1D//定义一个专门处理单通道的灰度图的类
{
private:
	int histSize[1];//项的数量
	float hranges[2];//像素的最小及最大值
	const float*ranges[1];
	int channels[1];//仅用到1个通道

public:
	Historam1D()//1D直方图的参数
	{
		histSize[0] = 256;
		hranges[0] = 0.0;
		hranges[1] = 255.0;
		ranges[0] = hranges;
		channels[0] = 0;
	}
	cv::MatND getHistogram(const cv::Mat &image)
	{
		cv::MatND hist;
		//计算直方图
		cv::calcHist(&image, 1, channels, Mat(), hist, 1, histSize, ranges);

		return hist;
	}
	cv::MatND getHistogramImg(const cv::Mat &image)
	{
		//计算直方图
		cv::MatND hist=getHistogram(image);
		//获取最大值与最小值
		//cv::calcHist(&image, 1, channels, Mat(), hist, 1, histSize, ranges);
		double maxVal = 0;
		double minVal = 0;
		cv::minMaxLoc(hist, &minVal, &maxVal, 0, 0);
		//显示直方图图像
		cv::Mat histImg(histSize[0], histSize[0],CV_8U, Scalar(255));
		//设置最高点为nbins的90%
		int hpt = static_cast<int>(0.9*histSize[0]);
		//每个条目都绘制一条垂直线
		for (int h = 0; h < histSize[0]; h++)
		{
			float binVal = hist.at<float>(h);
			int intensity = static_cast<int>(binVal*hpt / maxVal);
			//两点之间绘制一条线
			cv::line(histImg, Point(h, histSize[0]), Point(h, histSize[0] - intensity), Scalar::all(0));
		}
		return histImg;
	}
};

int main()
{
	Mat src = imread("group.jpg",0);

	Historam1D h;
	cv::MatND histo = h.getHistogram(src);

//	for (int i = 0; i < 256; i++ )
//		cout << "Vaule" << i << "=" << histo.at<float>(i) << endl;
	
	namedWindow("Histogram");
imshow("Histogram", h.getHistogramImg(src));//显示直方图
imshow("src", src);

	waitKey(0);
	return 0;
}




这是没用到类的。



#include<opencv2\opencv.hpp>
#include<iostream>

using namespace cv;
using namespace std;
int main()
{
	Mat image = imread("group.jpg", 0);
	if (!image.data){cout << "error" << endl;return 0;}
	MatND hist;       //MatND表示多维矩阵》3维
	int dims = 1;
	float hranges[] = { 0, 255 };
	const float *ranges[] = { hranges };   // 这里需要为const类型  
	int size = 256;
	int channels = 0;

	// 计算图像的直方图  
	calcHist(&image, 1, &channels, Mat(), hist, dims, &size, ranges);   
	Mat imageShow(size , size, CV_8U, Scalar(255));//创建白色背景
	// 获取最大值和最小值  
	double minVal = 0;
	double maxVal = 0;
	minMaxLoc(hist, &minVal, &maxVal, 0, 0);  // minMaxLoc寻找矩阵中最小值和最大值的位置. 
	//显示直方图的图像  
	int hpt = static_cast<int>(0.9 * size);

	for (int i = 0; i < 256; i++)
	{
		float value = hist.at<float>(i);           //   注意hist中是float类型   
		int intensity = static_cast<int>(value * hpt / maxVal);//绘制的高度
	
		//recentangle表示绘制矩形
		rectangle(imageShow, Point(i, size - 1), Point((i + 1) - 1, size - intensity), Scalar(0));
	}
	namedWindow("showImage");
	imshow("showImage", imageShow);
	waitKey(0);
	return 0;
}

二维直方图



#include<opencv2\opencv.hpp>
#include<iostream>

using namespace cv;
using namespace std;
int main()
{
	Mat image = imread("group.jpg", 1);
	if (!image.data)
	{
		cout << "fail to load image" << endl;
		return 0;
	}
	MatND hist;       // 在cv中用CvHistogram *hist = cvCreateHist  
	int dims = 2;
	float r_hranges[] = { 0, 255 };
	float g_hranges[] = { 0, 255 };
	const float *ranges[] = { r_hranges, g_hranges };   // 这里需要为const类型  
	int size[2] = { 256, 256 };
	int channels[] = { 0, 1 };   //代表 r g通道 2代表b通道  
	// 计算图像的直方图  
	calcHist(&image, 1, channels, Mat(), hist, dims, size, ranges);    // cv 中是cvCalcHist  
	int scale = 1;
	Mat imageShow(size[0] * scale, size[1] * scale, CV_8UC3, Scalar(255));
	// 获取最大值和最小值  
	double minVal = 0;
	double maxVal = 0;
	minMaxLoc(hist, &minVal, &maxVal, 0, 0);  
	//显示直方图的图像  
	//int hpt = saturate_cast<int>(0.9 * size[]);  

	for (int i = 0; i < 256; i++)
	{
		for (int j = 0; j < 256; j++)
		{
			float value = hist.at<float>(i, j);           //   注意直方图的值是float类型   
			int realValue = saturate_cast<int>(value * size[0] / maxVal);
		
			rectangle(imageShow, Point(i*scale, j*scale), Point(((i + 1)*scale - 1), (j + 1)*scale - 1), Scalar(realValue, realValue, realValue));
		}
	}
	namedWindow("baboon");
	namedWindow("showImage");
	imshow("showImage", imageShow);
	imshow("baboon", image);
	waitKey(0);
	return 0;

}



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值