Spark 使用 PySpark 读取图像 [英] Spark using PySpark read images

查看:149
本文介绍了Spark 使用 PySpark 读取图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好,我有很多图像(数百万以下)需要对其进行分类.我正在使用 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 <;exif:ResolutionUnit>英寸</exif:ResolutionUnit>\n <exif:Software>ACD 系统数字成像</exif:Software>\n <exif:DateTime>2013:07:29 10:37:00</exif:DateTime>\n <exif:YCbCrPositioning>居中</exif:YCbCrPositioning>\n <exif:ExifVersion>Exif Version 2.2</exif:ExifVersion>\n <exif:SubsecTime>/exif<:SubsecTime>\n FlashPix 版本 1.0\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"……输入通常是文件名.现在我真的迷失了这些 un​​icode 的含义以及我可以做些什么来将其转换为我熟悉的格式.

谁能与我分享如何将这些 un​​icode 读入 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:

<预><代码>>>>images = sc.binaryFiles("path/to/images/")>>>image_to_array = lambda 原始数据:np.asarray(Image.open(StringIO(rawdata)))>>>images.values().map(image_to_array)

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 读取图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