利用OpenCV计算并绘制灰度直方图

芒果浩明 2012-09-08

下面用两种方法实现直方图的计算和绘制,其一用自己实现计算直方图,其二利用OpenCV提供的库函数计算直方图。代码和算法不难,适合OpenCV初学者学习之用。如有疏漏错误之处,还请各路方家指出。下面使用的测试图是标准的lena图。

代码之一

  1. #include <cv.h>  
  2. #include <highgui.h>  
  3. #pragma comment( lib, "cv.lib" )  
  4. #pragma comment( lib, "cxcore.lib" )  
  5. #pragma comment( lib, "highgui.lib" )   
  6. int main()  
  7. {  
  8.     IplImage* src=cvLoadImage("lena.jpg",0);  
  9.     int width=src->width;  
  10.     int height=src->height;  
  11.     int step=src->widthStep;  
  12.     uchar* data=(uchar *)src->imageData;  
  13.     int hist[256]={0};  
  14.     for(int i=0;i<height;i++)  
  15.     {  
  16.         for(int j=0;j<width;j++)  
  17.         {  
  18.             hist[data[i*step+j]]++;  
  19.         }  
  20.     }  
  21.     int max=0;  
  22.     for(i=0;i<256;i++)  
  23.     {  
  24.         if(hist[i]>max)  
  25.         {  
  26.             max=hist[i];  
  27.         }  
  28.     }  
  29.     IplImage* dst=cvCreateImage(cvSize(400,300),8,3);  
  30.     cvSet(dst,cvScalarAll(255),0);  
  31.     double bin_width=(double)dst->width/256;  
  32.     double bin_unith=(double)dst->height/max;  
  33.     for(i=0;i<256;i++)  
  34.     {  
  35.         CvPoint p0=cvPoint(i*bin_width,dst->height);  
  36.         CvPoint p1=cvPoint((i+1)*bin_width,dst->height-hist[i]*bin_unith);  
  37.         cvRectangle(dst,p0,p1,cvScalar(0,255),-1,8,0);  
  38.     }  
  39.     cvNamedWindow("src",1);  
  40.     cvShowImage("src",src);  
  41.     cvNamedWindow("dst",1);  
  42.     cvShowImage("dst",dst);  
  43.     cvWaitKey(0);   
  44.     cvDestroyAllWindows();  
  45.     cvReleaseImage(&src);  
  46.     cvReleaseImage(&dst);  
  47.     return 0;  
  48. }  

代码效果如下

 

利用OpenCV计算并绘制灰度直方图

 

代码之二

  1. #include <cv.h>  
  2. #include <highgui.h>  
  3. #pragma comment( lib, "cv.lib" )  
  4. #pragma comment( lib, "cxcore.lib" )  
  5. #pragma comment( lib, "highgui.lib" )   
  6. int main()  
  7. {  
  8.     IplImage* src=cvLoadImage("lena.jpg",0);  
  9.     int size=256;  
  10.     float range[]={0,255};  
  11.     float* ranges[]={range};  
  12.     CvHistogram* hist=cvCreateHist(1,&size,CV_HIST_ARRAY,ranges,1);  
  13.     cvCalcHist(&src,hist,0,NULL);  
  14.     float max=0;  
  15.     cvGetMinMaxHistValue(hist,NULL,&max,NULL,NULL);  
  16.     IplImage* dst=cvCreateImage(cvSize(400,300),8,3);  
  17.     cvSet(dst,cvScalarAll(255),0);  
  18.     double bin_width=(double)dst->width/size;  
  19.     double bin_unith=(double)dst->height/max;  
  20.     for(int i=0;i<size;i++)  
  21.     {  
  22.         CvPoint p0=cvPoint(i*bin_width,dst->height);  
  23.         CvPoint p1=cvPoint((i+1)*bin_width,dst->height-cvGetReal1D(hist->bins,i)*bin_unith);  
  24.         cvRectangle(dst,p0,p1,cvScalar(0,255),-1,8,0);  
  25.     }  
  26.     cvNamedWindow("src",1);  
  27.     cvShowImage("src",src);  
  28.     cvNamedWindow("dst",1);  
  29.     cvShowImage("dst",dst);  
  30.     cvWaitKey(0);   
  31.     cvDestroyAllWindows();  
  32.     cvReleaseImage(&src);  
  33.     cvReleaseImage(&dst);  
  34.     return 0;  
  35. }  

代码效果如下

 

利用OpenCV计算并绘制灰度直方图

可见上面两种方法的结果并无明显的差异。

