2021年5月4日星期二

Fixing OpenCV Python stream ingestion

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?

https://stackoverflow.com/questions/67392519/fixing-opencv-python-stream-ingestion May 05, 2021 at 05:36AM

没有评论:

发表评论