2011-09-29 26 views
4

我是新來的圖像處理與Python和遇到一個奇怪的問題。如何將PIL和numpy之間模式爲「1」的圖像進行轉換?

比如我有哪些像素下一個2 * 2的黑白位圖圖像:

黑白色

白黑

使用PIL並將其轉換爲NumPy的:

>>> import Image 
>>> import numpy 
>>> im = Image.open('test.bmp') 
>>> im 
<BmpImagePlugin.BmpImageFile image mode=1 size=2x2 at 0x95A54EC> 
>>> numpy.asarray(im) 
array([[ True, True], 
     [False, False]], dtype=bool) 
>>> 

讓我困惑的是像素的順序陣列。爲什麼不是[[True, False], [False, True]]?謝謝。


UPDATE:位圖是在這裏: http://njuer.us/clippit/test.bmp

+0

你可以張貼位圖? – jterrace

+0

http://njuer.us/clippit/test.bmp,由GIMP製作 – Clippit

回答

3

它看起來像有一些錯誤與轉換到/從numpy的與1模式。

如果你將其轉換爲L第一,它工作正常:

>>> im 
<BmpImagePlugin.BmpImageFile image mode=1 size=2x2 at 0x17F17E8> 
>>> im2 = im.convert('L') 
>>> numpy.asarray(im2) 
array([[ 0, 255], 
     [255, 0]], dtype=uint8) 

另外,如果你嘗試轉換bool numpy的陣列到PIL,你得到奇怪的結果:

>>> testarr = numpy.array([[True,False],[True,False]], dtype=numpy.bool) 
>>> testpil = Image.fromarray(testarr, mode='1') 
>>> numpy.asarray(testpil) 
array([[False, False], 
     [False, False]], dtype=bool) 

然而與uint8完全一樣的事情正常工作:

>>> testarr = numpy.array([[255,0],[0,255]], dtype=numpy.uint8) 
>>> Image.fromarray(testarr) 
<Image.Image image mode=L size=2x2 at 0x1B51320> 
>>> numpy.asarray(Image.fromarray(testarr)) 
array([[255, 0], 
     [ 0, 255]], dtype=uint8) 

所以我建議使用L作爲中間數據類型,然後在保存前轉換爲1,如果您需要將其保存爲該格式。事情是這樣的:

>>> im 
<BmpImagePlugin.BmpImageFile image mode=1 size=2x2 at 0x17F17E8> 
>>> im2 = im.convert('L') 
>>> arr = numpy.asarray(im2) 
>>> arr 
array([[ 0, 255], 
     [255, 0]], dtype=uint8) 
>>> arr = arr == 255 
>>> arr 
array([[False, True], 
     [ True, False]], dtype=bool) 

然後轉換回:

>>> backarr = numpy.zeros(arr.shape, dtype=numpy.uint8) 
>>> backarr[arr] = 255 
>>> backarr 
array([[ 0, 255], 
     [255, 0]], dtype=uint8) 
>>> Image.fromarray(backarr).convert('1') 
<Image.Image image mode=1 size=2x2 at 0x1B41CB0> 
+0

'Image.fromarray'有一個參數'mode'。 'Image.fromarray(testarr,mode ='1')'毫無例外地工作。但我不知道PIL是否正確處理它。它真的是一個錯誤嗎? – Clippit

+0

@Clippit謝謝你指出。仍然看起來破碎 - 更新了我的答案 – jterrace

相關問題