opencv自定义间隔帧获取视频转存为图片的GUI界面实现

该程序功能只将mp4转为jpg

希望得到您的指导

非常感谢您观看我的博客,我的博客是为了记录我的学习过程同时保留我的某些可重复利用代码以方便下次使用。如果您对我的博客有任何建议还请您不吝指出,非常感谢您对我的指导。

背景

在实现opencv逐帧获取视频转存为图片后我便有了编写程序以图形的形式显示操作页面的想法。本文是基于上篇文章代码的修改以实现简单的GUI图形界面。

实现过程中发现仍需要深化学习的技术

  • 线程与进程
  • tkinter
  • pathlib
  • 打包为exe
  • 发布到局域网

下图为运行结果实例

在这里插入图片描述

import tkinter as tk
from tkinter import filedialog
import cv2
from pathlib import Path
import threading

global is_processing,current_task,pool,pause_event
pause_event = threading.Event()
pause_event.set()
is_processing = True
pool = None


def select_video():
    video_path =filedialog.askdirectory()
    entry_video.delete(0, tk.END)
    entry_video.insert(0, video_path)

def select_output_dir():
    output_dir = filedialog.askdirectory()
    entry_output.delete(0, tk.END)
    entry_output.insert(0, output_dir)


def start_process():
    global  is_processing
    is_processing = True
    app_status()



def stop_process():
    global is_processing,pool
    is_processing = False


def break_process():
    global is_processing,pause_event
    # is_processing = False
    pause_event.clear()

def continue_process():
    global is_processing,thread,pause_event
    # is_processing = True
    pause_event.set()



def app_status():
    global is_processing,thread
    video_path = entry_video.get()
    output_dir = entry_output.get()
    interval = int(frame_interval_entry.get())
    thread = threading.Thread(target=run,args=(video_path,output_dir,interval))
    thread.start()


def output_img(video_path, img_dir,frame_interval):
    global is_processing,pause_event
    # 由视频逐帧输出图片
    # video_path: 视频文件路径
    # img_dir: 图片保存目录路径,路径不支持中文
    cv = cv2.VideoCapture(video_path)
    frame_count = 0
    n = 0
    while is_processing:
        ret, frame = cv.read()
        if not ret:
            break
        frame_count += 1
        if frame_count % frame_interval == 0:
            if not pause_event.is_set():  # 检查是否需要暂停线程
                pause_event.wait()
            n += 1
            img_name = f"0000000{n}.jpg"
            img_file_path = Path(img_dir) / img_name
            if not img_file_path.exists():
                print("创建文件:", img_file_path)
                cv2.imwrite(str(img_file_path), frame, [cv2.IMWRITE_JPEG_QUALITY, 100])
            else:
                print("跳过:", img_file_path)

def run(video_dir, img_dir,frame_interval):
    global is_processing
    while is_processing:
        if not is_processing:
            break
        for file in Path(video_dir).iterdir():
            if file.suffix == ".mp4":
                video_file_path = str(file)
                img_dir_name = Path(img_dir) / file.stem  # 使用视频文件名作为子目录名
                img_dir_name.mkdir(parents=True, exist_ok=True)
                output_img(video_file_path, str(img_dir_name),frame_interval)
    print("Thread execution stopped")


# 创建主窗口
root = tk.Tk()
root.title("视频处理程序")
root.geometry("800x600")

# 添加选择视频按钮
btn_select_video = tk.Button(root, text="选择视频文件", command=select_video)
btn_select_video.pack(side='top',pady=10)

# 添加选择输出路径按钮
btn_select_output = tk.Button(root, text="选择输出路径", command=select_output_dir)
btn_select_output.pack(side='top',pady=10)

# 显示视频路径输入框
entry_video = tk.Entry(root)
entry_video.pack()

# 显示输出路径输入框
entry_output = tk.Entry(root)
entry_output.pack()

# 添加帧间隔输入框
frame_interval_label = tk.Label(root, text="帧间隔:")
frame_interval_label.pack(side='top', pady=10)
frame_interval_entry = tk.Entry(root)
frame_interval_entry.pack()

# 添加开始处理按钮
btn_start = tk.Button(root, text="开始处理", command=start_process)
btn_start.pack(side='top',pady=10)

