使用OpenCv python库

时间:2015-11-17 10:45:24

标签: python opencv numpy encoding base64

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

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">
&#13;
&#13;
&#13;

official doc表示,imread接受文件路径作为参数。从this SO回答,如果我这样做:

 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),但没有返回任何内容。

  2. 从解码后的字符串中获取字节并将其转换为numpy数组

    file_bytes = numpy.asarray(bytearray(imgdata), dtype=numpy.uint8)
    img = cv2.imdecode(file_bytes, 0) #Here as well I get returned nothing
    
  3. 文档并没有真正提到imdecode函数返回的内容。但是,根据我遇到的错误,我猜它期望numpy arrayscalar作为第一个参数。如何在内存中处理该图像,以便我可以在此后执行cv2.imshow('image',img)以及各种酷炫的内容。

    我希望我能说清楚。

3 个答案:

答案 0 :(得分:19)

这对我有用,并且不需要PIL /枕头或任何其他依赖项(cv2除外):

import cv2
import numpy as np

def data_uri_to_cv2_img(uri):
    encoded_data = uri.split(',')[1]
    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(img)

答案 1 :(得分:8)

你可以像这样使用cv2和枕头:

=SUMPRODUCT(--(A1:A15<>A2:A16))

答案 2 :(得分:7)

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

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