camera.py 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. from PyQt5.QtCore import pyqtSignal
  2. from PyQt5.QtCore import QObject
  3. from PyQt5.QtCore import QTimer
  4. from PyQt5.QtGui import QImage
  5. import cv2
  6. class CameraDevice(QObject):
  7. frame_ready = pyqtSignal(QImage)
  8. def __init__(self, device_id=-1):
  9. super().__init__()
  10. self.capture = cv2.VideoCapture(device_id)
  11. self.timer = QTimer()
  12. self.timer.timeout.connect(self.read_frame)
  13. self.timer.setInterval(1000/self.fps)
  14. self.timer.start()
  15. def __del__(self):
  16. self.timer.stop()
  17. self.capture.release()
  18. @property
  19. def fps(self):
  20. """Frames per second."""
  21. return self.capture.get(cv2.CAP_PROP_FPS)
  22. @property
  23. def size(self):
  24. """Returns the size of the video frames: (width, height)."""
  25. width = int(self.capture.get(cv2.CAP_PROP_FRAME_WIDTH))
  26. height = int(self.capture.get(cv2.CAP_PROP_FRAME_HEIGHT))
  27. return (width, height)
  28. def read_frame(self):
  29. """Read frame into QImage and emit it."""
  30. success, frame = self.capture.read()
  31. if success:
  32. img = _convert_array_to_qimage(frame)
  33. self.frame_ready.emit(img)
  34. else:
  35. raise ValueError("Failed to read frame")
  36. def _convert_array_to_qimage(a):
  37. height, width, channels = a.shape
  38. bytes_per_line = channels * width
  39. cv2.cvtColor(a, cv2.COLOR_BGR2RGB, a)
  40. return QImage(a.data, width, height, bytes_per_line, QImage.Format_RGB888)