<span style="font-family: Arial, Helvetica, sans-serif;">typedef struct CvHistogram</span>
{
int type;
CvArr* bins;
float thresh[CV_MAX_DIM][2]; /* For uniform histograms. */
float** thresh2; /* For non-uniform histograms. */
CvMatND mat; /* Embedded matrix header for array histograms. */
}
CvHistogram;
/* Creates new histogram */
CVAPI(CvHistogram*) cvCreateHist( int dims, int* sizes, int type,
float** ranges CV_DEFAULT(NULL),
int uniform CV_DEFAULT(1));
dims:直方图包含的维数 灰度直方图为1维
sizes:size数组的长度为dims,每个数表示分配给对应维数的bin的个数。如dims=3,则size中用[s1,s2,s3]分别指定每维bin的个数。
type:CV_HIST_ARRAY(默认),用来表示使用密集多维矩阵结构(如CvMatND)存储多维直方图;CV_HIST_SPARSE
ranges:取值范围
CV_INLINE void cvCalcHist( IplImage** image, CvHistogram* hist,
int accumulate CV_DEFAULT(0),
const CvArr* mask CV_DEFAULT(NULL) )
计算直方图
/* Normalizes histogram by dividing all bins by sum of the bins, multiplied by <factor>.
After that sum of histogram bins is equal to <factor> */
CVAPI(void) cvNormalizeHist( CvHistogram* hist, double factor );
归一化直方图
factor表示直方图归一化后的数值(通常情况下设为1)/* Finds indices and values of minimum and maximum histogram bins */
CVAPI(void) cvGetMinMaxHistValue( const CvHistogram* hist,
float* min_value, float* max_value,
int* min_idx CV_DEFAULT(NULL),
int* max_idx CV_DEFAULT(NULL));
输出直方图中找到的最小值和最大值
/* Retrieves value of the particular bin
of x-dimensional (x=1,2,3,...) histogram */
#define cvQueryHistValue_1D( hist, idx0 ) \
((float)cvGetReal1D( (hist)->bins, (idx0)))
#define cvQueryHistValue_2D( hist, idx0, idx1 ) \
((float)cvGetReal2D( (hist)->bins, (idx0), (idx1)))
#define cvQueryHistValue_3D( hist, idx0, idx1, idx2 ) \
((float)cvGetReal3D( (hist)->bins, (idx0), (idx1), (idx2)))
#define cvQueryHistValue_nD( hist, idx ) \
((float)cvGetRealND( (hist)->bins, (idx)))
访问直方图数据 每个函数都返回相应bin中的值的浮点数
##################################################
程序:生成灰度直方图
//Draw a grayImage histogram
//
void drawGrayImage(void)
{
IplImage *img=cvLoadImage("lena.jpg", CV_LOAD_IMAGE_GRAYSCALE);
if (img == NULL)
exit(0);
int dims=1; //创建一维直方图
int sizes[]={256}; //共有256个取值范围
int type=CV_HIST_ARRAY; //表示使用密集多维矩阵结构
float range[]={0, 255}; //取值范围为0-255
float *ranges[]={range};
CvHistogram *hist=NULL;//创建直方图的空指针结构
hist=cvCreateHist(dims, sizes, type, ranges, 1);//创建直方图
cvCalcHist(&img, hist, 0, NULL); //统计直方图
cvNormalizeHist(hist, 1.0); //归一化直方图
int hist_height=256; //直方图高度
int hist_size=256; //直方图尺寸
int scale=2;
//创建一张一维直方图的“图”,横坐标为灰度级,纵坐标为像素个数(*scale) 彩色图像
IplImage *hist_image=cvCreateImage(cvSize((hist_size*scale), hist_height), IPL_DEPTH_8U, 3);
if (hist_image == NULL)
exit(0);
cvZero(hist_image);
float max=0; //直方图中的最大值
cvGetMinMaxHistValue(hist, 0, &max, NULL, NULL);
for (int i=0; i<hist_size; i++)
{
float val=cvQueryHistValue_1D(hist, i);
int intensity=cvRound(hist_height*val/max);
cvRectangle(hist_image, cvPoint(i*scale, hist_height-1), cvPoint((i+1)*scale-1, hist_height-intensity-1), CV_RGB(255, 255, 255), -1, 8, 0);
}
cvNamedWindow("img");
cvNamedWindow("hist_image");
cvShowImage("img", img);
cvShowImage("hist_image", hist_image);
cvWaitKey(0);
cvDestroyAllWindows();
cvReleaseImage(&img);
cvReleaseImage(&hist_image);
}
##########################################################
程序:生成多通道一维颜色直方图
//draw multi channels hist image
//
void drawHistImage(void)
{
IplImage *img=cvLoadImage("lena.jpg");
IplImage *channel_1=cvCreateImage(cvGetSize(img), img->depth, 1);
IplImage *channel_2=cvCreateImage(cvGetSize(img), img->depth, 1);
IplImage *channel_3=cvCreateImage(cvGetSize(img), img->depth, 1);
if (NULL == img || NULL == channel_1 || NULL == channel_2 || NULL == channel_3)
exit(0);
cvSplit(img, channel_1, channel_2, channel_3, NULL);
int dims=1;
int sizes[]={256};
int type=CV_HIST_ARRAY;
float range[]={0, 255};
float *ranges[]={range};
CvHistogram *hist1=NULL;
CvHistogram *hist2=NULL;
CvHistogram *hist3=NULL;
CvHistogram *hist4=NULL;
hist1=cvCreateHist(dims, sizes, type, ranges, 1);
hist2=cvCreateHist(dims, sizes, type, ranges, 1);
hist3=cvCreateHist(dims, sizes, type, ranges, 1);
cvCalcHist(&channel_1, hist1, 0, NULL);
cvCalcHist(&channel_2, hist2, 0, NULL);
cvCalcHist(&channel_3, hist3, 0, NULL);
cvNormalizeHist(hist1, 1.0);
cvNormalizeHist(hist2, 1.0);
cvNormalizeHist(hist3, 1.0);
int scale=1;
int hist_size=256;
int hist_height=256;
IplImage *hist_image=cvCreateImage(cvSize(hist_size*scale*3, hist_height), IPL_DEPTH_8U, 3);
if (hist_image == NULL)
exit(0);
cvZero(hist_image);
float max1=0;
float max2=0;
float max3=0;
cvGetMinMaxHistValue(hist1, 0, &max1, NULL, NULL);
cvGetMinMaxHistValue(hist2, 0, &max2, NULL, NULL);
cvGetMinMaxHistValue(hist3, 0, &max3, NULL, NULL);
for (int i=0; i<hist_size; i++)
{
float val1=cvQueryHistValue_1D(hist1, i);
float val2=cvQueryHistValue_1D(hist2, i);
float val3=cvQueryHistValue_1D(hist3, i);
int intensity1=cvRound(val1*hist_height/max1);
int intensity2=cvRound(val2*hist_height/max2);
int intensity3=cvRound(val3*hist_height/max3);
cvRectangle(hist_image, cvPoint(i*scale, hist_height-1), cvPoint((i+1)*scale-1, hist_height-1-intensity3), CV_RGB(255, 0, 0), -1, 8, 0);
cvRectangle(hist_image, cvPoint(i*scale+hist_size, hist_height-1), cvPoint((i+1)*scale-1+hist_size, hist_height-1-intensity2), CV_RGB(0, 255, 0), -1, 8, 0);
cvRectangle(hist_image, cvPoint(i*scale+hist_size*2, hist_height-1), cvPoint((i+1)*scale-1+hist_size*2, hist_height-1-intensity1), CV_RGB(0, 0, 255), -1, 8, 0);
}
cvNamedWindow("channel1", 0);
cvNamedWindow("channel2", 0);
cvNamedWindow("channel3", 0);
cvResizeWindow("channel1", 200, 200);
cvResizeWindow("channel2", 200, 200);
cvResizeWindow("channel3", 200, 200);
cvNamedWindow("hist_image");
cvShowImage("channel3", channel_1);
cvShowImage("channel2", channel_2);
cvShowImage("channel1", channel_3);
cvShowImage("hist_image", hist_image);
cvWaitKey(0);
}
参考:http://blog.csdn.net/morewindows/article/details/8364656
http://blog.csdn.net/xiaowei_cqu/article/details/7600666