import sys
import cv2
import threading
from PyQt5.QtGui import QImage, QPixmap
from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QPushButton, QFileDialog, QSlider, QVBoxLayout, QHBoxLayout

class MainWindow(QWidget):
    def __init__(self):
        super().__init__()

        # 创建窗口控件
        self.image_label = QLabel(self)
        self.video_label = QLabel(self)
        self.setWindowTitle('Canny边缘检测')
        self.open_image_button = QPushButton('打开图像', self)
        self.open_video_button = QPushButton('打开视频', self)
        self.open_camera_button = QPushButton('打开摄像头', self)
        self.canny_image_button = QPushButton('Canny检测图像', self)
        self.canny_video_button = QPushButton('Canny检测视频', self)
        self.canny_camera_button = QPushButton('Canny检测摄像头', self)
        self.threshold_label = QLabel('阈值:100', self)
        self.threshold_slider = QSlider(self)
        self.threshold_slider.setOrientation(1)
        self.threshold_slider.setMinimum(0)
        self.threshold_slider.setMaximum(255)
        self.threshold_slider.setValue(100)

        # 设置控件位置和大小
        self.image_label.setGeometry(10, 10, 400, 400)
        self.video_label.setGeometry(420, 10, 400, 400)
        self.open_image_button.setGeometry(10, 420, 100, 30)
        self.open_video_button.setGeometry(120, 420, 100, 30)
        self.open_camera_button.setGeometry(230, 420, 100, 30)
        self.canny_image_button.setGeometry(10, 460, 100, 30)
        self.canny_video_button.setGeometry(120, 460, 100, 30)
        self.canny_camera_button.setGeometry(230, 460, 100, 30)
        self.threshold_label.setGeometry(10, 500, 100, 30)
        self.threshold_slider.setGeometry(10, 530, 30, 150)

        # 绑定按钮点击事件
        self.open_image_button.clicked.connect(self.open_image)
        self.open_video_button.clicked.connect(self.open_video)
        self.open_camera_button.clicked.connect(self.open_camera)
        self.canny_image_button.clicked.connect(self.canny_image)
        self.canny_video_button.clicked.connect(self.start_canny_video)
        self.canny_camera_button.clicked.connect(self.start_canny_camera)
        self.threshold_slider.valueChanged.connect(self.set_threshold)

        # 初始化图像和视频
        self.image = None
        self.cap = None
        self.threshold = 100
        self.timer = None

        # 设置布局
        vbox = QVBoxLayout()
        hbox1 = QHBoxLayout()
        hbox2 = QHBoxLayout()
        vbox.addWidget(self.image_label)
        vbox.addWidget(self.video_label)
        hbox1.addWidget(self.open_image_button)
        hbox1.addWidget(self.open_video_button)
        hbox1.addWidget(self.open_camera_button)
        hbox1.addWidget(self.canny_image_button)
        hbox1.addWidget(self.canny_video_button)
        hbox1.addWidget(self.canny_camera_button)
        hbox2.addWidget(self.threshold_label)
        hbox2.addWidget(self.threshold_slider)
        vbox.addLayout(hbox1)
        vbox.addLayout(hbox2)
        self.setLayout(vbox)

    def open_image(self):
        # 打开图像文件
        file_name, _ = QFileDialog.getOpenFileName(self, '打开图像', '', 'Image Files(*.jpg *.png *.bmp)')
        print('file name:', file_name)

        if file_name:
            # 释放原有数据
            if self.cap is not None:
                self.cap.release()

            # 读取图像
            self.image = cv2.imread(file_name)
            print('image:', self.image)

            if self.image is None:
                 print('Error: failed to read image')
                 return
            # 将图像转换为QImage格式
            qimage = QImage(self.image.data, self.image.shape[1], self.image.shape[0], QImage.Format_RGB888).rgbSwapped()

          
            # 将QImage显示在界面上
            pixmap = QPixmap.fromImage(qimage)
            self.image_label.setPixmap(pixmap)

            # 释放视频播放定时器
            if self.timer:
                self.timer.cancel()
                self.timer = None

    def open_video(self):
        # 打开视频文件
        file_name, _ = QFileDialog.getOpenFileName(self, '打开视频', '', 'Video Files(*.mp4 *.avi)')

        if file_name:
            # 释放原有数据
            if self.image is not None:
                self.image = None
                self.image_label.clear()

            if self.cap is not None:
                self.cap.release()

            # 打开新的视频
            self.cap = cv2.VideoCapture(file_name)

            # 显示第一帧图像
            ret, frame = self.cap.read()
            if ret:
                # 将图像转换为QImage格式
                qimage = QImage(frame.data, frame.shape[1], frame.shape[0], QImage.Format_RGB888).rgbSwapped()

                # 将QImage显示在界面上
                pixmap = QPixmap.fromImage(qimage)
                self.video_label.setPixmap(pixmap)

            # 取消视频播放定时器
            if self.timer:
                self.timer.cancel()
                self.timer = None

    def open_camera(self):
        # 打开摄像头
        if self.cap is not None:
            self.cap.release()

        self.cap = cv2.VideoCapture(0)

        # 取消视频播放定时器
        if self.timer:
            self.timer.cancel()
            self.timer = None

    def canny_image(self):
        if self.image is not None:
            # Canny边缘检测
            edges = cv2.Canny(self.image, self.threshold, self.threshold * 2)

            # 将边缘图像转换为QImage格式
            qimage = QImage(edges.data, edges.shape[1], edges.shape[0], QImage.Format_Grayscale8)

            # 将QImage显示在界面上
            pixmap = QPixmap.fromImage(qimage)
            self.image_label.setPixmap(pixmap)

    def start_canny_video(self):
        # 启动视频播放定时器
        if self.timer is None:
            self.timer = threading.Timer(0.03, self.canny_video)
            self.timer.start()

    def start_canny_camera(self):
        # 启动视频播放定时器
        if self.timer is None:
            self.timer = threading.Timer(0.03, self.canny_camera)
            self.timer.start()

    def canny_video(self):
        if self.cap is not None:
            # 读取视频帧
            ret, frame = self.cap.read()
            if ret:
                # Canny边缘检测
                edges = cv2.Canny(frame, self.threshold, self.threshold * 2)

                # 将边缘图像转换为QImage格式
                qimage = QImage(edges.data, edges.shape[1], edges.shape[0], QImage.Format_Grayscale8)

                # 将QImage显示在界面上
                pixmap = QPixmap.fromImage(qimage)
                self.video_label.setPixmap(pixmap)

            # 启动视频播放定时器
            self.timer = threading.Timer(0.03, self.canny_video)
            self.timer.start()

    def canny_camera(self):
        if self.cap is not None:
            # 读取视频帧
            ret, frame = self.cap.read()
            if ret:
                # Canny边缘检测
                edges = cv2.Canny(frame, self.threshold, self.threshold * 2)

                # 将边缘图像转换为QImage格式
                qimage = QImage(edges.data, edges.shape[1], edges.shape[0], QImage.Format_Grayscale8)

                # 将QImage显示在界面上
                pixmap = QPixmap.fromImage(qimage)
                self.video_label.setPixmap(pixmap)

            # 启动视频播放定时器
            self.timer = threading.Timer(0.03, self.canny_camera)
            self.timer.start()

    def set_threshold(self, value):
        self.threshold = value
        self.threshold_label.setText('阈值:{}'.format(value))

    def __del__(self):
        # 清理资源
        if self.cap:
            self.cap.release()
        cv2.destroyAllWindows()

if __name__ == '__main__':
    app = QApplication(sys.argv)
    main_window = MainWindow()
    main_window.show()
    sys.exit(app.exec_())
基于PyQt5和OpenCV的Canny边缘检测工具

原文地址: https://www.cveoy.top/t/topic/nvNw 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录