在C#中将灰度图像转换为黑白图像

3
我可以帮助您进行翻译。以下是需要翻译的内容:

我已经编写了一些C#代码,将我的RGB图像转换为灰度图像,并且我想将灰度图像转换为只有两种颜色,黑色和白色。 你能帮忙吗?

代码:

 Bitmap bmp = new Bitmap(file);
 int width = bmp.Width;
 int height = bmp.Height;
 int[] arr = new int[225];
 int i = 0;
 Color p;

 //Grayscale
 for (int y = 0; y < height; y++)
 {
     for (int x = 0; x < width; x++)
     {
         p = bmp.GetPixel(x,y);
         int a = p.A;
         int r = p.R;
         int g = p.G;
         int b = p.B;
         int avg = (r+g+b)/3;
         bmp.SetPixel(x, y, Color.FromArgb(a, avg ,avg, avg));
     }
 }
 pictureBox2.Image = bmp; 

1
根据什么标准? - walther
将你的灰色像素取出,如果超过某个限制就将其设置为白色,否则设置为黑色...但它很可能看起来像狗屎 ;) - Random Dev
1
你的灰度转换代码有问题,人眼对绿色非常敏感,对红色不太敏感,对蓝色很差劲。这与你可以吃的东西的颜色有很大关系。使用0.21 * r + 0.71 * g + 0.07 * b进行转换。将值剪切到黑色或白色只需与0.5进行比较。 - Hans Passant
2个回答

6

任何情况下都应停止使用GetPixel方法。

我是VB.Net的开发人员,我编写了以下方法,可以将图像转换为黑白。

首先,我会应用灰度矩阵,然后使用SetThreshold方法设置分隔黑色和白色的阈值。

''' <summary>
''' Transforms an image to black and white.
''' </summary>
''' <param name="img">The image.</param>
''' <returns>The black and white image.</returns>
Public Shared Function GetBlackAndWhiteImage(ByVal img As Image) As Image

    Dim bmp As Bitmap = New Bitmap(img.Width, img.Height)

    Dim grayMatrix As New System.Drawing.Imaging.ColorMatrix(
        {
            New Single() {0.299F, 0.299F, 0.299F, 0, 0},
            New Single() {0.587F, 0.587F, 0.587F, 0, 0},
            New Single() {0.114F, 0.114F, 0.114F, 0, 0},
            New Single() {0, 0, 0, 1, 0},
            New Single() {0, 0, 0, 0, 1}
        })

    Using g As Graphics = Graphics.FromImage(bmp)

        Using ia As System.Drawing.Imaging.ImageAttributes = New System.Drawing.Imaging.ImageAttributes()

            ia.SetColorMatrix(grayMatrix)
            ia.SetThreshold(0.5)

            g.DrawImage(img, New Rectangle(0, 0, img.Width, img.Height), 0, 0, img.Width, img.Height,
                                             GraphicsUnit.Pixel, ia)

        End Using

    End Using

    Return bmp

End Function

在线C#翻译:

/// <summary>
/// Transforms an image to black and white.
/// </summary>
/// <param name="img">The image.</param>
/// <returns>The black and white image.</returns>
public static Image GetBlackAndWhiteImage(Image img)
{

Bitmap bmp = new Bitmap(img.Width, img.Height);

System.Drawing.Imaging.ColorMatrix grayMatrix  = new ColorMatrix(
        new float[][] {
            new float[] { 0.299f, 0.299f, 0.299f, 0, 0  },
            new float[] { 0.587f, 0.587f, 0.587f, 0, 0  },
            new float[] { 0.114f, 0.114f, 0.114f, 0, 0 },
            new float[] { 0, 0, 0, 1, 0 },
            new float[] { 0, 0, 0, 0, 1}
        }););

using (Graphics g = Graphics.FromImage(bmp)) {

    using (System.Drawing.Imaging.ImageAttributes ia = new System.Drawing.Imaging.ImageAttributes()) {

        ia.SetColorMatrix(grayMatrix);
        ia.SetThreshold(0.5);

        g.DrawImage(img, new Rectangle(0, 0, img.Width, img.Height), 0, 0, img.Width, img.Height, GraphicsUnit.Pixel, ia);

    }

}

return bmp;

}

//=======================================================
//Service provided by Telerik (www.telerik.com)
//=======================================================

@jeanthierry 很高兴能帮助你,但你需要学习的是像素级别的操作(For... Bitmap.GetPixel)比我向你展示的方法慢100倍。 - ElektroStudios

4

我稍微修改了你的代码。因此,浅灰色像素变成纯白色,深灰色像素变成纯黑色。

 Bitmap bmp = new Bitmap(file);
 int width = bmp.Width;
 int height = bmp.Height;
 int[] arr = new int[225];
 int i = 0;
 Color p;

 //Grayscale
 for (int y = 0; y < height; y++)
 {
     for (int x = 0; x < width; x++)
     {
         p = bmp.GetPixel(x,y);
         int a = p.A;
         int r = p.R;
         int g = p.G;
         int b = p.B;
         int avg = (r+g+b)/3;
         avg = avg < 128 ? 0 : 255;     // Converting gray pixels to either pure black or pure white
         bmp.SetPixel(x, y, Color.FromArgb(a, avg ,avg, avg));
     }
 }
 pictureBox2.Image = bmp; 

谢谢Farzan Hajain。这个可行。感谢大家的建议和帮助。 - jeanthierry
@jeanthierry 确保如果其中一个回答解决了你的问题,请将其标记为已接受的答案,欢迎来到 SO,但请阅读规则,谢谢。 - ElektroStudios
请使用 int avg = (int)(0.2989*r + 0.5870*g + 0.1140*b)/3;,因为 int avg = (r+g+b)/3; 是非常错误的! - Dusan

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