使用 OpenCv python 库从内存中读取 base 64 编码图像

新手上路,请多包涵

我正在开发一款可以从网络摄像头流中进行面部识别的应用程序。我得到了画布的 base64 编码数据 uri,并想用它来做这样的事情:

 cv2.imshow('image',img)

数据 URI 看起来像这样:

  data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7

因此,为了清楚起见,我已经展示了图像的外观,因此 base64 字符串没有被破坏。

 <img src="data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7">

官方文档 说, imread 接受文件路径作为参数。从 这个 SO answer 中,如果我做类似的事情:

  import base64
 imgdata = base64.b64decode(imgstring) #I use imgdata as this variable itself in references below
 filename = 'some_image.jpg'
 with open(filename, 'wb') as f:
    f.write(imgdata)

上面的代码片段有效,图像文件得到正确生成。但是,考虑到我会对流的每一帧都执行此操作,我认为这么多文件 IO 操作是不可行的。我希望能够直接创建 img 对象将图像读入内存。

我尝试了两种似乎对某些人有效的解决方案。

  1. 使用 PIL 参考
    pilImage = Image.open(StringIO(imgdata))
   npImage = np.array(pilImage)
   matImage = cv.fromarray(npImage)

我得到 cv not defined 因为我安装了 openCV3,我可以使用 cv2 模块。我试过 img = cv2.imdecode(npImage,0) ,这没有任何回报。

  1. 从解码的字符串中获取字节并将其转换为各种 numpy 数组
   file_bytes = numpy.asarray(bytearray(imgdata), dtype=numpy.uint8)
   img = cv2.imdecode(file_bytes, 0) #Here as well I get returned nothing

该文档并没有真正提到 imdecode 函数返回的内容。但是,根据我遇到的错误,我猜它期望 numpy arrayscalar 作为第一个参数。我如何在内存中获取该图像的句柄,以便我可以执行 cv2.imshow('image',img) 以及之后的各种很酷的东西。

我希望我能说清楚。

原文由 Vivek Pradhan 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 784
2 个回答

你可以像这样同时使用 cv2 和 pillow :

 import base64
from PIL import Image
import cv2
from StringIO import StringIO
import numpy as np

def readb64(base64_string):
    sbuf = StringIO()
    sbuf.write(base64.b64decode(base64_string))
    pimg = Image.open(sbuf)
    return cv2.cvtColor(np.array(pimg), cv2.COLOR_RGB2BGR)

cvimg = readb64('R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7')
cv2.imshow(cvimg)

原文由 Jonno_FTW 发布,翻译遵循 CC BY-SA 3.0 许可协议

这是我的 python 3.7 解决方案,不使用 PIL

 import base64

def readb64(uri):
   encoded_data = uri.split(',')[1]
   nparr = np.fromstring(base64.b64decode(encoded_data), np.uint8)
   img = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
   return img

我希望这个解决方案适用于所有人

原文由 Javier Vallejos 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题