如何比较像素?
我正在使用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)进行比较,但这个比较总是返回假。我想知道正确的比较像素的方法是什么。
3 个回答
1
下面这个函数使用了 .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
,这是可能的最深蓝色)可能会在模式转换时被变成黑色。
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)
4
像素数据的比较是正确的。但是逻辑上有两个问题:
- 当你处理完一行时,应该把 j 重置为 0。
- 你在修改对象 "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)