在C#中将图像转换为黑白或棕褐色

6
我想将图像转换为黑白或深褐色。 转换图像后,我希望用转换后的图像替换现有图像。请给我一些建议。
5个回答

11
有许多方法可以使彩色图像变为灰度图像。事实上,可能没有一种“真正”的或“正确”的方法来做到这一点,但有些方法比其他方法更“正确”。我假设您的图像是RGB(红-绿-蓝)格式(虽然BGR也很常见)。
最简单的方法是使用三个RGB通道中的绿色通道,这应该适用于大多数照片(但对合成图像的效果不太好)。人类对光谱中绿色部分的变化最为敏感,因此绿色通道涵盖了大部分可见范围,并且是所需灰度图像的一个很好的近似值。
生成灰度图像的更好方法是使用三个RGB通道的加权平均值。选择相等的权重(0.33*R+0.33*G+0.33*B)将给出一个相当好的灰度图像。其他凸权重(非负权重总和为1)将给出不同的结果,其中一些可能被认为更具美感,而另一些则可能考虑到感知参数。(YUV使用这些权重Y = 0.299*R + 0.587*G + 0.114*B
您还可以将图像转换为另一个仅具有一个灰度通道(和2个“颜色”通道)的颜色空间,例如HSV(V为灰度),YUV(Y为灰度)或Lab(L为灰度)。差异应该不会很大。
“去饱和度”这个术语来自HSV空间。如果将图像转换为HSV,将S通道(饱和度)设置为全零,并渲染图像,则会得到一个三通道去饱和的“彩色”图像。
将这些灰度通道复制到RGB中,将给您一个三通道去饱和的“彩色”图像 - 所有3个RGB通道都相同。
一旦您拥有了这个三通道(RGB)去饱和的图像,您可以将每个通道乘以单独的权重来着色图像 - 一个棕褐色图像。
给定一个灰色像素 [v,v,v] ,请这样着色: [v * a,v * b,v * c] ,其中 0 <= a,b,c <=1

3

这种转换方式很好、很快(方法GetPixel/SetPixel非常慢),而且简单,但有两个主要问题。黑白(1像素)转换的结果非常糟糕,当源图像具有透明背景时,它会变成黑色。第二个问题是,即使在˙color˙图像上调用了Dispose方法,文件(在本例中为file.jpg)仍将被锁定。最好使用图形中的DrawImage方法。(这条评论不是给Serov Danil,而是给其他程序员的) - Julo

2
// Loop through the images pixels to reset color.
for(x=0; x<image1.Width; x++)
{
    for(y=0; y<image1.Height; y++)
    {
        Color pixelColor = image1.GetPixel(x, y);
        int grayScale = (int)((originalColor.R * .3) + 
            (originalColor.G * .59) + (originalColor.B * .11));

        //create the color object
        Color newColor =  Color.FromArgb(grayScale, grayScale, grayScale);
            image1.SetPixel(x, y, newColor);
    }
}

使用此方法将彩色像素转换为灰度图像

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

为什么要将这些值乘以组件?这会产生棕褐色吗?我怀疑是,但解释会很有用。 - ChrisF
红色(255,0,0),绿色(0,255,0),蓝色(0,0,255)。它们一起组成了白色,即255,255,255。如果使用上述公式计算纯RGB,结果接近于255。 - hungryMind

2

若要转换为棕褐色,则首先需将图像转换为灰度。然后,将每个像素乘以一个固定的缩放三元组,例如[1, 0.95, 0.82]。您可以尝试修改这个三元组来得到合适的效果…… 因此代码可能如下:

for(x=0; x<image1.Width; x++)     
{         
    for(y=0; y<image1.Height; y++)         
    {             
        Color pixelColor = image1.GetPixel(x, y);             

        int grayScale = (int)((originalColor.R * .3) + (originalColor.G * .59) + (originalColor.B * .11));              
        //create the color object             
        Color newColor =  Color.FromArgb(grayScale, grayScale, grayScale);             

        //now apply a sepia filter
        pixelColor.R = newColor.R*1;
        pixelColor.G = newColor.G*0.95;
        pixelColor.B = newColor.B*0.82;

        image1.SetPixel(x, y, pixelColor);
     }
 }

1
private Bitmap grayscale(Image image)
{
    Bitmap btm = new Bitmap(image);
    for (int i = 0; i < btm.Width; i++)
    {
        for (int j = 0; j < btm.Height; j++)
        {
            int ser = (btm.GetPixel(i, j).R + btm.GetPixel(i, j).G + btm.GetPixel(i, j).B) / 3;
            btm.SetPixel(i, j, Color.FromArgb(ser, ser, ser));
        }
    }
    return btm;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接