我正在尝试弄清楚如何为.bmp文件制作Schindlers List(电影)风格的照片过滤器。对于那些没有看过它的人,我希望能够制作除灰色之外的所有灰度。
这是一个类,我只允许使用以下库:iostream,fstream,cstdlib,string,cstring。
老师很乐意为我们提供大部分代码,我只需要相应地修改像素。
我的灰度算法并不完美。我通过使用fotor的灰度滤镜并比较前后RGB值得到它。当我运行此功能时,即使图片的颜色在我声明的范围内,整个图像也会以灰度结束。
如果有人可以帮助我让这项工作变得更棒!
void process( int& red, int& green, int& blue ) //schindler's list filter
{
if( red < 143 && red > 80 &&
green < 64 && green > 24 &&
blue < 70 && blue >> 30 )//my red range
{
red = red;
blue = blue;
green = green;
}
else //if the pixel isnt red the program will go ahead and make it grayscale
{
red = ((red + green) / 2)*1.01;
green = red;
blue = red;
}
}
答案 0 :(得分:5)
blue >> 30
愚蠢的拼写错误:你的意思是blue > 30
。
blue >> 30
基本上始终为零,转换为false
,使您的“保留颜色”块无法访问。
如果有人可以帮助我让这项工作变得更棒!
我们并不是真的在这里。下次请做一些调试。
删除条件,输出表达式和变量的值,直到找到不符合预期的值。 Make a testcase。摘要你的具体用例(即电影名称与问题无关)。
顺便说一句,作为一种风格问题,red = red
等完全没有意义!
答案 1 :(得分:1)
正如评论员所说,在经典的RGB色彩空间中,使用公式计算灰度值
grey = .2126*red + .7152*green + .0722*blue;
此外,如果您只想在要保留的颜色和灰色区域之间进行残酷的过渡,则可能看起来彩色区域已经在图片上绘制。
我宁愿根据您想要突出的颜色应用平滑效果。
// this is the center of the intervals you defined for your color
#define TARGET_R 111
#define TARGET_G 44
#define TARGET_B 50
// color distance to consider to mix grey and pure color
#define RADIUS 20 // R, G or B component
int dr = red - TARGET_R;
int dg = green - TARGET_G;
int db = blue - TARGET_B;
int dist = sqrt(dr*dr+dg*dg+db*db); // distance from target color
int grey = .2126*red+.7152*green+.0722*blue; // grey color
float color; // fraction of pure color
if (dist > RADIUS) // pure grey beyond radius
color = 0;
else if (dist > RADIUS/2) // slope from 0 @ radius to 1 @ radius/2
color = (RADIUS-dist)*2.0/RADIUS;
else // pure color between 0 and radius/2;
color = 1;
grey *= (1-color); // grey part
red = red * color + grey;
green = green * color + grey;
blue = blue * color + grey;
答案 2 :(得分:0)
您可以采用的另一种方法是将RGB颜色转换为HSV(色相饱和度值)颜色空间,并且仅在色调不在特定范围内时才将饱和度降低。例如:
if( 30 < h && h < 330 ) s = 0