彩色图像的直方图

来源:互联网 发布:淘宝裂变吸粉 编辑:程序博客网 时间:2024/06/03 00:34

彩色图像的直方图分为rgb三个通道,或者是在其它的颜色空间比如HSV等,只要将图像转换到其它颜色空间就好了。

第一种方法是基于opencv的

void rgbhistogram()
{
 //直方图参数初始化
 int hist_size[] = { 256 };
 float Range[]={0,255};
 float* HistogramRange[]={ Range };
  
 //从源图分别获取RGB三通道图
 IplImage *HistogramImage;
    IplImage* R_plane  = cvCreateImage( cvGetSize(pImg), 8, 1 );
    IplImage* G_plane  = cvCreateImage( cvGetSize(pImg), 8, 1 );
    IplImage* B_plane  = cvCreateImage( cvGetSize(pImg), 8, 1 );
    cvCvtPixToPlane( pImg, R_plane, G_plane, B_plane, 0 );
  
 //建立RGB直方图
 Histogram_R = cvCreateHist( 1, hist_size, CV_HIST_ARRAY, HistogramRange);
 Histogram_G = cvCreateHist( 1, hist_size, CV_HIST_ARRAY, HistogramRange);
 Histogram_B = cvCreateHist( 1, hist_size, CV_HIST_ARRAY, HistogramRange);

 HistogramImage = cvCreateImage(cvSize(256,600),8,3);
 HistogramImage->origin=1;

 //计算RGB直方图
 cvCalcHist(&R_plane,Histogram_R);
 cvCalcHist(&G_plane,Histogram_G);
 cvCalcHist(&B_plane,Histogram_B);
  
 //画RGB直方图
 for(int i=0; i<hist_size[0]; i++)
 {
  cvLine(HistogramImage,cvPoint(i,400),cvPoint(i,(int)(cvQueryHistValue_1D(Histogram_R,i)/30)+400),CV_RGB(255,0,0));
  cvLine(HistogramImage,cvPoint(i,200),cvPoint(i,(int)(cvQueryHistValue_1D(Histogram_G,i)/30)+200),CV_RGB(0,255,0));
  cvLine(HistogramImage,cvPoint(i,0),cvPoint(i,(int)(cvQueryHistValue_1D(Histogram_B,i)/30)),CV_RGB(0,0,255));
 }

 cvNamedWindow("Histogram");
 cvNamedWindow("Source");
 cvShowImage("Source",pImg);
 cvShowImage("Histogram",HistogramImage);
 
 cvWaitKey(0);

 cvDestroyWindow("Histogram");
 cvDestroyWindow("Source");
 
    cvReleaseImage(&R_plane);
    cvReleaseImage(&G_plane);
    cvReleaseImage(&B_plane);
 cvReleaseImage(&HistogramImage);

}

 

第二种方法是直接创建动态数组,通过访问图像的数据将直方图的数据存储到动态数组中,这种方法创建的直方图访问数据比较简单。

所以在直方图均衡化等基本操作中一般采用这种方法。

void rgbhistogram2()
{
 int *b=new int[256];
 int *g=new int[256];
 int *r=new int[256];
 memset(b,0,256*sizeof(int));
 memset(g,0,256*sizeof(int));
 memset(r,0,256*sizeof(int));
    uchar* data = (uchar*)pImg->imageData;
 for(int i=0;i<height;i++)
 {
  for(int j=0;j<width;j++)
  {
   b[data[i*step+j*channel+0]]++;
   g[data[i*step+j*channel+1]]++;
   r[data[i*step+j*channel+2]]++;
  }
 }
 IplImage* HistogramImage = cvCreateImage(cvSize(256,600),8,3);
 HistogramImage->origin=1;

  for(int i=0; i<256; i++)
 {
  cvLine(HistogramImage,cvPoint(i,400),cvPoint(i,(int)r[i]/30+400),CV_RGB(255,0,0));
  cvLine(HistogramImage,cvPoint(i,200),cvPoint(i,(int)g[i]/30+200),CV_RGB(0,255,0));
  cvLine(HistogramImage,cvPoint(i,0),cvPoint(i,(int)b[i]/30),CV_RGB(0,0,255));
 }
 cvNamedWindow("Histogram");
 cvNamedWindow("Source");
 cvShowImage("Source",pImg);
 cvShowImage("Histogram",HistogramImage);
 
 cvWaitKey(0);

 cvDestroyWindow("Histogram");
 cvDestroyWindow("Source");
 cvReleaseImage(&HistogramImage);
}