通过复用上面的代码。我们可以得到彩色图像各通道的直方图,代码如下

  1. #include <cv.h>  
  2. #include <highgui.h>  
  3. #pragma comment( lib, "cv.lib" )  
  4. #pragma comment( lib, "cxcore.lib" )  
  5. #pragma comment( lib, "highgui.lib" )   
  6. int main()  
  7. {  
  8.     IplImage* src=cvLoadImage("lena.jpg",1);  
  9.     IplImage* r=cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1);   
  10.     IplImage* g=cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1);   
  11.     IplImage* b=cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1);   
  12.     cvSplit(src,b,g,r,NULL);   
  13.     IplImage* gray = cvCreateImage(cvGetSize(src),8,1);  
  14.     cvCvtColor(src,gray,CV_BGR2GRAY);  
  15.     int size=256;  
  16.     float range[]={0,255};  
  17.     float* ranges[]={range};  
  18.       
  19.     CvHistogram* r_hist = cvCreateHist(1,&size,CV_HIST_ARRAY,ranges,1);  
  20.     CvHistogram* g_hist = cvCreateHist(1,&size,CV_HIST_ARRAY,ranges,1);  
  21.     CvHistogram* b_hist = cvCreateHist(1,&size,CV_HIST_ARRAY,ranges,1);  
  22.     CvHistogram* hist   = cvCreateHist(1,&size,CV_HIST_ARRAY,ranges,1);  
  23.     cvCalcHist(&r,r_hist,0,NULL);  
  24.     IplImage* r_dst=cvCreateImage(cvSize(400,300),8,3);  
  25.     cvSet(r_dst,cvScalarAll(255),0);  
  26.     float r_max=0;  
  27.     cvGetMinMaxHistValue(r_hist,NULL,&r_max,NULL,NULL);  
  28.     double r_bin_width=(double)r_dst->width/size;  
  29.     double r_bin_unith=(double)r_dst->height/r_max;  
  30.     for(int i=0;i<size;i++)  
  31.     {  
  32.         CvPoint p0=cvPoint(i*r_bin_width,r_dst->height);  
  33.         CvPoint p1=cvPoint((i+1)*r_bin_width,r_dst->height-cvGetReal1D(r_hist->bins,i)*r_bin_unith);  
  34.         cvRectangle(r_dst,p0,p1,cvScalar(255,0,0),-1,8,0);  
  35.     }  
  36.     cvCalcHist(&g,g_hist,0,NULL);  
  37.     IplImage* g_dst=cvCreateImage(cvSize(400,300),8,3);  
  38.     cvSet(g_dst,cvScalarAll(255),0);  
  39.     float g_max=0;  
  40.     cvGetMinMaxHistValue(g_hist,NULL,&g_max,NULL,NULL);  
  41.     double g_bin_width=(double)g_dst->width/size;  
  42.     double g_bin_unith=(double)g_dst->height/g_max;  
  43.     for(i=0;i<size;i++)  
  44.     {  
  45.         CvPoint p0=cvPoint(i*g_bin_width,g_dst->height);  
  46.         CvPoint p1=cvPoint((i+1)*g_bin_width,g_dst->height-cvGetReal1D(g_hist->bins,i)*g_bin_unith);  
  47.         cvRectangle(g_dst,p0,p1,cvScalar(0,255,0),-1,8,0);  
  48.     }  
  49.     cvCalcHist(&b,b_hist,0,NULL);  
  50.     IplImage* b_dst=cvCreateImage(cvSize(400,300),8,3);  
  51.     cvSet(b_dst,cvScalarAll(255),0);  
  52.     float b_max=0;  
  53.     cvGetMinMaxHistValue(b_hist,NULL,&b_max,NULL,NULL);  
  54.     double b_bin_width=(double)b_dst->width/size;  
  55.     double b_bin_unith=(double)b_dst->height/b_max;  
  56.     for(i=0;i<size;i++)  
  57.     {  
  58.         CvPoint p0=cvPoint(i*b_bin_width,b_dst->height);  
  59.         CvPoint p1=cvPoint((i+1)*b_bin_width,b_dst->height-cvGetReal1D(b_hist->bins,i)*b_bin_unith);  
  60.         cvRectangle(b_dst,p0,p1,cvScalar(0,0,255),-1,8,0);  
  61.     }  
  62.     cvCalcHist(&gray,hist,0,NULL);  
  63.     IplImage* gray_dst=cvCreateImage(cvSize(400,300),8,3);  
  64.     cvSet(gray_dst,cvScalarAll(255),0);  
  65.     float max=0;  
  66.     cvGetMinMaxHistValue(hist,NULL,&max,NULL,NULL);  
  67.     double bin_width=(double)gray_dst->width/size;  
  68.     double bin_unith=(double)gray_dst->height/max;  
  69.     for(i=0;i<size;i++)  
  70.     {  
  71.         CvPoint p0=cvPoint(i*bin_width,gray_dst->height);  
  72.         CvPoint p1=cvPoint((i+1)*bin_width,gray_dst->height-cvGetReal1D(hist->bins,i)*bin_unith);  
  73.         cvRectangle(gray_dst,p0,p1,cvScalar(0),-1,8,0);  
  74.     }  
  75.     IplImage* dst=cvCreateImage(cvSize(800,600),8,3);  
  76.     cvSetZero(dst);  
  77.     CvRect rect = cvRect(0, 0, 400, 300);   
  78.     cvSetImageROI(dst, rect);   
  79.     cvCopy(r_dst, dst);   
  80.     rect = cvRect(400, 0, 400, 300);  
  81.     cvSetImageROI(dst, rect);   
  82.     cvCopy(g_dst, dst);  
  83.     rect = cvRect(0, 300, 400, 300);  
  84.     cvSetImageROI(dst, rect);   
  85.     cvCopy(b_dst, dst);  
  86.     rect = cvRect(400, 300, 400, 300);  
  87.     cvSetImageROI(dst, rect);   
  88.     cvCopy(gray_dst, dst);  
  89.     cvResetImageROI(dst);  
  90.     cvNamedWindow("src",1);  
  91.     cvShowImage("src",src);  
  92.     cvNamedWindow("dst",1);  
  93.     cvShowImage("dst",dst);  
  94.     cvSaveImage("dst.jpg",dst);  
  95.     cvWaitKey(0);   
  96.     cvDestroyAllWindows();  
  97.     cvReleaseImage(&src);  
  98.     cvReleaseImage(&dst);  
  99.     cvReleaseImage(&r);  
  100.     cvReleaseImage(&g);  
  101.     cvReleaseImage(&b);  
  102.     cvReleaseImage(&gray);  
  103.     cvReleaseImage(&r_dst);  
  104.     cvReleaseImage(&g_dst);  
  105.     cvReleaseImage(&b_dst);  
  106.     cvReleaseImage(&gray_dst);  
  107.     return 0;  
  108. }  

效果图如下

 

利用OpenCV计算并绘制灰度直方图

相关推荐