I'm trying to break a video down into frames, draw some boxes and labels on the frames, and then feed them into a RedisImageStream, like this:
def get_last(self):
''' Gets latest from camera and model '''
p = self.conn.pipeline()
p.xrevrange(self.camera, count=1) # Latest frame
p.xrevrange(self.boxes, count=1) # Latest boxes
cmsg, bmsg = p.execute()
if cmsg:
last_id = cmsg[0][0].decode('utf-8')
label = f'{self.camera}:{last_id}'
data = io.BytesIO(cmsg[0][1][self.field])
img = Image.open(data)
if bmsg:
boxes = np.fromstring(bmsg[0][1]['boxes'.encode('utf-8')][1:-1], sep=',')
label += ' people: {}'.format(bmsg[0][1]['people'.encode('utf-8')].decode('utf-8'))
for box in range(int(bmsg[0][1]['people'.encode('utf-8')])): # Draw boxes
x1 = boxes[box*4]
y1 = boxes[box*4+1]
x2 = boxes[box*4+2]
y2 = boxes[box*4+3]
draw = ImageDraw.Draw(img)
draw.rectangle(((x1, y1), (x2, y2)), width=5, outline='red')
arr = np.array(img)
arr = cv2.cvtColor(arr, cv2.COLOR_BGR2RGB)
cv2.putText(arr, label, (10, 40), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0,0,255), 1, cv2.LINE_AA)
ret, img = cv2.imencode('.jpg', arr)
return img.tobytes()
At this point, I should be getting bytes. The output of get_last feeds into this generator:
def gen(stream):
while True:
try:
frame = stream.get_last()
yield (b'--frame\r\n'
b'Pragma-directive: no-cache\r\n'
b'Cache-directive: no-cache\r\n'
b'Cache-control: no-cache\r\n'
b'Pragma: no-cache\r\n'
b'Expires: 0\r\n'
b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n\r\n')
except Exception as exception:
# Output unexpected Exceptions.
logging.error("Error occurred", exc_info=True)
The output of the generator should go into a return stream on an HTTP route:
@app.route('/video')
def video_feed():
return Response(gen(RedisImageStream(conn, args)),
mimetype='multipart/x-mixed-replace; boundary=frame')
Instead, this throws an error per frame:
in gen
b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n\r\n')
TypeError: cannot convert 'NoneType' object to bytes
How should I debug this?