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):   #定义了一个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):       #打开图像文件的方法,通过QFileDialog选择图像文件,读取图像,将图像转化为QImage格式,显示在界面上面
        # 打开图像文件
        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)

            # 显示视频
            while True:
                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)
                    cv2.waitKey(30)
                else:
                    break

            # 释放视频播放定时器
            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)

        # 显示摄像头
        while True:
            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)
                cv2.waitKey(30)
            else:
                break

        # 释放视频播放定时器
        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))

if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())

功能介绍:

  • 打开图像: 选择本地图像文件,并显示在左侧图像区域。
  • 打开视频: 选择本地视频文件,并在右侧视频区域播放。
  • 打开摄像头: 打开默认摄像头,并在右侧视频区域显示实时画面。
  • Canny 检测图像: 对当前显示的图像进行 Canny 边缘检测,并在左侧图像区域显示结果。
  • Canny 检测视频: 对当前播放的视频进行实时 Canny 边缘检测,并在右侧视频区域显示结果。
  • Canny 检测摄像头: 对当前摄像头画面进行实时 Canny 边缘检测,并在右侧视频区域显示结果。
  • 阈值调节: 使用滑块调节 Canny 边缘检测的阈值,并实时更新显示结果。

代码说明:

  1. 使用 cv2 库进行图像和视频处理。
  2. 使用 PyQt5 库创建 GUI 界面。
  3. 使用 threading 库实现视频和摄像头实时处理的线程化。
  4. 使用 QFileDialog 选择文件。
  5. 使用 QImageQPixmapcv2 处理后的图像转换为 Qt 可显示的格式。
  6. 使用 QLabel 显示图像和视频。
  7. 使用 QPushButton 实现按钮功能。
  8. 使用 QSlider 实现阈值调节。
  9. 使用 QVBoxLayoutQHBoxLayout 设置布局。

运行方法:

  1. 确保已经安装 opencv-pythonPyQt5 库。
  2. 将代码保存为 .py 文件,并运行该文件。

注意:

  • 此代码需要在支持 Python 3.x 的环境下运行。
  • 如果运行过程中出现错误,请检查库是否安装正确,并参考相关文档进行调试。
  • 可以根据需要修改代码,添加更多功能,例如保存结果图像、调整显示尺寸等。
Canny 边缘检测:图像、视频和摄像头实时边缘提取

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

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