我的挑战
我需要使用Flask发送和接收图像,以便对1000多个相机流进行实时对象检测。
第1部分:将视频帧发送到API
我不想将图像帧保存在磁盘上,如今,我没有用于发送到Flask API的.png / .jpg文件。 我已经以numpy.array
的形式在内存中存储了图像数据(我正在使用cv2.VideoCapture()
从视频流中提取帧)。
如何将numpy.array
的这些字节发送到Flask API?
如今,我正在尝试使用cv2.imencode()
编码图像,将其转换为字节,然后使用base64对其进行编码。
### frame is a numpy.array with an image
img_encoded = cv2.imencode('.jpg', frame)[1]
img_bytes = img_encoded.tobytes()
所以
img_bytes
是这样的:b'\xff\xd8\xff\xe0\x00\x10JFIF\x00\x01\x01\x00\x00\x01\x00\x01\x00\x00\xff\xdb\x00C\x00\x02\x01\x01\x01\x01\x01\x02\x01\x01\x01\x02\x02\x02\x02\x02\x04\x03\x02\x02\x02\x02\x05\x04\x04\x03'
我正在尝试在
img_bytes
上发送requests.post()
:files = {'imageData': img_bytes}
res = requests.post('http://127.0.0.1/image', files=files)
我收到
<Response [200]>
,但API未能按预期工作。我相信我的Flask服务器无法很好地处理此编码字节...所以我的问题可能在第2部分上。第2部分:在Flask服务器上接收图像字节并将其转换为PIL.Image
我定义了一个函数
predict_image()
,该函数接收PIL.Image.open()
的输出并执行所有对象检测任务。我的问题是
imageData
显然无法正确打开我的变量PIL.Image.open()
。 type()
的imageData
是<class 'werkzeug.datastructures.FileStorage'>
。 在下面的代码段中,我的Web服务正在检索在请求中接收到的图像,并对其执行
predict_image()
对象检测:def predict_image_handler(project=None, publishedName=None):
try:
imageData = None
if ('imageData' in request.files):
imageData = request.files['imageData']
elif ('imageData' in request.form):
imageData = request.form['imageData']
else:
imageData = io.BytesIO(request.get_data())
img = Image.open(imageData)
results = predict_image(img)
return jsonify(results)
except Exception as e:
print('EXCEPTION:', str(e))
return 'Error processing image', 500
将图像发送到API时,我没有收到错误消息,但是API无法正常工作。我相信它并没有以正确的方式将字节转换回图像。
该代码中我缺少什么?在使用
imageData
打开对象PIL.Image.open()
之前,我需要做什么?
最佳答案
您要将img_encoded或img_bytes发送到“imageData”吗?我确实认为将img_bytes作为base64发送可能会导致这种情况。 werkzeug.datastructures。
FileStorage应该代理流方法,但是您是否尝试过使用imageData.stream?
关于python - 在Flask API上处理opencv图像(字节,编码为jpg),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57310462/