OpenCV之单通道图像的直方图绘制

      在分析图像的时候我们经常会用直方图来表示各种色彩分布、边缘梯度、分布概率等等事情。所谓的直方图就是对数据进行统计。

     下面介绍一下直方图常用的函数

       创建直方图

CvHistogram*  cvCreateHist(

int  dims,                               //直方图维数

int* sizes,                //维数尺寸

int   type,   //直方图的形式

float**   ranges=null,     //取值的上下界

int  uniform=1   //判断直方图是否均匀

)

CvHistogram是直方图的数据结构

首先要了解直方图里bin的含义。对数据进行统计的统计值会组织到事先定义好的bin中,bin的数值是从数据中计算出特征的统计量。看了之后你可能还是不太懂,没关系先放着继续往下看。

dims:表示直方图的维数。

为了更好的理解这个函数,我先说明ranges的意思,ranges:表示灰度级取值的上下界,则在直方图里显示的横坐标的范围是定义的上下界。

uniform:表示直方图的类型,非0值表示均匀直方图,0表示不均匀直方图。均匀就是将ranges平均分配,即直方图里每一段矩形的宽是一样的。

sizes:为整数数组,数组的长度等于dims,即一维直方图只有一个值,二维直方图有两个值存放在数组里。数组中的每一个整数表示分配给对应维数的bin的个数。例如ranges的上下界分别设置为0和20,相应维数的size等于5,并且是均匀直方图,则bin将被指定为[0,4]、[4,8]、[8,12]、[12,16]、[16,20]。如果是非均匀直方图,在size等于5的情况下如设置相应的区间(0,6,8,10,14,20),则bin将被指定为[0,6]、[6,8]、[8,10]、[10,14]、[14,20]。

type:两种形式。CV_HIST_ARRAY用来表示使用密集多维矩阵结构存储多维直方图。CV_HIST_SPARSE表示数据用稀疏矩阵存储。

直方图归一化

cvNormalizeHist(CvHistogram* hist, double factor)

hist表示直方图,factor表示直方图归一化后的数值,通常为1


直方图最大值和最小值

void  cvGetMinMaxHistValue(

const CvHistogram*  hist,              //直方图

float*                               min_value,        //最小值

float*                               max_value,     //最大值

int*                               min_idx=NULL,  //最小值索引值

int*                               min_idx=NULL,   //最大值索引值

)

hist为指定直方图,*min_value和*max_value设置为最小值和最大值,剩下的两个参数是可选的,如果不是NULL的指针,则返回最小和最大值的索引值,参数min_idx和max_idx被设为指向一个整数数组的指针,我将其理解为指向的是上面介绍过的sizes,假如一个直方图里有很多的bin值都是最值,则返回最小索引的bin。


计算直方图

void  cvCalcHist(

IplImage**    image,                //输入图像

CvHistogram*   hist,               //直方图

int                 accumulate=0,     //判断直方图在读入图像之前是够清零

const  CvArr*     mask=NULL,  //可选的布尔变量

)

此函数所接受的图像都被要求为单通道图像,主要是为了避免要确定多通道图像的混淆,包含多通道的多个图像需要确定谁在哪儿用这些图像的哪个通道

直方图绘制的思路:如果是单通道图像,利用cvCreateHist来创建直方图,用CalcHist来计算直方图,cvNormalizeHist来进行直方图归一化,接着创建一幅放直方图的图像,用cvGetMinMaxHistValue来统计最小最大值,然后在创建的图像里绘制直方图,调用cvRectangle来画矩形。

一维直方图代码如下:

#include"cv.h"
#include"highgui.h"
int main()
{
	IplImage * src = cvLoadImage("D://321.jpg");
	IplImage* gray_plane = cvCreateImage(cvGetSize(src), 8, 1);
	cvCvtColor(src, gray_plane, CV_BGR2GRAY);                 //RGB图像转换成灰度图

	int hist_size = 256;    //直方图尺寸  
	int hist_height = 256;
	float range[] = { 0, 255 };  //灰度级的范围  
	float* ranges[] = { range };
	
	CvHistogram* gray_hist = cvCreateHist(1, &hist_size, CV_HIST_ARRAY, ranges, 1);    //创建一维直方图,统计图像在[0 255]像素的均匀分布  
	
	cvCalcHist(&gray_plane, gray_hist, 0, 0);        //计算灰度图像的一维直方图 此函数被要求为单通道图像
	
	cvNormalizeHist(gray_hist, 1.0);      //归一化直方图  

	int scale = 2;           //比例系数
	  
	IplImage* hist_image = cvCreateImage(cvSize(hist_size*scale, hist_height), 8, 3);//创建一张一维直方图的图,横坐标为灰度级,纵坐标为像素个数(*scale)
	cvZero(hist_image);
	
	float max_value = 0;       
	cvGetMinMaxHistValue(gray_hist, 0, &max_value, 0, 0);      //统计直方图中的最大直方块 

	//分别将每个直方块的值绘制到图中  
	for (int i = 0; i<hist_size; i++)
	{
		float bin_val = cvQueryHistValue_1D(gray_hist, i); //像素i的概率   cvQueryHistValue_1D返回的是浮点数 
		int intensity = cvRound(bin_val*hist_height / max_value);  //要绘制的高度  cvRound:对数进行四舍五入 返回整型
		cvRectangle(hist_image,
			cvPoint(i*scale, hist_height - 1),
			cvPoint((i + 1)*scale - 1, hist_height - intensity),
			CV_RGB(255, 255, 255));            //用白色绘制矩形
	}
	cvNamedWindow("GraySource", 1);
	cvShowImage("GraySource", gray_plane);
	cvNamedWindow("H-S Histogram", 1);
	cvShowImage("H-S Histogram", hist_image);

	cvWaitKey(0);
}


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值