首页 > 解决方案 > OpenCV 从 pyspark 读取图像并传递给 Keras 模型

问题描述

这是此处发布的答案的后续问题。我正在使用 PySpark 2.4.4。我有一堆图像(一些 .png 一些 .jpeg)存储在谷歌云存储(GCS)上,我需要将它们传递给 Tensorflow 模型。我得到这样的图像。

images = spark.read.format("image").option("dropInvalid", False).load("gs://my-bucket/my_image.jpg")
images = images.collect()
image = cv2.imdecode(np.frombuffer(images[0].image.data, np.uint8), cv2.IMREAD_COLOR)

根据我读过的 OpenCV 文档,OpenCV 似乎无法理解我的数据格式。我知道这是因为cv2.imdecode(...)返回None。Spark 官方文档明确提到了与 OpenCV 的兼容性,所以我知道这是可能的。

最终我希望能够做到这一点。

prediction = model.predict(np.array([image]))[0]

在 Spark 之外,如果我不是从 GCS 而是从 http 端点获取图像,我所要做的就是这个,它可以工作。

resp = urllib.request.urlopen(image_url)
image = resp.read()
prediction = model.predict(np.array([image]))[0]

np.array([...])为了更好地了解模型正在寻找什么,这是数据在传递到零件之前应该是什么样子。

print(resp.read())
>>> b'\xff\xd8\xff\xe0\x00\x10JFIF\x00\x01\x01\x00\x00\x01\x00\x01\ ...'

我可以确认图像在 GCS 上时没有损坏。当我从 GCS 下载相同的图像到我的笔记本电脑,然后像这样阅读它时,我得到了一个类似的格式。该模型也能够以这种方式使用图像。我还目视检查了下载的 GCS 图像,它看起来不错。

with open("./my_image.jpeg", "rb") as image:
    print(image.read())
>>> b'\xff\xd8\xff\xe0\x00\x10JFIF\x00\x01\x01\ ...'

标签: pythonnumpyapache-sparkopencvpyspark

解决方案


不确定这是否是您正在寻找的,但我能够通过将 PIL 图像转换为 cv2 图像来实现。

火花加载:

images = sc.binaryFiles('/tmp/images/*', 10)
df = images.map(lambda img: extract_line_coords(img)).toDF()
df.show(5, False)

功能

def extract_line_coords(binary_images):
    name, img = binary_images
    pil_image = Image.open(io.BytesIO(img)).convert('RGB') 
    cv2_image = numpy.array(pil_image) 
    cv2_image = cv2_image[:, :, ::-1].copy() 
    gray     = cv2.cvtColor(cv2_image, cv2.COLOR_BGR2GRAY)
    ...
    ...

参考:将图像从 PIL 转换为 openCV 格式


推荐阅读