歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> 利用OpenCV計算並繪制灰度直方圖

利用OpenCV計算並繪制灰度直方圖

日期:2017/3/1 10:10:34   编辑:Linux編程

下面用兩種方法實現直方圖的計算和繪制,其一用自己實現計算直方圖,其二利用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. }

代碼效果如下

代碼之二

  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. }

代碼效果如下

可見上面兩種方法的結果並無明顯的差異。

通過復用上面的代碼。我們可以得到彩色圖像各通道的直方圖,代碼如下

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

效果圖如下

Copyright © Linux教程網 All Rights Reserved