分别获取位图图像中黑色和白色像素的总数

3
我正在尝试编写一段代码,它会逐行扫描我的图像,并告诉我图像中有多少个白色和黑色像素?(假设我的图像是由黑色字符与白色背景组成的)
var backgroundPixels = 0;

     for (int x = 0; x < bmp.Width; x++)
            {
                for (int y = 0; y < bmp.Height; y++)
                {
                    if (bmp.GetPixel(x, y).Equals(Color.White))
                    {
                        backgroundPixels++;
                    }
                }

            }
            label3.Text = Convert.ToString(backgroundPixels);

我遇到了问题,代码出现了故障。有人能帮我吗?


我已经编辑了你的标题。请参见"问题的标题应该包含“标签”吗?",在那里达成共识是“不应该”。 - chridam
1
你能详细描述一下当前观察到的行为吗? - Dave Van den Eynde
3
“doesn't work” 指什么?是崩溃了吗?数值与实际不符吗?无法解析所有像素吗? - Andrei V
尝试使用 bmp.GetPixel(x, y)RGB - Nitin Varpe
“doesn’t work” 有一个名称吗?比如说异常(exception)? - sasjaq
1
你可以在 MS Paint 中玩一下,创建一个控制图像,以查看它是否真的迭代了所有像素,并且值是否正确递增。 - Andrei V
3个回答

4
当你使用==Equals时,你并不是逐个比较ARGB的字节值,因为'=='运算符是这样处理的。
     public static bool operator ==(Color left, Color right)
        {
          if (left.value != right.value || (int) left.state != (int) right.state || (int) left.knownColor != (int) right.knownColor)
            return false;
          if (left.name == right.name)
            return true;
          if (left.name == null || right.name == null)
            return false;
          else
            return left.name.Equals(right.name);
        }

以下是在.NET中如何实现Equals方法的方式:
public override bool Equals(object obj)
    {
      if (obj is Color)
      {
        Color color = (Color) obj;
        if (this.value == color.value && (int) this.state == (int) color.state && (int) this.knownColor == (int) color.knownColor)
        {
          if (this.name == color.name)
            return true;
          if (this.name == null || color.name == null)
            return false;
          else
            return this.name.Equals(this.name);
        }
      }
      return false;
    }

要解决您的问题,应使用ToArgb()函数将颜色转换为ARGB,并发送当前颜色的32位数据。

 private void button1_Click(object sender, EventArgs e)
        {

            int whiteColor = 0;
            int blackColor = 0; 
            for (int x = 0; x < bmp.Width; x++)
            {
                for (int y = 0; y < bmp.Height; y++)
                {
                    Color color = bmp.GetPixel(x, y); 

                    if (color.ToArgb()==Color.White.ToArgb())
                    {
                        whiteColor++;  
                    }

                    else
                        if (color.ToArgb() == Color.White.ToArgb())
                        {
                            blackColor++; 
                        }
                }

            }
        }

3
它不起作用是因为你正在比较颜色结构体:
if (bmp.GetPixel(x, y).Equals(Color.White))

结构体的“Name”成员在像素上不会是“White”,而是包含十六进制值“ffffff”的字符串,因此即使ARGB值相同,对象仍然不同。你需要比较ARGB值。Color结构体就是这么愚蠢。

if (bmp.GetPixel(x, y).ToArgb().Equals(Color.White.ToArgb()))

另一种可能是您的像素实际上不是黑白而是灰度。

那么我应该如何首先获取一个清晰的黑白位图像素?(不是灰度) - CowBoy
你甚至不需要这样做,你可以只检查值是否高于或低于某个阈值,而不是检查它们是否为255或0。例如,<= 127 = 黑色,> 127 = 白色。如果是灰度图像,则所有组件应该相同,因此您只需检查其中一种颜色即可。 - svinja
svinja:感谢您的评论,实际上我需要将图像转换为黑白以进行下一阶段的工作,您能告诉我如何做吗?谢谢。 - CowBoy

1
Equals()方法比较的不仅仅是ARGB颜色,这意味着RGB=0,0,0(黑色)的颜色与Color.Black不同。尝试使用以下内容进行比较:
if (bmp.GetPixel(x, y).ToArgb().Equals(Color.White.ToArgb()))

或者

if (bmp.GetPixel(x, y).ToArgb() == Color.White.ToArgb())

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