PyQt와 OpenCV로 카메라 스트리밍 토글하기
2023. 8. 2. 23:21ㆍ개발
그냥 반복에 반복하며 쓰고 있는 코드라서 정리할 겸 작성해봄.
목표 및 설계
- 연결된 카메라를 이용한 스트리밍을 토글할 수 있는 GUI
- 카메라 쓰레드는 파일을 따로 생성
- cam_id로 특정 카메라 불러오기 (보통 0 또는 1)
- width, height, fps 설정할 수 있도록..
1. 설치
pip install pyqt5
pip install opencv-python
2. 코딩
# main.py
import sys
from camera import CameraThread
from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import (
QApplication,
QMainWindow,
QWidget,
QVBoxLayout,
QLabel,
QPushButton,
)
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.camera_thread = CameraThread(
cam_id=1,
width=640,
height=360
)
self.camera_thread.q_img.connect(self.update_label)
self.label_view = QLabel()
self.btn_camera = QPushButton('ON')
self.btn_camera.clicked.connect(self.handle_streaming)
layout = QVBoxLayout()
layout.addWidget(self.label_view)
layout.addWidget(self.btn_camera)
widget = QWidget()
widget.setLayout(layout)
self.setCentralWidget(widget)
self.show()
def handle_streaming(self):
if self.btn_camera.text() == 'ON':
self.btn_camera.setText('OFF')
self.camera_thread.is_streaming = True
self.camera_thread.start()
else:
self.btn_camera.setText('ON')
self.camera_thread.is_streaming = False
def update_label(self, q_img):
self.label_view.setPixmap(
QPixmap.fromImage(q_img)
)
if __name__ == "__main__":
app = QApplication(sys.argv)
main = MainWindow()
app.exec()
# camera.py
import cv2
import numpy as np
from PyQt5.QtGui import QImage
from PyQt5.QtCore import (
QThread,
pyqtSignal,
)
class CameraThread(QThread):
q_img = pyqtSignal(QImage)
def __init__(self, cam_id=0, width=1280, height=720, fps=30):
super().__init__()
self.is_streaming = False
self.cam_id = cam_id
self.width = width
self.height = height
self.fps = fps
def init_view(self):
self.q_img.emit(
QImage(
np.zeros((self.height, self.width, 3)),
self.width,
self.height,
self.width * 3,
QImage.Format_Grayscale16
)
)
def run(self):
cap = cv2.VideoCapture(self.cam_id)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, self.width)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, self.height)
cap.set(cv2.CAP_PROP_FPS, self.fps)
while self.is_streaming:
ret, frame = cap.read()
if not ret:
break
frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
q_img = QImage(
frame_rgb,
self.width,
self.height,
self.width * 3,
QImage.Format_RGB888
)
self.q_img.emit(q_img)
self.init_view()
cap.release()
728x90
반응형
'개발' 카테고리의 다른 글
NoMachine 이용기 : 원격 데스크톱, 외부 연결 (1) | 2023.09.05 |
---|---|
깃헙 블로그 개설 as side project diary (ruby, jekyll, github) (0) | 2023.08.05 |
Dictionary 클래스 python 및 dart 구현 (0) | 2023.07.15 |
파이썬 개발자의 플러터 개발환경셋업 (MacOS, VSCode) (0) | 2023.06.26 |
라즈베리파이 VNC 'Cannot currently show the desktop' 해결 (0) | 2023.05.12 |