2025-03-10 11:30:13 +08:00
|
|
|
|
import sys
|
|
|
|
|
import cv2
|
|
|
|
|
import numpy as np
|
|
|
|
|
import multiprocessing
|
|
|
|
|
from PyQt5 import QtWidgets, QtGui, QtCore
|
|
|
|
|
from PyQt5.QtCore import QTimer
|
|
|
|
|
from Detection_window import Ui_MainWindow
|
|
|
|
|
from camera.camera_process import CameraProcess
|
|
|
|
|
|
|
|
|
|
class DetectionApp(QtWidgets.QMainWindow, Ui_MainWindow):
|
|
|
|
|
def __init__(self):
|
|
|
|
|
super(DetectionApp, self).__init__()
|
|
|
|
|
self.setupUi(self)
|
|
|
|
|
|
2025-03-10 13:45:43 +08:00
|
|
|
|
# ✅ 先初始化 image_queue,再啟動相機擷取
|
2025-03-10 11:30:13 +08:00
|
|
|
|
self.image_queue = multiprocessing.Queue(maxsize=1)
|
2025-03-10 13:45:43 +08:00
|
|
|
|
self.camera_process = None # 相機進程尚未啟動
|
2025-03-10 11:30:13 +08:00
|
|
|
|
|
2025-03-10 13:45:43 +08:00
|
|
|
|
self.bt_KeepShot.clicked.connect(self.KeepShot)
|
|
|
|
|
self.bt_StopKeepShot.clicked.connect(self.StopKeepShot)
|
2025-03-10 11:30:13 +08:00
|
|
|
|
|
|
|
|
|
# ✅ 設定 QTimer,每 100ms 更新影像
|
|
|
|
|
self.timer = QTimer(self)
|
|
|
|
|
self.timer.timeout.connect(self.update_view_origin)
|
|
|
|
|
self.timer.start(100) # 每 100ms 更新一次影像
|
|
|
|
|
|
2025-03-10 13:45:43 +08:00
|
|
|
|
def KeepShot(self):
|
|
|
|
|
""" 啟動相機擷取 """
|
|
|
|
|
if self.camera_process is None or not self.camera_process.is_alive():
|
|
|
|
|
self.StopKeepShot() # 確保先停止舊的 Process,避免衝突
|
|
|
|
|
|
|
|
|
|
# ✅ 重新建立 Queue,避免殘留影像影響新擷取
|
|
|
|
|
self.image_queue = multiprocessing.Queue(maxsize=1)
|
|
|
|
|
|
|
|
|
|
# ✅ 確保 `CameraProcess` 是新的
|
|
|
|
|
self.camera_process = CameraProcess(self.image_queue)
|
|
|
|
|
self.camera_process.start()
|
|
|
|
|
else:
|
|
|
|
|
print("相機已經在擷取")
|
|
|
|
|
|
|
|
|
|
def StopKeepShot(self):
|
|
|
|
|
""" 停止相機擷取 """
|
|
|
|
|
if self.camera_process and self.camera_process.is_alive():
|
|
|
|
|
self.camera_process.stop() # 停止擷取
|
|
|
|
|
self.camera_process.join() # 等待進程完全結束
|
|
|
|
|
self.camera_process = None
|
|
|
|
|
print("已停止影像擷取")
|
|
|
|
|
|
|
|
|
|
# ✅ 清空 Queue,確保新擷取不會讀取到舊影像
|
|
|
|
|
while not self.image_queue.empty():
|
|
|
|
|
try:
|
|
|
|
|
self.image_queue.get_nowait()
|
|
|
|
|
except:
|
|
|
|
|
break
|
|
|
|
|
|
2025-03-10 11:30:13 +08:00
|
|
|
|
def update_view_origin(self):
|
|
|
|
|
""" 從 Queue 獲取影像並顯示在 QLabel (view_origin) 上 """
|
|
|
|
|
if not self.image_queue.empty():
|
|
|
|
|
image = self.image_queue.get() # 取得最新影像
|
|
|
|
|
self.display_image(image)
|
|
|
|
|
|
|
|
|
|
def display_image(self, image):
|
|
|
|
|
""" 顯示影像到 QLabel (view_origin) """
|
|
|
|
|
image_bgr = cv2.cvtColor(image, cv2.COLOR_BayerBG2BGR) if len(image.shape) == 2 else image
|
|
|
|
|
height, width, channel = image_bgr.shape
|
|
|
|
|
bytes_per_line = 3 * width
|
|
|
|
|
qimage = QtGui.QImage(image_bgr.data, width, height, bytes_per_line, QtGui.QImage.Format_BGR888)
|
|
|
|
|
pixmap = QtGui.QPixmap.fromImage(qimage).scaled(self.view_origin.size(), QtCore.Qt.KeepAspectRatio)
|
|
|
|
|
self.view_origin.setPixmap(pixmap)
|
|
|
|
|
|
|
|
|
|
def closeEvent(self, event):
|
|
|
|
|
""" 確保程式關閉時正確停止相機擷取進程 """
|
2025-03-10 13:45:43 +08:00
|
|
|
|
self.StopKeepShot() # 確保關閉程式時停止相機擷取
|
|
|
|
|
event.accept() # ✅ 允許視窗關閉
|
2025-03-10 11:30:13 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
|
app = QtWidgets.QApplication(sys.argv)
|
|
|
|
|
window = DetectionApp()
|
|
|
|
|
window.show()
|
|
|
|
|
sys.exit(app.exec_())
|