main.py 1.4 KB

123456789101112131415161718192021222324252627282930313233343536
  1. #!/usr/bin/env python3
  2. import base64
  3. import time
  4. import cv2
  5. from fastapi import Response
  6. from nicegui import app, ui
  7. # in case you don't have a webcam, this will provide a black placeholder image
  8. black_1px = 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAA1JREFUGFdjYGBg+A8AAQQBAHAgZQsAAAAASUVORK5CYII='
  9. placeholder = Response(content=base64.b64decode(black_1px.encode('ascii')), media_type='image/png')
  10. # OpenCV is used to access the webcam
  11. video_capture = cv2.VideoCapture(0)
  12. @app.get('/video/frame')
  13. async def grab_video_frame() -> Response:
  14. # thanks to FastAPI it is easy to create a web route which always provides the latest image from OpenCV
  15. if not video_capture.isOpened():
  16. return placeholder
  17. ret, frame = video_capture.read()
  18. if not ret:
  19. return placeholder
  20. _, imencode_image = cv2.imencode('.jpg', frame)
  21. jpeg = imencode_image.tobytes()
  22. return Response(content=jpeg, media_type='image/jpeg')
  23. # For non-flickering image updates an interactive image is much better than ui.image().
  24. video_image = ui.interactive_image().classes('w-full h-full')
  25. # A timer constantly updates the source of the image.
  26. # But because the path is always the same, we must force an update by adding the current timestamp to the source.
  27. ui.timer(interval=0.1, callback=lambda: video_image.set_source(f'/video/frame?{time.time()}'))
  28. ui.run()