2015-10-15 68 views
6

嗨,我有很多圖像(低百萬),我需要做分類。我正在使用Spark,並設法將(filename1, content1), (filename2, content2) ...格式的所有圖像讀入大型RDD。使用PySpark的火花閱讀圖像

images = sc.wholeTextFiles("hdfs:///user/myuser/images/image/00*") 

但是,我真的很困惑如何處理圖像的unicode表示。

這裏是一個圖像/文件的例子:

(u'hdfs://NameService/user/myuser/images/image/00product.jpg', u'\ufffd\ufffd\ufffd\ufffd\x00\x10JFIF\x00\x01\x01\x01\x00`\x00`\x00\x00\ufffd\ufffd\x01\x1eExif\x00\x00II*\x00\x08\x00\x00\x00\x08\x00\x12\x01\x03\x00\x01\x00\x00\x00\x01\x00\x00\x00\x1a\x01\x05\x00\x01\x00\x00\x00n\x00\x00\x00\x1b\x01\x05\x00\x01\x00\x00\x00v\x00\x00\x00(\x01\x03\x00\x01\x00\x00\x00\x02\x00\x00\x001\x01\x02\x00\x0b\x00\x00\x00~\x00\x00\x002\x01\x02\x00\x14\x00\x00\x00\ufffd\x00\x00\x00\x13\x02\x03\x00\x01\x00\x00\x00\x01\x00\x00\x00i\ufffd\x04\x00\x01\x00\x00\x00\ufffd\x00\x00\x00\x00\x00\x00\x00`\x00\x00\x00\x01\x00\x00\x00`\x00\x00\x00\x01\x00\x00\x00GIMP 2.8.2\x00\x002013:07:29 10:41:35\x00\x07\x00\x00\ufffd\x07\x00\x04\x00\x00\x000220\ufffd\ufffd\x02\x00\x04\x00\x00\x00407\x00\x00\ufffd\x07\x00\x04\x00\x00\x000100\x01\ufffd\x03\x00\x01\x00\x00\x00\ufffd\ufffd\x00\x00\x02\ufffd\x04\x00\x01\x00\x00\x00\x04\x04\x00\x00\x03\ufffd\x04\x00\x01\x00\x00\x00X\x01\x00\x00\x05\ufffd\x04\x00\x01\x00\x00\x00\ufffd\x00\x00\x00\x00\x00\x00\x00\x02\x00\x01\x00\x02\x00\x04\x00\x00\x00R98\x00\x02\x00\x07\x00\x04\x00\x00\x000100\x00\x00\x00\x00\ufffd\ufffd\x04_http://ns.adobe.com/xap/1.0/\x00<?xpacket begin=\'\ufeff\' id=\'W5M0MpCehiHzreSzNTczkc9d\'?>\n<x:xmpmeta xmlns:x=\'adobe:ns:meta/\'>\n<rdf:RDF xmlns:rdf=\'http://www.w3.org/1999/02/22-rdf-syntax-ns#\'>\n\n <rdf:Description xmlns:exif=\'http://ns.adobe.com/exif/1.0/\'>\n <exif:Orientation>Top-left</exif:Orientation>\n <exif:XResolution>96</exif:XResolution>\n <exif:YResolution>96</exif:YResolution>\n <exif:ResolutionUnit>Inch</exif:ResolutionUnit>\n <exif:Software>ACD Systems Digital Imaging</exif:Software>\n <exif:DateTime>2013:07:29 10:37:00</exif:DateTime>\n <exif:YCbCrPositioning>Centered</exif:YCbCrPositioning>\n <exif:ExifVersion>Exif Version 2.2</exif:ExifVersion>\n <exif:SubsecTime>407</exif:SubsecTime>\n <exif:FlashPixVersion>FlashPix Version 1.0</exif:FlashPixVersion>\n <exif:ColorSpace>Uncalibrated</exif:ColorSpace>\n 

更仔細地觀察,其實有一些字符看起來像

... 
<x:xmpmeta xmlns:x=\'adobe:ns:meta/\'>\n<rdf:RDF xmlns:rdf=\'http://www.w3.org/1999/02/22-rdf-syntax-ns#\'>\n\n 
<rdf:Description xmlns:exif=\'http://ns.adobe.com/exif/1.0/\'>\n 
<exif:Orientation>Top-left</exif:Orientation>\n 
<exif:XResolution>96</exif:XResolution>\n 
<exif:YResolution>96</exif:YResolution>\n 
... 

我以前的經驗,元數據是使用包SciPy的和相關的功能,如'imread'...並且輸入通常是一個文件名。現在我真的迷失了那些unicode的意思,我能做些什麼來將它轉換成我熟悉的格式。

任何人都可以與我分享如何讀取這些Unicode到一個scipy圖像(ndarray)?

+0

有趣的問題+1 –

+0

嘗試使用imread映射RDD。我認爲這應該工作。詳細說明:我對JPEG格式不熟悉,但每個圖像都變成了一個文件,並且具有特定的格式,您可以使用imread等函數來簡化對複雜圖像方案的操作。 – Dair

+0

@閱讀[imread]的源代碼(https://github.com/scipy/scipy/blob/v0.16.0/scipy/misc/pilutil.py#L102),它確實試圖讀取圖像給定文件名的PIL.Image,強制imread讀取unicode不起作用。 –

回答

4

您的數據看起來像來自真實圖像文件(JPG?)的原始字節。你的數據的問題是它應該是字節,而不是unicode。你必須弄清楚如何從unicode轉換爲字節。有一整套蠕蟲需要處理編碼陷阱,但使用img.encode('iso-8859-1')可能是幸運的。我不知道,我不會在我的回答中處理這個問題。

一個PNG圖像的原始數據是這樣的:

rawdata = '\x89PNG\r\n\x1a\n\x00\x00...\x00\x00IEND\xaeB`\x82' 

一旦你以字節爲單位擁有它,你可以創建一個從原始數據PIL圖像,並把它讀作一個nparray:

>>> from StringIO import StringIO 
>>> from PIL import Image 
>>> import numpy as np 
>>> np.asarray(Image.open(StringIO(rawdata))) 

array([[[255, 255, 255, 0], 
    [255, 255, 255, 0], 
    [255, 255, 255, 0], 
    ..., 
    [255, 255, 255, 0], 
    [255, 255, 255, 0], 
    [255, 255, 255, 0]]], dtype=uint8) 

所有你需要使它在星火工作是SparkContext.binaryFiles

>>> images = sc.binaryFiles("path/to/images/") 
>>> image_to_array = lambda rawdata: np.asarray(Image.open(StringIO(rawdata))) 
>>> images.values().map(image_to_array) 
+0

我真的很喜歡StringIO的方法,這也被記錄[這裏](http://effbot.org/imagingbook/image.htm#tag-Image.open),然而,把怪異的Unicode變成字節可能是棘手的部分。 'utf-8'和'iso-8859-1'都不起作用。投票通過:) –

+0

歡迎來到unicode地獄和祝你好運,隊友! –

+0

@PauloScardine你介意我是否進行編輯並將其轉換爲完整答案? – zero323