用一维数组画直方图(1)

                                                           用一维数组画直方图(1)

      摘要:此次实验主要是学习用一维数组画直方图,直方图是对数据进行统计,将统计值组织到一个事先定义好的bin中,bin中的数值是从数据中计算出来的特征统计量,这些数据可以是诸如阶梯方向,色彩或其他特征。即直方图获得的是数据分布的统计图。通常直方图的维数要低于原始数据。


主要的数据结构如下:

CvHistogram

多维直方图

typedef struct CvHistogram{

   int type;

   CvArr*bins:  存放直方图在每一  维直方柱上的具体数据,由于存在多维直方图。如果是一维直方图,那么bins就是一个一维的矩阵;

如果是二维直方图,那么bins就是一个二维的矩阵,等等;

   float thresh【CV_MAX_DIM[2];直方柱的划分是统一划分的,即均等划分;

   float **thresh2;不均等划分,可以自定义每一个直方柱的取值范围。

   CvMatND mat; 存直方图的数据。

}


CvHistigram*cvGreatHist(int dims,int*sizes,int type,float**ranges=NULL,int unifrom=1);

{

dims:表示直方图的维度

sizes:每一维直方柱(bin)的数据;

直方图存取数据方式

CV_HIST_ARRAY  直方图数据表示为多维密集数组CvMatND;

CV_HIST_TREE     直方图数据表示为多维稀散数组CvSpareMat;

ranges:直方图在每一维度上的范围

uniform:该值为0时,表示bin的范围可自由设定。

}



部分代码如下:

//画直方图
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);//置零
for (int i = 0; i < 255; i++) {
float histValue = cvQueryHistValue_1D(hist, i);
float nextValue = cvQueryHistValue_1D(hist, i + 1);

               //计算每个柱条的四个点
CvPiont pt1 = cvPiont(i*scaleX, 64 * scaleY);
CvPiont pt2 = cvPiont((i + 1)*scaleX, 64 * scaleY);
CvPiont pt3 = cvPiont((i + 1)*scaleX,( 64 - (nextValue / histMax) * 64) * scaleY);
CvPiont pt4 = cvPiont(i*scaleX, (64 - (nextValue / histMax) * 64 )* scaleY);

              //各点的连接(每四点连接起来就是一个四边形,也就是一个直方柱)
int numPts = 5;
CvPiont 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 dims = 1;
int size = 256;
float range[i] = { 0,255 };
float*ranges[] = { range };//方便同时创建多个维数的直方图,所以用二维指针
CvHistogram *hist;
hist=cvCreateHist(dims, &size, CV_HIST_ARRAY, ranges, 1);
cvClearHist(hist);
IplImage*imgRed = cvCreateImage(cvGetSize(src), 8, 1);
IplImage*imgGreen = cvCreateImage(cvGetSize(src), 8, 1);
IplImage*imgBlue = cvCreateImage(cvGetSize(src), 8, 1);
cvSplit(src, imgBlue, imgGreen, imgRed, NULL);//把原图分为三个单通道的图像
//计算直方图
cvCalcHist(&imgBlue, hist, 0, 0);
IplImage*histBlue = DrawHistogram(hist);
cvClearHist(hist);


cvCalcHist(&imgGreen, hist, 0, 0);

IplImage*histGreen = DrawHistogram(hist);
cvClearHist(hist);


cvCalcHist(&imgRed, hist, 0, 0);
IplImage*histRed = DrawHistogram(hist);
cvClearHist(hist);

}




    实验小结:实验运行的结果不是很理想,有一些内容有待改进。



   参考文献:大学生自学网——OpenCv的学习





猜你喜欢

转载自blog.csdn.net/HHCCWWlxy/article/details/79584431