问题描述
您好,我有很多图像(数百万以下)需要对其进行分类.我正在使用 Spark 并设法将 (filename1, content1), (filename2, content2) ...
格式的所有图像读入一个大 RDD.
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\x0x00\x00\x01\x00\x00\x00\x1a\x01\x05\x00\x01\x00\x00\x00n\x00\x00\x00\x1b\x01\x05\x00\x01\x00\x00\x00\x00\x00\x00\x00(\x01\x03\x00\x01\x00\x00\x00\x02\x00\x00\x001\x01\x02\x00\x0b\x00\x00\x00~\x00\x00\x00\x00\x00x01\x02\x00\x14\x00\x00\x00\ufffd\x00\x00\x00\x13\x02\x03\x00\x01\x00\x00\x00\x01\x00\x00\x00i\ufffd\x00i\ufffdx00\x01\x00\x00\x00\ufffd\x00\x00\x00\x00\x00\x00\x00`\x00\x00\x00\x01\x00\x00\x00`\x00\x00\x00\x01x00\x00\x00GIMP 2.8.2\x00\x002013:07:29 10:41:35\x00\x07\x00\x00\ufffd\x07\x00\x04\x00\x00\x000220\x0002220\x00x00\x04\x00\x00\x00407\x00\x00\ufffd\x07\x00\x04\x00\x00\x000100\x01\ufffd\x03\x00\x01\x00\x00\x00\x00\x00\ufffdx00\x02\ufffd\x04\x00\x01\x00\x00\x00\x04\x04\x00\x00\x03\ufffd\x04\x00\x01\x00\x00\x00X\x01\x00\x00\x00\x00ufffd\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\x07x04\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 \n <exif:Orientation>左上</exif:Orientation>\n <exif:XResolution>96</exif:XResolution>\n <exif:YResolution>96</exif:YResolution>\n \n \n \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:描述 xmlns:exif=\'http://ns.adobe.com/exif/1.0/\'>\n<exif:Orientation>左上</exif:Orientation>\n<exif:XResolution>96</exif:XResolution>\n<exif:YResolution>96</exif:YResolution>\n...我以前的经验是使用包 scipy 和相关函数,如imread"……输入通常是文件名.现在我真的迷失了这些 unicode 的含义以及我可以做些什么来将其转换为我熟悉的格式.
谁能与我分享如何将这些 unicode 读入 scipy 图像(ndarray)?
您的数据看起来像是来自真实图像文件 (JPG?) 的原始字节.您的数据的问题在于它应该是字节,而不是 unicode.您必须弄清楚如何从 unicode 转换为字节.您必须处理一整罐充满编码陷阱的蠕虫,但使用 img.encode('iso-8859-1')
可能会很幸运.我不知道,我不会在回答中处理这个问题.
PNG 图像的原始数据如下所示:
rawdata = '\x89PNG\r\n\x1a\n\x00\x00...\x00\x00IEND\xaeB`\x82'
以字节为单位获得后,您可以从原始数据创建 PIL 图像,并将其作为 nparray 读取:
>>>从 StringIO 导入 StringIO>>>从 PIL 导入图像>>>将 numpy 导入为 np>>>np.asarray(Image.open(StringIO(rawdata)))数组([[[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)要使其在 Spark 上运行,您只需SparkContext.binaryFiles
:
Hi there I have a lot of images (lower millions) that I need to do classification on. I am using Spark and managed to read in all the images in the format of (filename1, content1), (filename2, content2) ...
into a big RDD.
images = sc.wholeTextFiles("hdfs:///user/myuser/images/image/00*")
However, I got really confused what to do with the unicode representation of the image.
Here is an example of one image/file:
(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
Looking closer, there are actually some characters look like the metadata like
...
<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
...
My previous experience was using the package scipy and related functions like 'imread' ... and the input is usually a filename. Now I really got lost what does those unicode mean and what I can do to transform it into a format that I am familiar with.
Can anyone share with me how can I read in those unicode into a scipy image (ndarray)?
Your data looks like the raw bytes from a real image file (JPG?). The problem with your data is that it should be bytes, not unicode. You have to figure out how to convert from unicode to bytes. There is a whole can of worms full of encoding traps you have to deal with, but you may be lucky using img.encode('iso-8859-1')
. I don't know and I will not deal with that in my answer.
The raw data for a PNG image looks like this:
rawdata = '\x89PNG\r\n\x1a\n\x00\x00...\x00\x00IEND\xaeB`\x82'
Once you have it in bytes, you can create a PIL image from the raw data, and read it as a 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)
All you need to make it work on Spark is 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)
这篇关于Spark 使用 PySpark 读取图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!