# 添加停止处理按钮
btn_start = tk.Button(root, text="停止处理", command=stop_process)
btn_start.pack(side='top',pady=10)

# 添加暂停处理按钮
btn_start = tk.Button(root, text="暂停处理", command=break_process)
btn_start.pack(side='top',pady=10)

# 添加继续处理按钮
btn_start = tk.Button(root, text="继续处理", command=continue_process)
btn_start.pack(side='top',pady=10)


# 启动主循环
root.mainloop()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/480045.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

酷开科技以内容技术服务和数字营销服务为核心,自主研发酷开系统

家庭场景的需求,才是大屏电视的目的。屏幕越大得到的画幕越大,消费者也就看的越清楚,从而获得更好的观看体验,尤其是家里有老人孩子的,为了得到更好的视觉效果,使得消费者对于大屏的需求也在增加。酷开系统…

python的O2O生鲜食品订购flask-django-nodejs-php

用户只能通过一些类似软件进行查看生鲜超市,这样的管理方式仍然是比较机械传统的,本文通过对市面上常见的线上管理系统与现实生活中结合问题的讨论,从一个微信小程序的O2O生鲜食品订购角度进行需求分析,提供一些新的思路&#xff…

【Canvas与艺术】绘制暗绿色汽车速度仪表盘

【原型】 【成果】 【代码】 <!DOCTYPE html> <html lang"utf-8"> <meta http-equiv"Content-Type" content"text/html; charsetutf-8"/> <head><title>暗绿色汽车速度仪表盘</title><style type"t…

从0到1实现RPC | 03 重载方法和参数类型转换

一、存在的问题 1.重载方法在当前的实现中还不支持&#xff0c;调用了会报错。 2.类型转换也还存在问题。 假设定义的接口如下&#xff0c;参数是float类型。 在Provider端接受到的是一个Double类型&#xff0c;这是因为web应用接收的请求后处理的类型。 在反射调用的时候就会…

大数据主要组件HDFS Iceberg Hadoop spark介绍

HDFSIceberghadoopspark HDFS 面向PB级数据存储的分布式文件系统&#xff0c;可以存储任意类型与格式的数据文件&#xff0c;包括结构化的数据以及非结构化的数据。HDFS将导入的大数据文件切割成小数据块&#xff0c;均匀分布到服务器集群中的各个节点&#xff0c;并且每个数据…

综合知识篇18-系统可靠性设计考点(2024年软考高级系统架构设计师冲刺知识点总结系列文章)

专栏系列文章: 2024高级系统架构设计师备考资料(高频考点&真题&经验)https://blog.csdn.net/seeker1994/category_12593400.html案例分析篇00-【历年案例分析真题考点汇总】与【专栏文章案例分析高频考点目录】(2024年软考高级系统架构设计师冲刺知识点总结-案例…

puppeteer使用示例云顶之弈官网

自己从0到1开发的&#xff0c;微信小程序【云顶宝藏】求求点个5星好评吧&#xff01; 需求&#xff1a;拿到所有英雄的信息 思路&#xff1a;点击每个英雄&#xff0c;进入英雄详情页&#xff0c;拿信息&#xff0c;并返回&#xff0c;继续下一个英雄** 最终效果 本地环境 win…

PostgreSQL技术大讲堂 - 第48讲:PG高可用实现keepalived

PostgreSQL从小白到专家&#xff0c;是从入门逐渐能力提升的一个系列教程&#xff0c;内容包括对PG基础的认知、包括安装使用、包括角色权限、包括维护管理、、等内容&#xff0c;希望对热爱PG、学习PG的同学们有帮助&#xff0c;欢迎持续关注CUUG PG技术大讲堂。 第48讲&#…

Spring Boot 3 极速搭建OAuth2认证框架

本篇环境 Java 17Spring Boot 3.2.3Spring Authorization Server 1.2.3开发工具 SpringToolSuite4Spring Boot 3.2.3 需要JDK 17及之上的版本。 项目初始化 项目可以使用Spring的初始化器生成, 也可以创建一个Maven类型的项目。 项目创建后的目录结构如下: 项目配置 使用 …

OpenHarmony游戏应用程序-实现的一个手柄游戏

