numpy 使用OpenCv python库从内存中读取base64编码的图像

3phpmpom  于 2023-06-23  发布在  Python
关注(0)|答案(4)|浏览(143)

我正在开发一个应用程序,可以通过网络摄像头进行面部识别。我得到画布的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">

official doc表示,imread接受文件路径作为参数。从this所以答案,如果我做这样的事情:

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 reference

pilImage = Image.open(StringIO(imgdata))
npImage = np.array(pilImage)
matImage = cv.fromarray(npImage)

我没有定义cv,因为我安装了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)以及此后的各种很酷的操作。
我希望我说得够清楚了。

uujelgoq

uujelgoq1#

这是我针对python3.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

我希望这个解决方案对所有人都有效

xriantvc

xriantvc2#

(Edit:Updated for python 3)这在python 3上对我有效,并且不需要PIL/pillow或任何其他依赖项(除了cv2):

import cv2
import numpy as np
import base64

def data_uri_to_cv2_img(uri):
    encoded_data = uri.split(',')[1]
    nparr = np.frombuffer(base64.b64decode(encoded_data), np.uint8)
    # old (python 2 version):
    # nparr = np.fromstring(encoded_data.decode('base64'), np.uint8)

    img = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
    return img

data_uri = "data:image/jpeg;base64,/9j/4AAQ..."
img = data_uri_to_cv2_img(data_uri)
cv2.imshow("Image", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
zmeyuzjn

zmeyuzjn3#

你可以像这样使用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)
klsxnrf1

klsxnrf14#

我找到了这个简单的解决办法。

import cv2
import numpy as np
import base64
image = ""  # raw data with base64 encoding
decoded_data = base64.b64decode(image)
np_data = np.fromstring(decoded_data,np.uint8)
img = cv2.imdecode(np_data,cv2.IMREAD_UNCHANGED)
cv2.imshow("test", img)
cv2.waitKey(0)

来源:https://gist.github.com/HoweChen/7cdd09b08147133d8e1fbe9b52c24768

相关问题