Canny 边缘检测:图像、视频和摄像头实时边缘提取
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 边缘检测的阈值,并实时更新显示结果。
代码说明:
- 使用
cv2库进行图像和视频处理。 - 使用
PyQt5库创建 GUI 界面。 - 使用
threading库实现视频和摄像头实时处理的线程化。 - 使用
QFileDialog选择文件。 - 使用
QImage和QPixmap将cv2处理后的图像转换为 Qt 可显示的格式。 - 使用
QLabel显示图像和视频。 - 使用
QPushButton实现按钮功能。 - 使用
QSlider实现阈值调节。 - 使用
QVBoxLayout和QHBoxLayout设置布局。
运行方法:
- 确保已经安装
opencv-python和PyQt5库。 - 将代码保存为
.py文件,并运行该文件。
注意:
- 此代码需要在支持 Python 3.x 的环境下运行。
- 如果运行过程中出现错误,请检查库是否安装正确,并参考相关文档进行调试。
- 可以根据需要修改代码,添加更多功能,例如保存结果图像、调整显示尺寸等。
原文地址: https://www.cveoy.top/t/topic/nwVV 著作权归作者所有。请勿转载和采集!