介绍 本篇Codelab是基于TS扩展的声明式开发范式编程语言&#xff0c;以及OpenHarmony的分布式能力实现的一个手柄游戏。 说明&#xff1a; 本示例涉及使用系统接口&#xff0c;需要手动替换Full SDK才能编译通过。 完成本篇Codelab需要两台开发板&#xff0c;一台开发板作为游…

罗德与施瓦茨CMA180电信无线电测试仪

181/2461/8938产品概述&#xff1a; R&S CMA180 是适用于在 100 kHz 至 3 GHz 范围内操作的无线电系统的无线电通信测试仪。其技术完全基于数字信号处理及先进计算。 简介&#xff1a;R&S CMA180 无线电通信测试仪 R&SCMA180 是适用于在 100 kHz 至 3 GHz 范围内…

电商系统秒杀二 秒杀场景下如何进行限流

本章学习内容 1、在秒杀页面&#xff0c;客户点击秒杀后&#xff0c;在前台弹出一个验证码&#xff0c;需要用户输入验证码才能往后端发送请求&#xff0c;这样能够错开秒杀下单的时间。 2、通过验证码&#xff0c;对后台下单请求进行保护&#xff0c;防止刷单&#xff0c;即防…

通过JWT完成token登录验证

前言 什么是JWT&#xff1f; 全称是JSON Web token&#xff0c;是用于对应用程序上的用户进行身份验证的标记&#xff0c;使用 JWTS 的应用程序不再需要保存有关其用户的 cookie 或其他session数据 使用JWT的优势 提高了程序的可伸缩性&#xff0c;也极大的提高了应用程序的安全…

2024蓝桥杯每日一题(单调队列)

备战2024年蓝桥杯 -- 每日一题 Python大学A组 试题一&#xff1a;单调栈 试题二&#xff1a;滑动窗口 试题三&#xff1a;子矩阵 试题四&#xff1a;最大子序和 试题一&#xff1a;单调栈 【题目描述】 给定一个长度为 N 的整数数列&#xff0c;输出每…

第十四届蓝桥杯JavaB组省赛真题 - 幸运数字

进制转换可以参考如下的十进制&#xff0c;基本一样的&#xff0c;只是把10变成了其他数字&#xff0c; sum就是各个数位之和 public static int myUtil(int n) {int sum 0;while(n > 0) {sum n % 10;n / 10;}return sum;} 注意&#xff1a; 如果写在同一个类里面&…

基于javaSpringboot+mybatis+layui的装修验收管理系统设计和实现

基于javaSpringbootmybatislayui的装修验收管理系统设计和实现 博主介绍&#xff1a;多年java开发经验&#xff0c;专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 央顺技术团队 Java毕设项目精品实战案例《1000套》 欢迎点赞 收藏 ⭐留…

Java安全 反序列化(5) CC6链原理分析

Java安全 反序列化(5) CC6链原理分析 CC6学习的目的在于其可以无视jdk版本&#xff0c;这条链子更像CC1-LazyMap和URLDNS链子的缝合版 文章目录 Java安全 反序列化(5) CC6链原理分析前言一.CC6的原理和实现以及易错点我们如何实现调用LazyMap.get()方法一个易错点 二.完整CC6P…

亚马逊服务器ssh以及scp

ssh awspass.pem为创建服务器时创建的密钥&#xff0c;ubuntu用户 ssh -i "awspass.pem" ubuntuipscp scp -i "awspass.pem" -r dist/* ubuntuip:/home/ubuntu/

macOS下Java应用的打包和安装程序制作

文章目录 macOS应用程序结构Java应用打包JavaAppLauncherjpackage其它相关JDK命令附录JavaAppLauncher源码链接macOS应用程序结构 macOS通常以dmg或pkg作为软件发行包,安装到/Applications下后,结构比较统一。 info.plist里的CFBundleExecutable字段可以指定入口,如果不指定…

使用uniapp 的 plus.sqlite 操作本地数据库报错:::table xxx has no column named xxxx

背景&#xff1a; 1、使用uniapp 的 plus.sqlite 进行APP本地数据库操作 2、SQLite 模块用于操作本地数据库文件&#xff0c;可实现数据库文件的创建&#xff0c;执行SQL语句等功能。 遇到&#xff1a;在之前创建的表上进行新增字段的操作时候&#xff0c;出现问题&#xff1a…
最新文章