使用 OpenCv python 库从内存中读取 base 64 编码图像
Read a base 64 encoded image from memory using OpenCv python library
我正在开发一个应用程序,可以从网络摄像头流中进行面部识别。我得到 canvas 的 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 says, that imread
accepts a file path as the argument. From 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
对象将图像读入内存。
我尝试了两种似乎对某些人有效的解决方案。
使用 PIL reference:
pilImage = Image.open(StringIO(imgdata))
npImage = np.array(pilImage)
matImage = cv.fromarray(npImage)
我得到 cv
not defined 因为我安装了 openCV3,它可以作为 cv2
模块使用。我试了img = cv2.imdecode(npImage,0)
,这个returns什么都没有。
从解码的字符串中获取字节并将其转换为各种 numpy 数组
file_bytes = numpy.asarray(bytearray(imgdata), dtype=numpy.uint8)
img = cv2.imdecode(file_bytes, 0) #Here as well I get returned nothing
文档并没有真正提到 imdecode
函数 returns 是什么。但是,从我遇到的错误来看,我猜它期望 numpy array
或 scalar
作为第一个参数。我如何在内存中处理该图像,以便我可以做 cv2.imshow('image',img)
以及之后的各种很酷的事情。
我希望我能说清楚。
你可以像这样同时使用 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)
这在 python 2 上对我有用,不需要 PIL/pillow 或任何其他依赖项(cv2 除外):
编辑:python3 使用 base64.b64decode(encoded_data)
解码。
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)
这是我针对 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
我希望这个解决方案适用于所有人
我找到了这个简单的解决方案。
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
我正在开发一个应用程序,可以从网络摄像头流中进行面部识别。我得到 canvas 的 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 says, that imread
accepts a file path as the argument. From 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
对象将图像读入内存。
我尝试了两种似乎对某些人有效的解决方案。
使用 PIL reference:
pilImage = Image.open(StringIO(imgdata)) npImage = np.array(pilImage) matImage = cv.fromarray(npImage)
我得到
cv
not defined 因为我安装了 openCV3,它可以作为cv2
模块使用。我试了img = cv2.imdecode(npImage,0)
,这个returns什么都没有。从解码的字符串中获取字节并将其转换为各种 numpy 数组
file_bytes = numpy.asarray(bytearray(imgdata), dtype=numpy.uint8) img = cv2.imdecode(file_bytes, 0) #Here as well I get returned nothing
文档并没有真正提到 imdecode
函数 returns 是什么。但是,从我遇到的错误来看,我猜它期望 numpy array
或 scalar
作为第一个参数。我如何在内存中处理该图像,以便我可以做 cv2.imshow('image',img)
以及之后的各种很酷的事情。
我希望我能说清楚。
你可以像这样同时使用 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)
这在 python 2 上对我有用,不需要 PIL/pillow 或任何其他依赖项(cv2 除外):
编辑:python3 使用 base64.b64decode(encoded_data)
解码。
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)
这是我针对 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
我希望这个解决方案适用于所有人
我找到了这个简单的解决方案。
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