当前位置:   article > 正文

Opencv绘制HSV颜色直方图_opencv hsv 直方图

opencv hsv 直方图

一. 使用Opencv绘制HSV颜色直方图

所用的函数

cvCvtColor

可在: 使用Opencv将RGB颜色空间转换到HSV颜色空间/灰度图 文章中查找相关介绍

所使用的结构体:

CvHistogram 

以及函数:

cvCalcHist
CvCreateHist
cvGetMinMaxHistValue
cvConvertScale
cvReleaseHist

可在: 使用Opencv绘制灰度直方图/对比 文章中查找对应的函数介绍

 

1. 开始编写代码

准备一张实验图

如有需要,自行保存到本地,JPG格式!

1.1 打开测试图

1.2 创建三个用来分别绘制H,S,V的直方图

  1. //打开测试图
  2. IplImage * image = cvLoadImage("D:\\2.jpg", 1); //将本地测试图导入到程序堆中
  3. if (image == NULL){ //判断是否打开成功
  4. printf("错误:无法打开该图像,图像文件路径不正确!");
  5. return -1;
  6. }

1.3 RGB颜色空间到HSV颜色空间转换

  1. //创建一张空白图像用于存储转换成HSV颜色空间后的图像
  2. IplImage *image1 = cvCreateImage(cvSize(image->width, image->height), image->depth, image->nChannels); //注意图像必须和输入图像的size,颜色位深度,通道一致
  3. cvZero(image1); //清空image_data数据
  4. //颜色空间转换
  5. cvCvtColor(image, image1, CV_BGR2HSV);//CV_BGR2HSV

1.4 创建存储HSV通道图像

  1. //创建存储HSV通道图像
  2. IplImage *image_h = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 1);//注意,必须是单通道图像
  3. IplImage *image_s = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 1);//注意,必须是单通道图像
  4. IplImage *image_v = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 1);//注意,必须是单通道图像

1.5 分离通道

  1. //分离通道
  2. cvSplit(image, image_h, image_s, image_v, NULL); //注意Opencv中hsv没有顺序问题

1.6 创建通道直方图

 

  1. //创建H通道的直方图
  2. int arr_size_h = 255; //定义一个变量用于表示直方图行宽
  3. float hranges_arr_h[] = { 0, 180 }; //图像方块范围数组
  4. float *phranges_arr_h = hranges_arr_h; //cvCreateHist参数是一个二级指针,所以要用指针指向数组然后传参
  5. CvHistogram *hist_h = cvCreateHist(1, &arr_size_h, CV_HIST_ARRAY, &phranges_arr_h, 1); //创建一个一维的直方图,行宽为255,多维密集数组,方块范围为0-180,bin均化
  6. //创建S通道的直方图
  7. int arr_size_s = 255; //定义一个变量用于表示直方图行宽
  8. float hranges_arr_s[] = { 0, 255 }; //图像方块范围数组
  9. float *phranges_arr_s = hranges_arr_s; //cvCreateHist参数是一个二级指针,所以要用指针指向数组然后传参
  10. CvHistogram *hist_s = cvCreateHist(1, &arr_size_s, CV_HIST_ARRAY, &phranges_arr_s, 1); //创建一个一维的直方图,行宽为255,多维密集数组,方块范围为0-255,bin均化
  11. //创建V通道的直方图
  12. int arr_size_v = 255; //定义一个变量用于表示直方图行宽
  13. float hranges_arr_v[] = { 0, 255 }; //图像方块范围数组
  14. float *phranges_arr_v = hranges_arr_v; //cvCreateHist参数是一个二级指针,所以要用指针指向数组然后传参
  15. CvHistogram *hist_v = cvCreateHist(1, &arr_size_v, CV_HIST_ARRAY, &phranges_arr_v, 1); //创建一个一维的直方图,行宽为255,多维密集数组,方块范围为0-255,bin均化

