我有一个原始图像,其中每个像素对应一个16位无符号整数.我试图使用PIL Image.fromstring()函数读取,如下面的代码:
if __name__ == "__main__":
if (len(sys.argv) != 4):
print 'Error: missing input argument'
sys.exit()
file = open(sys.argv[1], 'rb')
rawData = file.read()
file.close()
imgSize = (int(sys.argv[2]), int(sys.argv[3]))
# Use the PIL raw decoder to read the data.
# - the 'F;16' informs the raw decoder that we are reading a little endian, unsigned integer 16 bit data.
img = Image.fromstring('L', imgSize, rawData, 'raw', 'F;16')
im.save('out.png')
Run Code Online (Sandbox Code Playgroud)
PIL文档通知fromstring()函数的第一个参数是'mode'.然而,看文档和谷歌搜索,我无法找到有关该论点真正意义的细节(我相信它与色彩空间或类似的东西有关).有谁知道我在哪里可以找到关于fromstring()函数的更详细的参考以及mode参数的含义?
我正在开发一个应用程序,可以从网络摄像头流中进行面部识别.我得到了画布的base64编码数据uri,并希望用它来做这样的事情:
cv2.imshow('image',img)
Run Code Online (Sandbox Code Playgroud)
数据URI看起来像这样:
data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7
Run Code Online (Sandbox Code Playgroud)
所以,为了清楚起见,我已经显示了图像的样子,因此base64字符串没有被破坏.
<img src="data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7">
Run Code Online (Sandbox Code Playgroud)
在官方文档说,是imread
接受作为参数的文件路径.从这个 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)
Run Code Online (Sandbox Code Playgroud)
上面的代码片段可以正常工作,并且可以正确生成图像文件.但是,我不认为这么多文件IO操作是可行的,因为我会为流的每一帧执行此操作.我希望能够将图像直接读入内存中创建img
对象.
我尝试了两种似乎适用于某些人的解决方案.
使用PIL 参考:
pilImage = Image.open(StringIO(imgdata))
npImage = np.array(pilImage)
matImage = cv.fromarray(npImage)
Run Code Online (Sandbox Code Playgroud)
我cv
没有定义,因为我安装了openCV3,我可以将其作为cv2
模块使用.我试过img = cv2.imdecode(npImage,0)
,这什么都没有.
从解码的字符串中获取字节并将其转换为numpy数组
file_bytes = numpy.asarray(bytearray(imgdata), dtype=numpy.uint8)
img = cv2.imdecode(file_bytes, 0) #Here as well I get returned nothing
Run Code Online (Sandbox Code Playgroud)文档没有真正提到 …
我能够从zip成功加载图像:
with zipfile.ZipFile('test.zip', 'r') as zfile:
data = zfile.read('test.jpg')
# how to open this using imread or imdecode?
Run Code Online (Sandbox Code Playgroud)
问题是:如何在不保存图像的情况下使用imread或imdecode在opencv中进一步处理?
更新:
这是我得到的预期错误.我需要将'data'转换为opencv可以使用的类型.
data = zfile.read('test.jpg')
buf = StringIO.StringIO(data)
im = cv2.imdecode(buf, cv2.IMREAD_GRAYSCALE)
# results in error: TypeError: buf is not a numpy array, neither a scalar
a = np.asarray(buf)
cv2.imdecode(a, cv2.IMREAD_GRAYSCALE)
# results in error: TypeError: buf data type = 17 is not supported
Run Code Online (Sandbox Code Playgroud) 我有一个.tar
包含数百张图片的文件(.png
).我需要通过opencv处理它们.
我想知道 - 出于效率原因 - 是否可以在不经过光盘的情况下处理它们.换句话说,我想从与tar文件相关的内存流中读取图片.
考虑一下
import tarfile
import cv2
tar0 = tarfile.open('mytar.tar')
im = cv2.imread( tar0.extractfile('fname.png').read() )
Run Code Online (Sandbox Code Playgroud)
最后一行不能正常工作,因为imread
需要文件名而不是流.
考虑直接从tar
流中读取这种方式可以例如针对文本实现(参见例如此SO问题).
有任何建议用正确的png
编码打开流?
解包到ramdisk当然是一种选择,虽然我一直在寻找更多的东西可缓存.
我发现如何使用 FastAPI 将 numpy 数组作为图像返回?然而,我仍然在努力展示图像,它看起来只是一个白色的方块。
io.BytesIO
我像这样读入一个数组:
def iterarray(array):
output = io.BytesIO()
np.savez(output, array)
yield output.get_value()
Run Code Online (Sandbox Code Playgroud)
在我的端点中,我的回报是StreamingResponse(iterarray(), media_type='application/octet-stream')
当我留空media_type
以推断时,会下载一个 zip 文件。
如何将数组显示为图像?