AP/detection.py
2025-03-10 21:06:08 +08:00

104 lines
4.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
from read_ini import ConfigReader
from log_handler import LogHandler
class DetectionApp(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self):
super(DetectionApp, self).__init__()
self.setupUi(self)
self.log_handler = LogHandler() # ✅ 建立 LogHandler 物件
self.log_handler.write_log("程式啟動") # ✅ 寫入 log: 程式啟動
# ✅ 讀取 `exposure_time`
self.config_reader = ConfigReader()
self.exposure_time = self.config_reader.get_exposure_time()
# ✅ 先初始化 image_queue再啟動相機擷取
self.image_queue = multiprocessing.Queue(maxsize=1)
self.camera_process = None # 相機進程尚未啟動
# ✅ 連接按鈕事件
self.bt_KeepShot.clicked.connect(self.KeepShot)
self.bt_StopKeepShot.clicked.connect(self.StopKeepShot)
# ✅ 設定 QTimer每 100ms 更新影像
self.timer = QTimer(self)
self.timer.timeout.connect(self.update_view_origin)
self.timer.start(100) # 每 100ms 更新一次影像
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)
# ✅ 使用 `exposure_time` 啟動相機
self.camera_process = CameraProcess(self.image_queue, exposure_time=self.exposure_time)
self.camera_process.start()
self.log_handler.write_log("相機啟動") # ✅ 寫入 log: 相機啟動
self.statusbar.showMessage(f"開始擷取影像 (曝光時間: {self.exposure_time} 微秒)")
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("已停止影像擷取")
self.log_handler.write_log("相機停止") # ✅ 寫入 log: 相機停止
# ✅ 清空 Queue確保新擷取不會讀取到舊影像
while not self.image_queue.empty():
try:
self.image_queue.get_nowait()
except:
break
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):
reply = QtWidgets.QMessageBox.question(
self, "確認", "確定要關閉應用程式嗎?",
QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No, QtWidgets.QMessageBox.No
)
if reply == QtWidgets.QMessageBox.Yes:
self.StopKeepShot() # 停止相機
self.log_handler.write_log("程式關閉") # ✅ 寫入 log: 程式關閉
event.accept() # 允許視窗關閉
else:
event.ignore() # 阻止視窗關閉
if __name__ == "__main__":
multiprocessing.freeze_support() # 在 Windows 上執行 multiprocessing 需要這行
app = QtWidgets.QApplication(sys.argv)
window = DetectionApp()
window.show()
sys.exit(app.exec_())