本篇文章参考了万水千山的博客PS 图像调整算法——黑白和阿发伯的博客C++图像处理 -- 图像颜色混合(上)
黑白调整
Photoshop CS的图像黑白调整功能,是通过对红、黄、绿、青、蓝和洋红等6种颜色的比例调节来完成的。能更精细地将彩色图片转换为高质量的黑白照片。
Photoshop CS图像黑白调整功能的计算公式为:
gray= (max - mid) * ratio_max + (mid - min) * ratio_max_mid + min
公式中:gray为像素灰度值,max、mid和min分别为图像像素R、G、B分量颜色的最大值、中间值和最小值,ratio_max为max所代表的分量颜色(单色)比率,ratio_max_mid则为max与mid两种分量颜色所形成的复色比率。
默认的单色及复色比率为:
Color_Ratio(1)=0.4; %%%% Red
Color_Ratio(2)=0.6; %%%% Yellow
Color_Ratio(3)=0.4; %%%% Green
Color_Ratio(4)=0.6; %%%% Cyan
Color_Ratio(5)=0.2; %%%% Blue
Color_Ratio(6)=0.8; %%%% Magenta
下面是实现代码:
BOOL Convert24toGrayPS(LPSTR lpDIBBits, LONG lWidth, LONG lHeight)
{
unsigned char *lpSrc;
LONG lLineBytes = WIDTHBYTES(lWidth * 24);
unsigned char buf;
unsigned char* lpRed;
unsigned char* lpGreen;
unsigned char* lpBlue;
float Color_Ratio[6];
int Index;
//PS中各颜色的默认比例
//BGR分别为蓝色,绿色和红色,其中蓝色和绿色的中间色为青色,
//红色和绿色的中间色为黄色,红色和蓝色的中间色为紫(洋红)色。
Color_Ratio[0] = 0.4; //红色Red
Color_Ratio[1] = 0.6; //黄色Yellow
Color_Ratio[2] = 0.4; //绿色Green
Color_Ratio[3] = 0.6; //青色Cyan
Color_Ratio[4] = 0.2; //蓝色Blue
Color_Ratio[5] = 0.8; //紫(洋红)色Magenta
for (int i = 0; i < lHeight; i++)
{
for (int j = 0; j < lWidth * 3; j += 3)
{
lpRed = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i) + j + 2;//顺序为BGR
lpGreen = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i) + j + 1;
lpBlue = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i) + j;
int SumRGB = (*lpRed) + (*lpGreen) + (*lpBlue);
int MaxValue = max((*lpRed), max((*lpGreen), (*lpBlue)));
int MinValue = min((*lpRed), min((*lpGreen), (*lpBlue)));
int MidValue = SumRGB - MaxValue - MinValue;
if (MinValue == (*lpRed))
{
Index = 3;
}
else if (MinValue == (*lpGreen))
{
Index = 5;
}
else
{
Index = 1;
}
float ratio_max_mid = Color_Ratio[Index];
if (MaxValue == (*lpRed))
{
Index = 0;
}
else if (MaxValue == (*lpGreen))
{
Index = 2;
}
else
{
Index = 4;
}
float ratio_max = Color_Ratio[Index];
buf = (MaxValue - MidValue)*ratio_max + (MidValue - MinValue)*ratio_max_mid + MinValue;
*lpRed = *lpGreen = *lpBlue = buf;
}
}
return TRUE;
}
经过亲自试验,发现这个算法确实比(0.299R+ 0.587G+ 0.114B)的这个效果要好一些,但是本人还读过Imageshop的一篇关于实现灰度图的算法对比度保留之彩色图像去色算法---基础算法也可以上档次,在这篇文章中灰度图完好的保留了对比度,效果更真实一些(尽管通过PS的黑白调整,调整各个参数也可以达到保留对比度的效果,但是那样操作起来太复杂了),不过本人暂时懒得去学习,先记录在这里吧,还有一个问题就是,使用PS的算法生成的灰度图会比较暗,不知道是自己程序的原因还是别的原因还是这个算法本来就是这样的。(这个经过u010120739的评论发现自己把数据类型都定义错了,应该定义为float型)
int ratio_max_mid = Color_Ratio[Index];
int Color_Ratio[6];
int ratio_max = Color_Ratio[Index];
改为
float ratio_max_mid = Color_Ratio[Index];
float Color_Ratio[6];
float ratio_max = Color_Ratio[Index];
下面贴出效果图,从左到右分别是原图,(0.299R+ 0.587G+ 0.114B)效果图,PS算法效果图,Imageshop博文算法效果图: