2015-10-15 2 views
6

Привет, у меня есть много изображений (более низкие миллионы), которые мне нужно сделать для классификации. Я использую Spark и умею читать все изображения в формате (filename1, content1), (filename2, content2) ... в большом RDD.Spark using PySpark читать изображения

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

Однако, я действительно запутался в том, что делать с представлением изображения в Юникоде.

Вот пример одного изображения/файла:

(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 и что я могу сделать, чтобы преобразовать его в формат, который мне знаком.

Может ли кто-нибудь поделиться со мной, как я могу читать эти юникоды в scipy-изображении (ndarray)?

+0

Интересный вопрос +1 –

+0

Попробуйте сопоставить RDD с imread. Я думаю, что это должно сработать. Чтобы уточнить: я не знаком с форматом JPEG, но каждое изображение становится файлом и имеет определенный формат, в котором вы используете такие функции, как imread, чтобы упростить манипуляцию сложными схемами изображения. – Dair

+0

@Dair, читающий исходный код [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), однако превращение странного юникода в байты, вероятно, является сложной частью. Оба «utf-8» и «iso-8859-1» не работали. Проголосовал, хотя :) –

+0

Добро пожаловать в юникод ад и удачи, приятель! –

+0

@PauloScardine Не могли бы вы сделать редактирование и превратить его в полный ответ? – zero323

Смежные вопросы