【问题标题】:convert image to Black-White or Sepia in c#在c#中将图像转换为黑白或棕褐色
【发布时间】:2011-06-05 05:31:38
【问题描述】:

我想将图像更改为黑白或棕褐色。 转换图像后,我想用转换后的图像替换现有图像。

请给我一些建议。

【问题讨论】:

    标签: image-processing c#-3.0


    【解决方案1】:

    有很多方法可以去饱和彩色图像。事实上,可能没有一种“正确”或“正确”的方法可以做到这一点,尽管有些方法比其他方法更“正确”。
    我假设您的图像是 RGB(红-绿-蓝)格式(尽管 BGR 也很常见)。

    最简单的方法应该适用于大多数照片(但对合成图像不太适用),即只使用 3 个 RGB 通道的绿色通道。人类对光谱中绿色部分的变化最为敏感,因此绿色通道覆盖了大部分可见范围,非常接近您想要的灰度图像。

    生成灰度图像的更好方法是使用 3 个 RGB 通道的加权平均值。选择相等的权重 (0.33*R+0.33*G+0.33*B) 将给出一个非常好的灰度图像。其他凸权重(总和为 1 的非负权重)将给出不同的结果,其中一些可能被认为更美观,一些可能会考虑感知参数。 (YUV uses these weights:Y = 0.299*R + 0.587*G + 0.114*B)

    您始终可以将图像转换为只有一个单个灰度通道(和 2 个“颜色”通道)的颜色空间,例如 HSV(V 是灰度)、YUV(Y 是灰度)或 Lab(L 为灰度)。差异应该不会很大。

    “去饱和”一词来自 HSV 空间。如果将图像转换为 HSV,将 S 通道(饱和度)设置为全零,然后渲染图像,您将获得 3 通道去饱和“彩色”图像。

    将这些灰度通道复制到 RGB 中将为您提供一个 3 通道去饱和“颜色”图像 - 其中所有 3 个 RGB 通道都是相同的。

    一旦您有了这张 3 通道 (RGB) 去饱和图像,您就可以将每个通道乘以一个单独的权重来为图像着色 - 棕褐色图像。

    给定一个灰色像素[v,v,v],将其着色为:[v*a, v*b, v*c],这样0 <= a,b,c <=1

    【讨论】:

      【解决方案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;
      

      【讨论】:

      • 为什么用这些值来乘以组件?这会给棕褐色吗?我怀疑确实如此,但解释一下会很有用。
      • 红色 (255,0,0) 绿色 (0,255,0) 蓝色 (0,0,255) 它们一起形成白色,即 255,255,255。如果使用纯 RGB 使用上述公式计算,结果接近 255。
      【解决方案3】:

      对于棕褐色,您首先要转换为灰度。然后只需将每个像素乘以一组缩放三元组,例如 [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);
           }
       }
      

      【讨论】:

        【解决方案4】:

        在这里我找到了很好的答案: https://social.msdn.microsoft.com/Forums/vstudio/en-US/1d6b5960-c509-433c-b000-c885b8c727c4/how-to-convert-an-image-to-black-and-white-not-grayscale?forum=csharpgeneral&prof=required

        var color = new Bitmap("file.jpg");
        var bw = color.Clone(new Rectangle(0, 0, color.Width, color.Height), 
              PixelFormat.Format1bppIndexed);
        

        【讨论】:

        • 这种转换很好,很快(GetPixel/SetPixel的方法很慢),而且简单,但有两个主要问题。黑/白(1 像素)转换的结果很糟糕,当源图像中有透明背景时,它会变成黑色。第二个问题是即使已经在˙color˙ 图像上调用了Dispose 方法,文件(在这种情况下为file.jpg)也会被锁定。最好在图形中使用DrawImage 方法。 (此评论不是针对 Serov Danil 的,而是针对其他程序员的)
        【解决方案5】:
        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;
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-05-07
          • 1970-01-01
          • 2011-09-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多