【转】图像灰度化方法总结及其VC实现

转载自:  http://blog.csdn.net/likezhaobin/article/details/6915754

最近一段时间作者开始进行运动目标识别定位系统设计,本文以及后续的几篇文章都是从一个图像处理初学者的角度来总结目标检测定位过程中所应用到的各种常 见的算法,尤其是解决算法实现过程中由于粗心大意或者C编程基本功不扎实所引起的各种问题。本文主要对彩色图片灰度化的方法及其实现过程进行总结,最终给 出实现的C代码。

在进行视频流目标识别与跟踪时,通常第一个步骤就是对采集到的彩色图像进行灰度化,这是因为黑白照片数据量小,相比彩照更易实现实时算法,另一方面黑白照 片是由未处理的光线所形成的照片,因此从图像处理学角度来看,这种未经特殊滤光处理的图片所涵盖的信息更有价值。

目前,在图像处理过程中,最常用的彩色图片格式有RGB,HSV、YUV以及HLS三种。以下分别对这三种格式的彩色图像进行灰度化实现。

1、RGB空间图像

定义于RGB空间的彩色图,其每个像素点的色彩由R、G、B三个分量共同决定。每个分量在内存所占的位数共同决定了图像深度,即每个像素点所占的字节数。 以常见的24深度彩色RGB图来说,其三个分量各占1个字节,这样每个分量可以取值为0~255,这样一个像素点可以有1600多万 (255*255*255)的颜色的变化范围。对这样一幅彩色图来说,其对应的灰度图则是只有8位的图像深度(可认为它是RGB三个分量相等),这也说明 了灰度图图像处理所需的计算量确实要少。不过需要注意的是,虽然丢失了一些颜色等级,但是从整幅图像的整体和局部的色彩以及亮度等级分布特征来看,灰度图 描述与彩色图的描述是一致的。
     对于RGB图像进行灰度化,通俗点说就是对图像的RGB三个分量进行加权平均得到最终的灰度值。最常见的加权方法如下:

1)Gray=B;Gray=G;Gray=R

2)Gray=max(B+G+R)

3)Gray=(B+G+R)/3

4)Gray= 0.072169B+ 0.715160G+ 0.212671R

5)Gray= 0.11B+ 0.59G+ 0.3R

这三种方法中,第一种为分量法,即用RGB三个分量的某一个分量作为该点的灰度值;第二种方法为最大值法,将彩色图像中的三分量亮度的最大值作为灰度
图的灰度值。第三种方法将彩色图像中的三分量亮度求平均得到一个灰度图;后两种都是属于加权平均法,其中第四种是OpenCV开放库所采用的灰度权值,第
五种为从人体生理学角度所提出的一种权值(人眼对绿色的敏感最高,对蓝色敏感最低)。

2、其他颜色空间的灰度化

关于HSV以及HLS颜色空间的彩色图灰度化,可以参考网页《HSL和HSV色彩空间》,该网页中所述方法可将几种不同颜色表达方式进行转换,将其转换到RGB空间,然后再采用上述公式进行灰度化。

关于YUV空间的彩色图像,其Y的分量的物理意义本身就是像素点的亮度,由该值反映亮度等级,因此可根据RGB和YUV颜色空间的变化关系建立亮度Y与R、G、B三个颜色分量的对应:Y=0.3R+0.59G+0.11B,以这个亮度值表达图像的灰度值

3、代码实现

