在 Flask 上处理 opencv 图像(字节,编码为 jpg)API
Dealing with an opencv image (bytes, encoded as jpg) on a Flask API
我的挑战
我需要使用 Flask 发送和接收图像,以便对 1000 多个摄像头流进行实时对象检测。
第 1 部分:将我的视频帧发送到 API
我不想将图像帧保存在我的磁盘上,现在我没有 .png/.jpg 文件可以发送到 Flask API. 我已经将图像数据作为 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'
我正在尝试在我的 requests.post()
上发送 img_bytes
:
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()
正确打开。 imageData
的type()
是<class 'werkzeug.datastructures.FileStorage'>
.
在下面的这个片段中,我的网络服务正在检索根据请求接收到的图像,并对其执行 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 没有按预期工作。我相信它没有以正确的方式将字节转换回图像。
我在这段代码中遗漏了什么?在使用 PIL.Image.open()
打开对象 imageData
之前,我需要对它做什么?
您要向 'imageData' 发送 img_encoded 或 img_bytes 吗?我确实认为将 img_bytes 作为 base64 发送可能会导致类似的行为。 werkzeug.datastructures。
FileStorage 应该代理流方法,但您是否尝试过使用 imageData.stream?
我的代码有一点错误,我试图在 post 上发送 img_encoded
而不是 img_bytes
。现在一切正常了。
第 1 部分:发出请求
### frame is a numpy.array with an image
img_encoded = cv2.imencode('.jpg', frame)[1]
img_bytes = img_encoded.tobytes()
files = {'imageData': img_bytes}
response = requests.post(url,
files=files)
第 2 部分:处理接收到的字节
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
我的挑战
我需要使用 Flask 发送和接收图像,以便对 1000 多个摄像头流进行实时对象检测。
第 1 部分:将我的视频帧发送到 API
我不想将图像帧保存在我的磁盘上,现在我没有 .png/.jpg 文件可以发送到 Flask API. 我已经将图像数据作为 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'
我正在尝试在我的 requests.post()
上发送 img_bytes
:
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()
正确打开。 imageData
的type()
是<class 'werkzeug.datastructures.FileStorage'>
.
在下面的这个片段中,我的网络服务正在检索根据请求接收到的图像,并对其执行 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 没有按预期工作。我相信它没有以正确的方式将字节转换回图像。
我在这段代码中遗漏了什么?在使用 PIL.Image.open()
打开对象 imageData
之前,我需要对它做什么?
您要向 'imageData' 发送 img_encoded 或 img_bytes 吗?我确实认为将 img_bytes 作为 base64 发送可能会导致类似的行为。 werkzeug.datastructures。 FileStorage 应该代理流方法,但您是否尝试过使用 imageData.stream?
我的代码有一点错误,我试图在 post 上发送 img_encoded
而不是 img_bytes
。现在一切正常了。
第 1 部分:发出请求
### frame is a numpy.array with an image
img_encoded = cv2.imencode('.jpg', frame)[1]
img_bytes = img_encoded.tobytes()
files = {'imageData': img_bytes}
response = requests.post(url,
files=files)
第 2 部分:处理接收到的字节
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