2011-05-22 40 views
2

我正在使用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。什麼是比較像素的正確方法?

+0

看起來沒錯。原始圖像絕對是RGB?檢查'im.mode'。如果它不是「RGB」,那就是問題所在。 – andrewdski

回答

4

像素數據比較正確。但是,有兩個問題與邏輯:

  1. 當你與一個行後,應該復位j爲0
  2. 要修改的對象「IM」,而是寫「面具」。

這應該工作(只要你沒有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) 
1

以下函數使用.point方法,並分別適用於所述圖像的每個頻帶:

CVT_TABLE= (255,) + 255 * (0,) 

def do_convert(img): 
    return img.point(CVT_TABLE * len(img.getbands())) 

在每個頻帶上獨立地工作意味着這樣一個圖: new Battlestar Galactica poster
將被轉換成這樣:
colourful result

但是,你可以得到幾乎所有你想要的東西,如果你將圖像轉換爲模式的「L」第一:

CVT_TABLE= (255,) + 255 * (0,) 

def do_convert(img): 
    return img.convert("L").point(CVT_TABLE) 

產生以下結果:
almost but not quite

唯一的缺點是,一些最黑的顏色(例如#000001,最黑的藍色可能)可能會通過模式轉換轉換爲黑色。

+1

夥計們,當你因爲「認爲這個答案沒有用處而失望」時,請寫下解釋原因的評論。 – tzot

1

下面是我如何重寫它,它通過使用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)