本文旨在对整个实现原理及思路进行总结,因此以下基于OpenCv的基本函数实现这几种变化过程,至于位图以及其他形式的图像,在获取了图像原始数据后,处理方法都一样,仅需注意指针的位置操作即可。具体代码如下:

  1. IplImage    *ColorImage;                        //定义相应的图像指针
  2. IplImage    *GrayImage1;                        //从1~5代表5中不同权值的结果
  3. IplImage    *GrayImage2;
  4. IplImage    *GrayImage3;
  5. IplImage    *GrayImage4;
  6. IplImage    *GrayImage5;
  7. IplImage    *GrayImage6;
  8. IplImage    *GrayImage7;
  9. ColorImage = cvLoadImage( "49138.jpg", -1 );    //读取图片
  10. if (ColorImage == NULL)
  11. return;
  12. GrayImage1 = cvCreateImage(cvGetSize(ColorImage),8,1);
  13. GrayImage2 = cvCreateImage(cvGetSize(ColorImage),8,1);
  14. GrayImage3 = cvCreateImage(cvGetSize(ColorImage),8,1);
  15. GrayImage4 = cvCreateImage(cvGetSize(ColorImage),8,1);
  16. GrayImage5 = cvCreateImage(cvGetSize(ColorImage),8,1);
  17. GrayImage6 = cvCreateImage(cvGetSize(ColorImage),8,1);
  18. GrayImage7 = cvCreateImage(cvGetSize(ColorImage),8,1);
  19. CvMat* pGrayMat1 = NULL;         //定义与图像关联的数据指针
  20. CvMat* pGrayMat2 = NULL;
  21. CvMat* pGrayMat3 = NULL;
  22. CvMat* pGrayMat4 = NULL;
  23. CvMat* pGrayMat5 = NULL;
  24. CvMat* pGrayMat6 = NULL;
  25. CvMat* pGrayMat7 = NULL;
  26. pGrayMat1 = cvCreateMat(ColorImage->height, ColorImage->width, CV_32FC1);
  27. pGrayMat2 = cvCreateMat(ColorImage->height, ColorImage->width, CV_32FC1);
  28. pGrayMat3 = cvCreateMat(ColorImage->height, ColorImage->width, CV_32FC1);
  29. pGrayMat4 = cvCreateMat(ColorImage->height, ColorImage->width, CV_32FC1);
  30. pGrayMat5 = cvCreateMat(ColorImage->height, ColorImage->width, CV_32FC1);
  31. pGrayMat6 = cvCreateMat(ColorImage->height, ColorImage->width, CV_32FC1);
  32. pGrayMat7 = cvCreateMat(ColorImage->height, ColorImage->width, CV_32FC1);
  33. BYTE data1;       //中间过程变量
  34. BYTE data2;
  35. BYTE data3;
  36. BYTE data4;
  37. BYTE data5;
  38. BYTE data6;
  39. BYTE data7;
  40. for(int j=0; j<ColorImage->height; j++)
  41. {
  42. for(int i=0; i<ColorImage->width; i++)
  43. {
  44. data1 = (BYTE)ColorImage->imageData[j*ColorImage->widthStep + i*3];     //B分量
  45. data2 = (BYTE)ColorImage->imageData[j*ColorImage->widthStep + i*3 + 1]; //G分量
  46. data3 = (BYTE)ColorImage->imageData[j*ColorImage->widthStep + i*3 + 2]; //R分量
  47. data4 = max(data1, max(data2, data3));    //最大值
  48. data5 = (BYTE)((data1 + data2 + data3)/3);
  49. data6 = (BYTE)(0.072169*data1 + 0.715160*data2 + 0.212671*data3);
  50. data7 = (BYTE)(0.11*data1 + 0.59*data2 + 0.30*data3);
  51. cvmSet(pGrayMat1, j, i, data1);
  52. cvmSet(pGrayMat2, j, i, data2);
  53. cvmSet(pGrayMat3, j, i, data3);
  54. cvmSet(pGrayMat4, j, i, data4);
  55. cvmSet(pGrayMat5, j, i, data5);
  56. cvmSet(pGrayMat6, j, i, data6);
  57. cvmSet(pGrayMat7, j, i, data6);
  58. }
  59. }
  60. cvConvert(pGrayMat1, GrayImage1);
  61. cvConvert(pGrayMat2, GrayImage2);
  62. cvConvert(pGrayMat3, GrayImage3);
  63. cvConvert(pGrayMat4, GrayImage4);
  64. cvConvert(pGrayMat5, GrayImage5);
  65. cvConvert(pGrayMat6, GrayImage6);
  66. cvConvert(pGrayMat7, GrayImage7);
  67. cvNamedWindow( "ColorImage",CV_WINDOW_AUTOSIZE);
  68. cvNamedWindow( "GrayImage1",CV_WINDOW_AUTOSIZE);
  69. cvNamedWindow( "GrayImage2",CV_WINDOW_AUTOSIZE);
  70. cvNamedWindow( "GrayImage3",CV_WINDOW_AUTOSIZE);
  71. cvNamedWindow( "GrayImage4",CV_WINDOW_AUTOSIZE);
  72. cvNamedWindow( "GrayImage5",CV_WINDOW_AUTOSIZE);
  73. cvNamedWindow( "GrayImage6",CV_WINDOW_AUTOSIZE);
  74. cvNamedWindow( "GrayImage7",CV_WINDOW_AUTOSIZE);
  75. cvShowImage("ColorImage", ColorImage);
  76. cvShowImage("GrayImage1", GrayImage1);
  77. cvShowImage("GrayImage2", GrayImage2);
  78. cvShowImage("GrayImage3", GrayImage3);
  79. cvShowImage("GrayImage4", GrayImage4);
  80. cvShowImage("GrayImage5", GrayImage5);
  81. cvShowImage("GrayImage6", GrayImage6);
  82. cvShowImage("GrayImage7", GrayImage7);
  83. cvWaitKey(0);
  84. cvDestroyWindow("ColorImage");
  85. cvDestroyWindow("GrayImage1");
  86. cvDestroyWindow("GrayImage2");
  87. cvDestroyWindow("GrayImage3");
  88. cvDestroyWindow("GrayImage4");
  89. cvDestroyWindow("GrayImage5");
  90. cvDestroyWindow("GrayImage6");
  91. cvDestroyWindow("GrayImage7");
  92. cvReleaseImage(&ColorImage);
  93. cvReleaseImage(&GrayImage1);
  94. cvReleaseImage(&GrayImage2);
  95. cvReleaseImage(&GrayImage3);
  96. cvReleaseImage(&GrayImage4);
  97. cvReleaseImage(&GrayImage5);
  98. cvReleaseImage(&GrayImage6);
  99. cvReleaseImage(&GrayImage7);
  100. cvReleaseMat(&pGrayMat1);
  101. cvReleaseMat(&pGrayMat2);
  102. cvReleaseMat(&pGrayMat3);
  103. cvReleaseMat(&pGrayMat4);
  104. cvReleaseMat(&pGrayMat5);
  105. cvReleaseMat(&pGrayMat6);
  106. cvReleaseMat(&pGrayMat7);

