1.把彩***像分成3个图像(cvSplit)

2.创建直方图并且分配内存(CvHistogram* hist=cvCreateHist)

3.读取图像的直方图,把数据存放在直方图结构体中(cvCapcHist)

4.读取直方图结构体中每个值的点数(cvQueryHistValue_1D)

5.描点,画图(cvPoint,cvFillConvexPoly)

直方图的其它操作:

1.cvNorMalizeHist(CvHistogram* hist,double factor)

归一化直方图,factor表示直方图归一化后的数字

2.cvThreshHist(CvHistogram* hist,double factor);

factor是一个开关阀值,小于该阀值的各个bin的值都被设为0

3.void cvCopyHist(const CvHistogram* src,CvHistogram** dst);

复制一个直方图的信息到另一个直方图,如果设置*dst为NULL,那么生成一个与src一样大小的新直方图,*dst被分配给一个指向新分配的直方图的指针

4.cvGetMinMaxHistValue(const CvHistogram* hist,float* min_value,float* max_value,int min_idx=NULL,int max_idx=NULL)

求直方图hist中的最小最大值及其索引

5.cvCalcHist(IplImage** p_w_picpath,CvHistogram* hist,int accumulate=0,const CvArr* mask=NULL);

从图像中自动计算直方图,图像要转换为单通道图像,accumulate如果非零,表示直方图hist在读入图像之前没有被清零,允许cvCalcHist()在一个数据采集循环中被多次调用,mask如果非零,则只有与mask非零元素对应

6.double cvCompareHist(const CvHistogram* hist1,const CvHistogram*  hist2,int method)

比较两个大小相同的直方图的相似度

程序1(自己):

#include "cv.h"#include "cxcore.h"#include "highgui.h"IplImage* cvDrawHist(IplImage *p_w_picpath,int x=1,int y=1){int dim=1;int size=256;float range[]={0,255};float *ranges[]={range};  //数组的个数等于维数,这里是一维CvHistogram *hist=cvCreateHist(dim,&size,CV_HIST_ARRAY,ranges,1);cvClearHist(hist);cvCalcHist(&p_w_picpath,hist);float max=0;cvGetMinMaxHistValue(hist,NULL,&max);IplImage *HistImage=cvCreateImage(cvSize(256*x,64*y),8,1);cvZero(HistImage);CvPoint pts[5];for(int i=0;i<255;i++){float num=cvQueryHistValue_1D(hist,i);float nextnum=cvQueryHistValue_1D(hist,i+1);pts[0]=cvPoint(i*x,0);pts[1]=cvPoint((i+1)*x,0);pts[2]=cvPoint((i+1)*x,64*y-nextnum/max*64*y);pts[3]=cvPoint(i*x,64*y-num/max*64*y);pts[4]=cvPoint(i*x,0);cvFillConvexPoly(HistImage,pts,5,cvScalar(255));}return HistImage;}void main(){IplImage *src=cvLoadImage("c:\\1.jpg");cvNamedWindow("src");cvShowImage("src",src);IplImage *red=cvCreateImage(cvGetSize(src),8,1);IplImage *green=cvCreateImage(cvGetSize(src),8,1);IplImage *blue=cvCreateImage(cvGetSize(src),8,1);cvSplit(src,red,green,blue,NULL);cvNamedWindow("red");cvNamedWindow("green");cvNamedWindow("blue");cvShowImage("red",red);cvShowImage("green",green);cvShowImage("blue",blue);IplImage *r_hist=cvDrawHist(red);IplImage *b_hist=cvDrawHist(blue);IplImage *g_hist=cvDrawHist(blue);cvNamedWindow("r_hist");cvNamedWindow("g_hist");cvNamedWindow("b_hist");cvShowImage("r_hist",r_hist);cvShowImage("g_hist",b_hist);cvShowImage("b_hist",g_hist);cvWaitKey(0);cvDestroyWindow("red");cvReleaseImage(&red);cvDestroyWindow("green");cvReleaseImage(&green);cvDestroyWindow("blue");cvReleaseImage(&blue);cvDestroyWindow("r_hist");cvReleaseImage(&r_hist);cvDestroyWindow("g_hist");cvReleaseImage(&g_hist);cvDestroyWindow("b_hist");cvReleaseImage(&b_hist);}

