【问题标题】:How do you compare pixels?你如何比较像素?
【发布时间】:2016-12-16 04:41:01
【问题描述】:

我正在使用 PIL 拍摄具有黑色背景的图像并用它制作蒙版。我想要程序做的是遍历图像中的所有像素,如果像素为黑色,则将其变为白色,如果是任何其他颜色,则将其变为黑色,但我不确定如何适当地比较像素值以确定什么与像素有关。

到目前为止,这是我创建全黑图像的代码。

import os, sys
import Image

filename = "C:\Users\pdiffley\Dropbox\C++2\Code\Test\BallSpriteImage.bmp"
height   = 50
width    = 50


im = Image.open(filename)
im = im.load()

i = 0
j = 0
while i<height:
    while j<width:
        if im[j,i] == (0,0,0):
            im[j,i] = (255,255,255)
        else:
            im[j,i] = (0,0,0) 
        j = j+1
    i = i+1
mask = Image.new('RGB', (width, height))
newfile = filename.partition('.')
newfile = newfile[0] + "Mask.bmp"

mask.save(newfile)

我认为问题在于 if 语句将 im[j,i] 与 RGB 值 (0,0,0) 进行比较,该值始终为 false。比较像素的正确方法是什么?

【问题讨论】:

  • 看起来不错。原图肯定是RGB的吗?检查im.mode。如果不是“RGB”,那就是问题所在。

标签: python python-imaging-library


【解决方案1】:

像素数据比较正确。但是逻辑有两个问题:

  1. 当你完成一行时,你应该将 j 重置为 0。
  2. 您正在修改对象“im”,但写入“mask”。

这应该可以工作(只要你没有 alpha 通道 - 正如 andrewdski 指出的那样):

img = Image.open(filename)
im = img.load()

i = 0
while i<height:
    j = 0
    while j<width:
        if im[j,i] == (0,0,0):
            im[j,i] = (255,255,255)
        else:
            im[j,i] = (0,0,0) 
        j = j+1
    i = i+1
newfile = filename.partition('.')
newfile = newfile[0] + "Mask.png"

img.save(newfile)

【讨论】:

    【解决方案2】:

    这是我重写它的方法,它通过使用for 循环来避免像素索引重置问题,将数据写入单独的掩码图像而不是返回到源,并删除硬编码的图像大小。我还在文件名字符串中添加了r 前缀来处理其中的反斜杠。

    import os, sys
    import Image
    
    BLACK = (0,0,0)
    WHITE = (255, 255, 255)
    
    filename = r"C:\Users\pdiffley\Dropbox\C++2\Code\Test\BallSpriteImage.bmp"
    
    img = Image.open(filename)
    width, height = img.size
    im = img.load()
    
    mask = Image.new('RGB', (width, height))
    msk = mask.load()
    
    for y in xrange(height):
        for x in xrange(width):
            if im[x,y] == BLACK:
                msk[x,y] = WHITE
            else:  # not really needed since mask's initial color is black
                msk[x,y] = BLACK
    
    newfilename = filename.partition('.')
    newfilename = newfilename[0] + "Mask.bmp"
    mask.save(newfilename)
    

    【讨论】:

      【解决方案3】:

      以下函数使用.point方法,分别作用于图像的每个波段:

      CVT_TABLE= (255,) + 255 * (0,)
      
      def do_convert(img):
          return img.point(CVT_TABLE * len(img.getbands()))
      

      在每个频段上单独工作意味着这样的图片:
      将转换为:

      但是,如果您先将图像转换为“L”模式,您几乎可以得到您想要的:

      CVT_TABLE= (255,) + 255 * (0,)
      
      def do_convert(img):
          return img.convert("L").point(CVT_TABLE)
      

      产生以下结果:

      唯一的缺点是一些最暗的颜色(例如#000001,可能是最深的蓝色)可能会通过模式转换转换为黑色。

      【讨论】:

      • 伙计们,当你因为“认为这个答案没有用”而投反对票时,请写下评论解释原因。
      猜你喜欢
      • 1970-01-01
      • 2013-10-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-28
      • 1970-01-01
      • 2011-01-09
      • 1970-01-01
      相关资源
      最近更新 更多