1.7 计算通道直方图大小

  1. //计算H通道的直方图大小
  2. cvCalcHist(&image_h, hist_h, 0, 0);
  3. //计算S通道的直方图大小
  4. cvCalcHist(&image_s, hist_s, 0, 0);
  5. //计算V通道的直方图大小
  6. cvCalcHist(&image_v, hist_v, 0, 0);

1.8 直方图缩小

  1. //H通道的直方图缩小
  2. float max_val_h; //用于存储获取到的最大值
  3. cvGetMinMaxHistValue(hist_h, 0, &max_val_h, 0, 0); //获取直方图最大值
  4. cvConvertScale(hist_h->bins, hist_h->bins, max_val_h ? 180 / max_val_h : 0., 0); //按比例缩小直方图
  5. //S通道的直方图缩小
  6. float max_val_s; //用于存储获取到的最大值
  7. cvGetMinMaxHistValue(hist_s, 0, &max_val_s, 0, 0); //获取直方图最大值
  8. cvConvertScale(hist_s->bins, hist_s->bins, max_val_s ? 255 / max_val_s : 0., 0); //按比例缩小直方图
  9. //V通道的直方图缩小
  10. float max_val_v; //用于存储获取到的最大值
  11. cvGetMinMaxHistValue(hist_v, 0, &max_val_v, 0, 0); //获取直方图最大值
  12. cvConvertScale(hist_v->bins, hist_v->bins, max_val_v ? 255 / max_val_v : 0., 0); //按比例缩小直方图

1.9 绘制直方图

 

 

 

  1. //创建一个空白图像用于绘制直方图
  2. IplImage *histimg = cvCreateImage(cvSize(320, 200), 8, 3);
  3. cvZero(histimg); //清空histimag-imagedata数据
  4. //开始绘制H通道的直方图
  5. int bin_h;
  6. bin_h = histimg->width / arr_size_h; //得到开始绘制点位置
  7. for (int i = 0; i < arr_size_h; i++)
  8. {
  9. double val = (cvGetReal1D(hist_h->bins, i)*histimg->height / 360);//获取矩阵元素值,并转换为对应高度
  10. CvScalar color = CV_RGB(255, 0, 0);
  11. cvRectangle(histimg, cvPoint(i*bin_h, histimg->height), cvPoint((i + 1)*bin_h, (int)(histimg->height - val)), color, 1, 8, 0);
  12. }
  13. //创建一个空白图像用于绘制直方图
  14. IplImage *sistimg = cvCreateImage(cvSize(320, 200), 8, 3);
  15. cvZero(sistimg); //清空histimag-imagedata数据
  16. //开始绘制S通道的直方图
  17. int bin_s;
  18. bin_s = sistimg->width / arr_size_s; //得到开始绘制点位置
  19. for (int i = 0; i < arr_size_s; i++)
  20. {
  21. double val = (cvGetReal1D(hist_s->bins, i)*sistimg->height / 255);//获取矩阵元素值,并转换为对应高度
  22. CvScalar color = CV_RGB(0, 255, 0);
  23. cvRectangle(sistimg, cvPoint(i*bin_s, sistimg->height), cvPoint((i + 1)*bin_s, (int)(sistimg->height - val)), color, 1, 8, 0);
  24. }
  25. //创建一个空白图像用于绘制直方图
  26. IplImage *vistimg = cvCreateImage(cvSize(320, 200), 8, 3);
  27. cvZero(vistimg); //清空histimag-imagedata数据
  28. //开始绘制V通道的直方图
  29. int bin_v;
  30. bin_v = vistimg->width / arr_size_v; //得到开始绘制点位置
  31. for (int i = 0; i < arr_size_v; i++)
  32. {
  33. double val = (cvGetReal1D(hist_v->bins, i)*vistimg->height / 255);//获取矩阵元素值,并转换为对应高度
  34. CvScalar color = CV_RGB(0, 0, 255);
  35. cvRectangle(vistimg, cvPoint(i*bin_v, vistimg->height), cvPoint((i + 1)*bin_v, (int)(vistimg->height - val)), color, 1, 8, 0);
  36. }

