第四篇 灰度
从前面的两篇文章看得出,图像算法处理主要还是以灰度为基础。的确也是这样。多数算法对篇图像的处理。基本上都是以灰度为基础。究其原因,是因为灰度图像只有一个维度,便运算吧。像RGB,HSV,HSI,YCrCb等,都是多个维度的信息。只有灰度,是一个维度,且取值范围是在0-255之间.当然,我不是说所有算法都是这样。举个例子,有一些算法需要识别皮肤,这个时候就不能以灰度为基础,必须用色度为基础。
前面第一篇文章有提到,RGB其实是在灰度的信号上,通过覆膜过滤光的方式来取得的。但本质上,还是光电转换中的亮度信号,转为灰度数值。其实将RGB每个通道的值取出,也就独立的“灰度”数值。不过就我们常用的彩色转灰度而言,却不能是取某一个通道,必须是三个通道一计算。
灰度计算有很多方式,比如,
最大值法(取每个像素RGB三通道中最大的值做为整个图像的灰度)
最小值法(取每个像素RGB三通道中最小的值做为整个图像的灰度)
平均值 (取每个像素RGB三通道的和除以三做为整个图像的灰度)
心理学法(以这个公式为基础 Gray = R*0.299 + G*0.587 + B*0.114)
下面将贴出代码,图像运行的结果:
图1
这个是最小值的图像,很明显,图像偏暗。
图2
这个是最大值的图像,明显图像偏亮。
图3
这个是三通道中的平均值,在图像的叶子方面还是稍微暗了一点点。
图4
最后这一张是心理学的图像,明显比前三张效果要好得多。且目前绝大多数都是以这个公式为基准来取得灰度图像的。
另外,这个图像明显是倒像,是因为BMP本来的图像就是倒的。为了让大家加深这一个关键点,是以就没有更正图像的底影。
由于代码太多,我就只贴部分关键的。同时因为算法过于简单,故没有太多的讲解的必要。
void ColorToGrayMin(PStruImage grayImage, PStruImage colorImage)
{
int i,j;
for(i = 0;i < colorImage->height;i++)
{
unsigned char *cptr = colorImage->cptr + colorImage->bytePerLine * i;
unsigned char *gray = grayImage->cptr + grayImage->bytePerLine * i;
for(j = 0;j < colorImage->width;j++)
{
int v = 0;
int r = *cptr++;
int g = *cptr++;
int b = *cptr++;
v = r < g ? r : g;
v = v < b ? v : b;
gray[j] = v;
}
}
}
上面是最小值,这是最大值:
v = r > g ? r : g;
v = v > b ? v : b;
这是平均值:gray[j] = (r+g+b)/3;
这是心理学值:gray[j] = (299*r+587*g+114*b)/1000;
以上是核心源代码,如果需要完整的源代码和VS工程。请单独给我留言。
源代码链接: https://download.****.net/download/finger157959/12515369