灰度直方图的原理和计算

一、灰度直方图的认识

  我们平时看到的灰度图像是由0到255个像素组成的,像素是组成图像的基本单位,灰度直方图就是灰度图像素值的直观体现,其中bins就是衣服灰度图直方图的条数。

                                                  灰度直方图的原理和计算_第1张图片


                                     灰度直方图的原理和计算_第2张图片

二、程序1

原理大家去百度吧,在这就不具体说了。

程序中涉及到血多opencv函数,我下面简单介绍一些:

1.计算直方图:

void calcHist(const Mat* arrays, int narrays, const int* channels, InputArray mask, OutputArray
  hist, int dims, const int* histSize, const float** ranges, bool uniform=true, bool accumulate=
  false );
分别表示:输入图像、输入图像的维数、输入图像的通道数、掩膜、输出直方图、输出维数、输出直方图的bins数等。

2.球直方图最大、最小块,也即是找最大和最小的bins

void minMaxLoc( const Mat& src,double* minVal,double* maxVal=0,Point* minLoc=0,Point* maxLoc=0,const Mat& mask=Mat() ); 
3.在图像中画矩形

void cvRectangle( CvArr* img, CvPoint pt1, CvPoint pt2, CvScalar color,
                  int thickness=1, int line_type=8, int shift=0 );
分别表示:原图像、左上角坐标、右下角坐标等

好,开始贴代码:

#include   
#include   
#include   
using namespace cv;
using namespace std;
int main()
{
	Mat src, gray;
	src = imread("D:\\vvoo\\lena.jpg");
	cvtColor(src, gray, CV_RGB2GRAY);

	int bins = 256;//一维直方图bins  
	int hist_size[] = { bins };

	float range[] = { 0, 256 };//直方图每一个bins的范围  
	const float* ranges[] = { range };
	MatND hist;//输出直方图  

	int channels[] = { 0 };//一维通道  

	//创建并计算直方图  
	calcHist(&gray, 1, channels, Mat(), // do not use mask  
		hist, //输出直方图  
		1, hist_size,
		ranges,
		true, // the histogram is uniform  
		false);

	double max_val;
	minMaxLoc(hist, 0, &max_val, 0, 0);//找出最大的bins值  
	int scale = 2;//bins之间的距离为2  
	int hist_height = 300;//输出直方图的高度  

	Mat hist_img = Mat::zeros(hist_height, bins*scale, CV_8UC3);//定义hist_img的矩阵,高度为hist_height,宽度为bins*scale  

	for (int i = 0; i(i);

		int intensity = cvRound(bin_val*hist_height / max_val);  //归一化,要绘制的高度,从上往下数  

		rectangle(hist_img, Point(i*scale, hist_height/* - 1*/),
			Point((i + 1)*scale - 1, hist_height - intensity),
			CV_RGB(0, 255, 255));
	}
	imshow("Source", src);
	imshow("Gray Histogram", hist_img);
	waitKey(500000);
	return 0;
}

运行结果:

原图

灰度直方图的原理和计算_第3张图片

直方图

灰度直方图的原理和计算_第4张图片

三、程序2(滑动块控制量化位数)

是对程序1进行稍微更改:

滑动块函数:

CreateTrackbar(
const char* trackbar_name, //滑动条的名称
const char* window_name, //窗口的名称,滑动条不会遮挡图像
int* value, //当滑动条被拖到时,OpenCV会自动将当前位置所代表的值传给指针指向的整数
int count, //滑动条所能达到的最大值
CvTrackbarCallback on_change //可选的回调函数,回调函数可参见http://wapedia.mobi/zhtrad/回调函数
);

程序2:

#include 
#include 
using namespace cv;
using namespace std;

Mat srcImage, gray;
int bins = 200;
#define hist_height 500//输出直方图的高度  
#define hist_width  800

static void showHelpText();
static void HIST(int, void*);


int main()
{
	showHelpText();
	system("color 4d");
	srcImage = imread("D:\\vvoo\\lena.jpg");

	if (!srcImage.data)
	{
		cout << "the image is error !" << endl;
		return 0;
	}
	namedWindow("srcIamge");
	imshow("srcIamge", srcImage);
	cvtColor(srcImage, gray, CV_RGB2GRAY);

	//调用
	createTrackbar("bins", "srcIamge", &bins, 256, HIST);
	HIST(0, 0);

	while ((char(waitKey(1)) != 'q'))//q键退出
	{
	}
	waitKey(0);
	return 0;
}
static void HIST(int, void*)
{
	int hist_size[] = { bins };

	float range[] = { 0, 256 };//直方图每一个bins的范围  
	const float* ranges[] = { range };
	MatND hist;//输出直方图  

	int channels[] = { 0 };//一维通道  

	//创建并计算直方图  
	calcHist(&gray, 1, channels, Mat(), // do not use mask  
		hist, //输出直方图  
		1, hist_size,
		ranges,
		true, // the histogram is uniform  
		false);

	double max_val;
	minMaxLoc(hist, 0, &max_val, 0, 0);//找出最大的bins值  


	Mat hist_img = Mat::zeros(hist_height, hist_width, CV_8UC3);//定义hist_img的矩阵  

	double bin_w = (double)hist_width / bins;  //bins为直方图条的个数,则 bin_w 为条的宽度  

	for (int i = 0; i(i);

		int intensity = cvRound(bin_val*hist_height / max_val);  //归一化,要绘制的高度,从上往下数  

		rectangle(hist_img, Point(i*bin_w, hist_height),
			Point((i + 1)*bin_w, hist_height - intensity),
			CV_RGB(255, 0, 255));
	}
	imshow("一维直方图", hist_img);
}
static void showHelpText()
{
	cout << "通过滑块调节直方图量化的条数" << endl;
}

结果:

灰度直方图的原理和计算_第5张图片

四、参考资料

1.点击打开链接

http://blog.csdn.net/sxhelijian/article/details/8042507

2.灰度直方图

你可能感兴趣的:(图像处理基本知识,Opencv常用函数介绍)