2.0 显示图像

  1. //显示图像
  2. cvNamedWindow("image_hsv",0);
  3. cvNamedWindow("H",0);
  4. cvNamedWindow("S",0);
  5. cvNamedWindow("V",0);
  6. cvShowImage("image_hsv", image1);
  7. cvShowImage("H", histimg);
  8. cvShowImage("S", sistimg);
  9. cvShowImage("V", vistimg);
  10. cvWaitKey(0);//message

运行结果:

 

 

 

完整代码:

  1. //打开测试图
  2. IplImage * image = cvLoadImage("D:\\3.jpg", 1); //将本地测试图导入到程序堆中
  3. if (image == NULL){ //判断是否打开成功
  4. printf("错误:无法打开该图像,图像文件路径不正确!");
  5. return -1;
  6. }
  7. //RGB颜色空间到HSV颜色空间
  8. //创建一张空白图像用于存储转换成HSV颜色空间后的图像
  9. IplImage *image1 = cvCreateImage(cvSize(image->width, image->height), image->depth, image->nChannels); //注意图像必须和输入图像的size,颜色位深度,通道一致
  10. cvZero(image1); //清空image_data数据
  11. //颜色空间转换
  12. cvCvtColor(image, image1, CV_BGR2HSV);//CV_BGR2HSV
  13. //创建存储HSV通道图像
  14. IplImage *image_h = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 1);//注意,必须是单通道图像
  15. IplImage *image_s = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 1);//注意,必须是单通道图像
  16. IplImage *image_v = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 1);//注意,必须是单通道图像
  17. //分离通道
  18. cvSplit(image, image_h, image_s, image_v, NULL); //注意Opencv中hsv没有顺序问题
  19. //创建H通道的直方图
  20. int arr_size_h = 255; //定义一个变量用于表示直方图行宽
  21. float hranges_arr_h[] = { 0, 180 }; //图像方块范围数组
  22. float *phranges_arr_h = hranges_arr_h; //cvCreateHist参数是一个二级指针,所以要用指针指向数组然后传参
  23. CvHistogram *hist_h = cvCreateHist(1, &arr_size_h, CV_HIST_ARRAY, &phranges_arr_h, 1); //创建一个一维的直方图,行宽为255,多维密集数组,方块范围为0-180,bin均化
  24. //创建S通道的直方图
  25. int arr_size_s = 255; //定义一个变量用于表示直方图行宽
  26. float hranges_arr_s[] = { 0, 255 }; //图像方块范围数组
  27. float *phranges_arr_s = hranges_arr_s; //cvCreateHist参数是一个二级指针,所以要用指针指向数组然后传参
  28. CvHistogram *hist_s = cvCreateHist(1, &arr_size_s, CV_HIST_ARRAY, &phranges_arr_s, 1); //创建一个一维的直方图,行宽为255,多维密集数组,方块范围为0-255,bin均化
  29. //创建V通道的直方图
  30. int arr_size_v = 255; //定义一个变量用于表示直方图行宽
  31. float hranges_arr_v[] = { 0, 255 }; //图像方块范围数组
  32. float *phranges_arr_v = hranges_arr_v; //cvCreateHist参数是一个二级指针,所以要用指针指向数组然后传参
  33. CvHistogram *hist_v = cvCreateHist(1, &arr_size_v, CV_HIST_ARRAY, &phranges_arr_v, 1); //创建一个一维的直方图,行宽为255,多维密集数组,方块范围为0-255,bin均化
  34. //计算H通道的直方图大小
  35. cvCalcHist(&image_h, hist_h, 0, 0);
  36. //计算S通道的直方图大小
  37. cvCalcHist(&image_s, hist_s, 0, 0);
  38. //计算V通道的直方图大小
  39. cvCalcHist(&image_v, hist_v, 0, 0);
  40. //H通道的直方图缩小
  41. float max_val_h; //用于存储获取到的最大值
  42. cvGetMinMaxHistValue(hist_h, 0, &max_val_h, 0, 0); //获取直方图最大值
  43. cvConvertScale(hist_h->bins, hist_h->bins, max_val_h ? 180 / max_val_h : 0., 0); //按比例缩小直方图
  44. //S通道的直方图缩小
  45. float max_val_s; //用于存储获取到的最大值
  46. cvGetMinMaxHistValue(hist_s, 0, &max_val_s, 0, 0); //获取直方图最大值
  47. cvConvertScale(hist_s->bins, hist_s->bins, max_val_s ? 255 / max_val_s : 0., 0); //按比例缩小直方图
  48. //V通道的直方图缩小
  49. float max_val_v; //用于存储获取到的最大值
  50. cvGetMinMaxHistValue(hist_v, 0, &max_val_v, 0, 0); //获取直方图最大值
  51. cvConvertScale(hist_v->bins, hist_v->bins, max_val_v ? 255 / max_val_v : 0., 0); //按比例缩小直方图
  52. //创建一个空白图像用于绘制直方图
  53. IplImage *histimg = cvCreateImage(cvSize(320, 200), 8, 3);
  54. cvZero(histimg); //清空histimag-imagedata数据
  55. //开始绘制H通道的直方图
  56. int bin_h;
  57. bin_h = histimg->width / arr_size_h; //得到开始绘制点位置
  58. for (int i = 0; i < arr_size_h; i++)
  59. {
  60. double val = (cvGetReal1D(hist_h->bins, i)*histimg->height / 360);//获取矩阵元素值,并转换为对应高度
  61. CvScalar color = CV_RGB(255, 0, 0);
  62. cvRectangle(histimg, cvPoint(i*bin_h, histimg->height), cvPoint((i + 1)*bin_h, (int)(histimg->height - val)), color, 1, 8, 0);
  63. }
  64. //创建一个空白图像用于绘制直方图
  65. IplImage *sistimg = cvCreateImage(cvSize(320, 200), 8, 3);
  66. cvZero(sistimg); //清空histimag-imagedata数据
  67. //开始绘制S通道的直方图
  68. int bin_s;
  69. bin_s = sistimg->width / arr_size_s; //得到开始绘制点位置
  70. for (int i = 0; i < arr_size_s; i++)
  71. {
  72. double val = (cvGetReal1D(hist_s->bins, i)*sistimg->height / 255);//获取矩阵元素值,并转换为对应高度
  73. CvScalar color = CV_RGB(0, 255, 0);
  74. cvRectangle(sistimg, cvPoint(i*bin_s, sistimg->height), cvPoint((i + 1)*bin_s, (int)(sistimg->height - val)), color, 1, 8, 0);
  75. }
  76. //创建一个空白图像用于绘制直方图
  77. IplImage *vistimg = cvCreateImage(cvSize(320, 200), 8, 3);
  78. cvZero(vistimg); //清空histimag-imagedata数据
  79. //开始绘制V通道的直方图
  80. int bin_v;
  81. bin_v = vistimg->width / arr_size_v; //得到开始绘制点位置
  82. for (int i = 0; i < arr_size_v; i++)
  83. {
  84. double val = (cvGetReal1D(hist_v->bins, i)*vistimg->height / 255);//获取矩阵元素值,并转换为对应高度
  85. CvScalar color = CV_RGB(0, 0, 255);
  86. cvRectangle(vistimg, cvPoint(i*bin_v, vistimg->height), cvPoint((i + 1)*bin_v, (int)(vistimg->height - val)), color, 1, 8, 0);
  87. }
  88. //显示图像
  89. cvNamedWindow("image_hsv",0);
  90. cvNamedWindow("H",0);
  91. cvNamedWindow("S",0);
  92. cvNamedWindow("V",0);
  93. cvShowImage("image_hsv", image1);
  94. cvShowImage("H", histimg);
  95. cvShowImage("S", sistimg);
  96. cvShowImage("V", vistimg);
  97. cvWaitKey(0);//message

 

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/article/detail/46686
推荐阅读
相关标签
  

闽ICP备14008679号