各种不同方法实现灰度化的效果图对比如下;

图1 待处理的原始图像—脱离低级趣味的猫

图2 分量灰度化—B分量

图3 分量灰度化—G分量

图4 分量灰度化—R分量

图5 最大值灰度化

图6 均值灰度化

图7 OpenCV权值系数灰度化

图8 网络常用权值灰度化

4、思考

上文的代码实现中,以最后一种方法为例,用到了如下代码:

Gray= (0.11* Blue + 0.59* Green + 0.30* Red);

实际计算机处理时,这种方法已经很快了,但实际上还存在可以优化的余地。以上代码所采用的是浮点运算。而在图像处理中,速度就是生命,实时性往往是很
重要的指标,这就要求我们在实现算法时必须考虑到代码的效率问题。所以有一个原则:在图像处理中,能不用浮点运算,就最好不要用!

因此,上述代码可以等效的优化为:

Gray = (30 * Red + 59 *Green + 11 * Blue) / 100;

这样一改,可以有效避免浮点运算,因此可以提高代码的效率

对这行代码还可以继续改进为如下:

Gray= HiByte(77 * Red + 151 * Green + 28 * Blue);

其中77,151,28分别除以256,即为上文的三个系数。

同样的,还可以实现为:

Gray= (77 * Red + 151 * Green + 28 * Blue) shr 8;

这种方法实现了移位运算,避免了除法,效率上又有所提高。

关于具体的代码效率问题,可以参考博文《由图像的灰度化看基本图像处理》

时间: 2024-08-01 16:30:07

【转】图像灰度化方法总结及其VC实现的相关文章

图像处理之常见二值化方法汇总

图像处理之常见二值化方法汇总 图像二值化是图像分析与处理中最常见最重要的处理手段,二值处理方法也非常多.越 精准的方法计算量也越大.本文主要介绍四种常见的二值处理方法,通常情况下可以满 足大多数图像处理的需要.主要本文讨论的方法仅针对RGB色彩空间. 方法一: 该方法非常简单,对RGB彩色图像灰度化以后,扫描图像的每个像素值,值小于127的 将像素值设为0(黑色),值大于等于127的像素值设为255(白色).该方法的好处是计算 量少速度快.缺点更多首先阈值为127没有任何理由可以解释,其次完全不

java实现图像灰度化