程序2:

#include "cv.h"#include "cxcore.h"#include "highgui.h"//绘制直方图IplImage* DrawHistogram(CvHistogram* hist , float scaleX = 1 , float scaleY = 1){        //获取直方图中极大值        float histMax = 0;        cvGetMinMaxHistValue(hist , 0 ,&histMax ,0 ,0);        //创建图像 该图像用于显示直方图        IplImage* imgHist = cvCreateImage(cvSize(256*scaleX , 64*scaleY) , 8 ,1);        //图像置零        cvZero(imgHist);        //依次绘制直方图的bin        for(int i=0;i<255;i++)        {                //获取直方图的值                float histValue = cvQueryHistValue_1D(hist , i);                float nextValue = cvQueryHistValue_1D(hist , i+1);                //获取四边形的四个点的坐标  详情请观看视频的讲解                CvPoint pt1 = cvPoint(      i*scaleX , 64*scaleY);                CvPoint pt2 = cvPoint(  (i+1)*scaleX , 64*scaleY);                CvPoint pt3 = cvPoint(  (i+1)*scaleX , (64 - (nextValue/histMax)*64) *scaleY );                CvPoint pt4 = cvPoint (      i*scaleX , (64 - (histValue/histMax)*64) *scaleY );                int numPts = 5;                CvPoint pts[5];                pts[0] = pt1;                pts[1] = pt2;                pts[2] = pt3;                pts[3] = pt4;                pts[4] = pt1;                //填充四边形                cvFillConvexPoly(imgHist , pts ,numPts , cvScalar(255));        }        return imgHist;}int main(int argc, char* argv[]){        //加载图像        IplImage* src = cvLoadImage("c:\\1.jpg");                cvNamedWindow("sr");        cvShowImage("sr" , src);        int dims = 1;  // 一维直方图        int size =256; //bin的个数        float range[] = {0,255}; //取值范围        float* ranges[] = {range};        CvHistogram* hist;        //创建直方图        hist = cvCreateHist(dims , &size , CV_HIST_ARRAY ,  ranges , 1 );        //清空直方图        cvClearHist(hist);        //给B  G  R 三个通道的图像分配空间        IplImage* imgRed = cvCreateImage(cvGetSize(src) , 8 ,1);        IplImage* imgGreen = cvCreateImage(cvGetSize(src) , 8 ,1);        IplImage* imgBlue = cvCreateImage(cvGetSize(src) , 8 ,1);        //将图像src  分解成B   G   R 三个通道        cvSplit(src , imgBlue , imgGreen , imgRed , NULL);        //计算B通道 直方图        cvCalcHist(&imgBlue , hist , 0 , 0 );        //绘制B通道直方图  结果保存在histBlue        IplImage* histBlue = DrawHistogram(hist);        //将B通道的直方图数据清空        cvClearHist(hist);        //计算G通道直方图        cvCalcHist(&imgGreen , hist , 0 , 0 );        //绘制G通道直方图  histGreen        IplImage* histGreen = DrawHistogram(hist);        //将G通道的直方图数据清空        cvClearHist(hist);        //计算R通道 直方图        cvCalcHist(&imgRed , hist , 0 , 0 );        //绘制R通道直方图  histRed        IplImage* histRed = DrawHistogram(hist);        //将R通道的直方图数据清空        cvClearHist(hist);        cvNamedWindow("B");        cvNamedWindow("G");        cvNamedWindow("R");        cvShowImage("B"  , histBlue);        cvShowImage("G"  , histGreen);        cvShowImage("R"  , histRed);        cvWaitKey(0);        //释放资源        //(1) 释放源图像        cvReleaseImage(&src);        //(2) 释放三个通道的图像        cvReleaseImage(&imgRed);        cvReleaseImage(&imgGreen);        cvReleaseImage(&imgBlue);        //(3)释放三个通道直方图        cvReleaseImage(&histBlue);        cvReleaseImage(&histGreen);        cvReleaseImage(&histRed);        //(4)释放直方图空间        cvReleaseHist(&hist);        return 0;}