基于OpenCV和PyQt5的跳绳计数器应用程序

这篇具有很好参考价值的文章主要介绍了基于OpenCV和PyQt5的跳绳计数器应用程序。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

基于OpenCV和PyQt5的跳绳计数器应用程序

介绍

本文将介绍一个基于OpenCV和PyQt5的跳绳计数器应用程序。该程序可以使用计算机摄像头来检测跳绳动作,并计算跳绳次数。本文将介绍程序的实现方法和实现细节,包括背景减除算法和轮廓检测算法的使用。

背景减除算法

背景减除算法是一种常用的图像处理技术,用于从静态摄像头拍摄的视频中提取运动目标。该算法基于假设,即摄像头的背景是静态的,而运动目标是动态的。因此,通过将当前帧图像与背景帧图像进行差分,可以得到运动目标的二值图像。

在本程序中,我们使用了MOG2背景减除算法。该算法是一种基于高斯混合模型的背景减除算法。它将每个像素的灰度值建模为多个高斯分布的混合,其中每个高斯分布表示不同的背景或前景区域。通过比较当前帧图像的像素值与背景模型的像素值来确定每个像素是否属于前景区域。

轮廓检测算法

轮廓检测算法是一种用于检测图像中对象轮廓的算法。在本程序中,我们使用了OpenCV中的findContours函数来检测跳绳动作的轮廓。该函数接受一个二值图像和一些参数,然后返回一个轮廓列表。轮廓是由一系列连续的点组成的,表示对象的边界。通过计算轮廓的数量,我们可以确定跳绳次数。

应用程序实现

本程序使用了Python编程语言和PyQt5 GUI框架。程序界面分为两个部分:视频显示区域和跳绳计数器。

Video类是程序的核心组件,它负责处理视频帧,并使用背景减除算法和轮廓检测算法来检测跳绳动作。Video类继承了QThread类,因此可以在单独的线程中运行,以避免阻塞主线程。

程序的实现基本上是以下几个步骤:

1.初始化程序界面和Video类。

2.启动Video线程并开始视频捕捉。

3.在每个视频帧中,使用背景减除算法提取前景区域。

4.使用轮廓检测算法检测跳绳动作的轮廓。

5.计算跳绳次数并更新计数器。

6.将视频帧显示在界面上。

7.等待下一帧视频并重复上述步骤。

完整代码

import cv2
from PyQt5 import QtCore, QtGui, QtWidgets
import numpy as np

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        # 设置主窗口属性
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(800, 600)

        # 添加Central Widget
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")

        # 添加Widget用于显示视频
        self.video_widget = QtWidgets.QLabel(self.centralwidget)
        self.video_widget.setGeometry(QtCore.QRect(100, 100, 640, 480))
        self.video_widget.setFrameShape(QtWidgets.QFrame.Box)
        self.video_widget.setText("")
        self.video_widget.setAlignment(QtCore.Qt.AlignCenter)
        self.video_widget.setObjectName("video_widget")

        # 添加Label用于显示跳绳次数
        self.result_label = QtWidgets.QLabel(self.centralwidget)
        self.result_label.setGeometry(QtCore.QRect(275, 30, 250, 50))
        font = QtGui.QFont()
        font.setPointSize(20)
        font.setBold(True)
        font.setWeight(75)
        self.result_label.setFont(font)
        self.result_label.setAlignment(QtCore.Qt.AlignCenter)
        self.result_label.setObjectName("result_label")

        # 设置主窗口的Central Widget为self.centralwidget
        MainWindow.setCentralWidget(self.centralwidget)




class MainWindow(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()
        # 创建UI对象
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        # 创建视频对象并连接信号
        self.video = Video(self.ui.video_widget)
        self.video.frame_update.connect(self.ui.video_widget.setPixmap)
        self.video.count_update.connect(self.ui.result_label.setText)

        # 启动视频
        self.video.readFrame()




class Video(QtCore.QObject):
    frame_update = QtCore.pyqtSignal(QtGui.QPixmap)
    count_update = QtCore.pyqtSignal(str)

    def __init__(self, widget):
        super().__init__()
        self.cap = cv2.VideoCapture("跳绳2.mp4")
        self.fgbg = cv2.createBackgroundSubtractorMOG2()
        self.count = 0
        self.jumping = False
        self.widget = widget
        self.timer = QtCore.QTimer()

        # 连接定时器信号
        self.timer.timeout.connect(self.readFrame)

        # 每100毫秒读取一帧
        self.timer.start(100)

    def readFrame(self):
        ret, frame = self.cap.read()
        if not ret:
            self.timer.stop()
            return

        fgmask = self.fgbg.apply(frame)

        thresh = cv2.threshold(fgmask, 50, 255, cv2.THRESH_BINARY)[1]

        contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
        if len(contours) > 0:
            largest_contour = max(contours, key=cv2.contourArea)
            if cv2.contourArea(largest_contour) > 1000:
                if not self.jumping:
                    self.jumping = True
                    self.count += 1
            else:
                self.jumping = False

        cv2.putText(frame, "Count: {}".format(self.count), (10, 50),
                    cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2, cv2.LINE_AA)

        # 将opencv图像格式转换为QPixmap
        h, w, ch = frame.shape
        bytes_per_line = ch * w
        convert_to_Qt_format = QtGui.QImage(frame.data, w, h, bytes_per_line, QtGui.QImage.Format_RGB888)
        p = convert_to_Qt_format.scaled(640, 480, QtCore.Qt.KeepAspectRatio)
        pixmap = QtGui.QPixmap.fromImage(p)

        # 发送新帧信号
        self.frame_update.emit(pixmap)

        # 发送计数信号
        self.count_update.emit("跳绳次数:%d" % self.count)






if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = MainWindow()
    MainWindow.show()
    sys.exit(app.exec_())


检测效果

基于OpenCV和PyQt5的跳绳计数器应用程序

结论

本文介绍了一个基于OpenCV和PyQt5的跳绳计数器应用程序的实现方法和实现细节。通过使用背景减除算法和轮廓检测算法,该程序可以准确地检测跳绳动作,并计算跳绳次数。该程序不仅可以用于跳绳计数,还可以用于其他需要检测运动目标的应用程序。文章来源地址https://www.toymoban.com/news/detail-468630.html

到了这里,关于基于OpenCV和PyQt5的跳绳计数器应用程序的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包