/*在研究Java实现将一张图片转成字符画的时候,发现将图像转化字符串是根据照片的灰度采用不同的字符画出来,形成一个灰度表.于是就研究了下关于灰度值这个东西,于是跳了一个大坑...因为鄙人用的ubuntu,所以我的代码路径会有所不同.直接贴出原博文代码.故事的开始是这样的...*/ 1.关于Java实现将一张图片转成字符画(原文地址:http://blog.csdn.net/zhouli_05/article/details/7913263) 怎么样用Java实现将一张图片转成字符画?? 输入:

VB6之图像灰度与二值化

老代码备忘,我对图像处理不是太懂. 注:部分代码引援自网上,话说我到底自己写过什么代码... Private Declare Function GetBitmapBits Lib "gdi32" (ByVal hbitmap As Long, _ ByVal dwCount As Long, _ lpBits As Any) As Long Private Declare Function SetBitmapBits Lib "gdi32" (ByVal hbitm

c#图像灰度化、灰度反转、二值化

图像灰度化:将彩色图像转化成为灰度图像的过程成为图像的灰度化处理.彩色图像中的每个像素的颜色有R.G.B三个分量决定,而每个分量有255中值可取,这样一个像素点可以有1600多万(255*255*255)的颜色的变化范围.而灰度图像是R.G.B三个分量相同的一种特殊的彩色图像,其一个像素点的变化范围为255种,所以在数字图像处理种一般先将各种格式的图像转变成灰度图像以使后续的图像的计算量变得少一些.灰度图像的描述与彩色图像一样仍然反映了整幅图像的整体和局部的色度和亮度等级的分布和特征.图像的灰度

Java图像灰度化的实现过程解析

概要 本文主要介绍了灰度化的几种方法,以及如何使用Java实现灰度化.同时分析了网上一种常见却并不妥当的Java灰度化实现,以及证明了opencv的灰度化是使用“加权灰度化”法 24位彩色图与8位灰度图 首先要先介绍一下24位彩色图像,在一个24位彩色图像中,每个像素由三个字节表示,通常表示为RGB.通常,许多24位彩色图像存储为32位图像,每个像素多余的字节存储为一个alpha值,表现有特殊影响的信息[1]. 在RGB模型中,如果R=G=B时,则彩色表示一种灰度颜色,其中R=G=B的值叫灰度值

图像 - 灰度化、灰度反转、二值化

原文地址:http://www.cnblogs.com/gdjlc/archive/2013/03/05/2943801.html 图像灰度化: 将彩色图像转化成为灰度图像的过程成为图像的灰度化处理.彩色图像中的每个像素的颜色有R.G.B三个分量决定,而每个分量有255中值可取,这样一个像素点可以有1600多万(255*255*255)的颜色的变化范围.而灰度图像是R.G.B三个分量相同的一种特殊的彩色图像,其一个像素点的变化范围为255种,所以在数字图像处理种一般先将各种格式的图像转变成灰度图

【数字图像处理】三.MFC实现图像灰度、采样和量化功能详解

本文主要讲述基于VC++6.0 MFC图像处理的应用知识,主要结合自己大三所学课程<数字图像处理>及课件进行讲解,主要通过MFC单文档视图实现显示BMP格式图片,并通过Bitmap进行灰度处理.图片采样和量化功能. 个人认为对初学者VC++6.0可能还是很值得学习的工具,所以采用它来讲解,而不是VS或C#.同时文章比较详细基础,希望该篇文章对你有所帮助~ [数字图像处理]一.MFC详解显示BMP格式图片 [数字图像处理]二.MFC单文档分割窗口显示图片 免费资源下载地址: http://dow

图像灰度化

1彩色图,灰度图,单色图 灰度图是指只含亮度信息,不含色彩信息的图像.灰度化处理是把含有亮度和色彩的彩色图像变化成灰度图像的过程. 图像灰度化处理一般采用以下三种算法: 平均值法: f(i,j)=(R(i,j)+G(i,j)+B(i,j))/3 最大值法: f(i,j)=max(R(i,j),G(i,j),B(i,j)) 加权平均值法:f(i,j)=0.30R(i,j)+0.59G(i,j)+0.11B(i,j) 2 图像灰度化opencv 1 #include <opencv2/opencv.

Azure 动手演示之一:采用定制化方法在 Azure 中创建虚拟机

也许大家看过很多关于 Windows Azure (Microsoft Azure) 介绍或如何使用的文章,但即使看过很多图片或 PPT,也难以真正理解这一全球领先的公有云平台. 鉴于此,我制作了一系列如何使用 Azure 的视频录像,主要是实时录制我在屏幕上对 Azure 的操作.希望能对大家深入的了解 Windows Azure (Microsoft Azure) 有所帮助. 本演示看上去非常简单,目的是如何在 Azure 上创建虚拟机,但事实上,它是如何在 Azure 上创建整个企业部署的