万用表数据导出变化曲线图——pycharm实现视频数据导出变化曲线图

万用表数据导出变化曲线图——pycharm实现视频数据导出变化曲线图

  • 一、效果展示
  • 二、环境配置
  • 三、代码构思
  • 四、代码展示
  • 五、代码、python环境包链接

一、效果展示

图1.1 效果展示
(左图:万用表视频截图;右图:表中数据变化曲线图)

二、环境配置

软件:PyCharm 2021.1.3 (Professional Edition)

python环境包:放在文章结尾文件链接,其中 .yaml 文件

三、代码构思

Created with Raphaël 2.3.0 Start 预备工作:拍摄一段万用表视频 预备工作:裁剪视频、读取视频每秒帧数 代码1:将视频按帧数截屏至某文件夹下 代码2:ocr 截屏文件夹下所有文件 代码3:正则表达式筛选截图中数字数据,并修正数据 代码4:绘图 End

四、代码展示

# functions.py
import cv2
import os
import glob# video to img
def extract_frames(video_path, output_folder, interval):cap = cv2.VideoCapture(video_path)frame_count = 0while cap.isOpened():ret, frame = cap.read()if not ret:breakif frame_count % interval == 0:output_path = f"{output_folder}/frame_{interval}_{frame_count // interval}.jpg"cv2.imwrite(output_path, frame)frame_count += 1cap.release()# 计数文件夹里的文件个数
def count_files_in_directory(directory):return len([f for f in os.listdir(directory) if os.path.isfile(os.path.join(directory, f))])# 删除文件夹下的图片
def del_imgs(folder_path):# 定义要删除的图片文件夹路径# 获取文件夹中所有图片文件的路径image_files = glob.glob(os.path.join(folder_path, '*.jpg')) + glob.glob(os.path.join(folder_path, '*.png'))# 遍历所有图片文件并删除for image_file in image_files:os.remove(image_file)
# img_to_plot.py
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.pyplot import MultipleLocatordef wyb_plot(Real_time_value, Maximum, Average, Minimum, fps, title, x_scale=2, y_scale=0.500):x = [i for i in range(len(Real_time_value))]plt.figure(dpi=200)x_major_locator = MultipleLocator(x_scale)# 把x轴的刻度间隔设置为2,并存在变量里y_major_locator = MultipleLocator(y_scale)# 把y轴的刻度间隔设置为0.0500,并存在变量里ax = plt.gca()# ax为两条坐标轴的实例ax.xaxis.set_major_locator(x_major_locator)# 把x轴的主刻度设置为1的倍数ax.yaxis.set_major_locator(y_major_locator)# 把y轴的主刻度设置为10的倍数# # 绘制柱状图# y = Real_time_value# plt.bar(x, y)# 绘制曲线图plt.plot(x, Real_time_value, label='Real_time_value')plt.plot(x, Maximum, label='Maximum')plt.plot(x, Average, label='Average')plt.plot(x, Minimum, label='Minimum')# 绘制曲线图,并标出最大值和最小值max_y = np.max(Real_time_value)min_y = np.min(Real_time_value)max_index = np.argmax(Real_time_value)min_index = np.argmin(Real_time_value)plt.annotate("(%s,%s)" % (x[max_index], max_y), xy=(x[max_index], max_y), xytext=(x[max_index], max_y + 0.5),textcoords='offset points',color='red')plt.savefig('wyb_plot.png')plt.annotate("(%s,%s)" % (x[min_index], min_y), xy=(x[min_index], min_y), xytext=(x[min_index], min_y - 0.5),textcoords='offset points',color='green')max_y = np.max(Maximum)min_y = np.min(Maximum)max_index = np.argmax(Maximum)min_index = np.argmin(Maximum)plt.annotate("(%s,%s)" % (x[max_index], max_y), xy=(x[max_index], max_y), xytext=(x[max_index], max_y + 0.5),textcoords='offset points',color='red')plt.savefig('wyb_plot.png')plt.annotate("(%s,%s)" % (x[min_index], min_y), xy=(x[min_index], min_y), xytext=(x[min_index], min_y - 0.5),textcoords='offset points',color='green')max_y = np.max(Average)min_y = np.min(Average)max_index = np.argmax(Average)min_index = np.argmin(Average)plt.annotate("(%s,%s)" % (x[max_index], max_y), xy=(x[max_index], max_y), xytext=(x[max_index], max_y + 0.5),textcoords='offset points',color='red')plt.savefig('wyb_plot.png')plt.annotate("(%s,%s)" % (x[min_index], min_y), xy=(x[min_index], min_y), xytext=(x[min_index], min_y - 0.5),textcoords='offset points',color='green')max_y = np.max(Minimum)min_y = np.min(Minimum)max_index = np.argmax(Average)min_index = np.argmin(Average)plt.annotate("(%s,%s)" % (x[max_index], max_y), xy=(x[max_index], max_y), xytext=(x[max_index], max_y + 0.5),textcoords='offset points',color='red')plt.savefig('wyb_plot.png')plt.annotate("(%s,%s)" % (x[min_index], min_y), xy=(x[min_index], min_y), xytext=(x[min_index], min_y - 0.5),textcoords='offset points',color='green')plt.xlabel('x/'+str(fps)+"fps")plt.ylabel('y/A')plt.title(title)plt.legend()plt.savefig('wyb_plot.png')# plt.show()
# main.py
import functions
import numpy as np
import ocr_imgs
import img_to_plot# 用户告知!/ Users informed!
print("Welcome to use wyb_project!")
print("Please place the video under the video folder")# 逻辑判断 / logical judgment
video_path_lj = int(input("Whether to set the video_path( default video_path = ./video/wybdata.mp4)(1/0): "))
interval_lj = int(input("Whether to set the interval( default screenshot / fps = 30)(1/0): "))video_path = "./video/wybdata.mp4"
output_folder = "./img"
# 输入 video name / Enter your video name
if video_path_lj:vi_name = input("Enter a video name(mind add suffix): ")video_path = "./video/" + vi_name# screenshot/fps
interval = 30  # 默认每隔30帧截取一张图片
if interval_lj:interval = int(input("screenshot / fps: "))# screenshot
extract_frames = functions.extract_frames
extract_frames(video_path, output_folder, interval)# 计数文件夹里的文件个数
directory = output_folder
count_files_in_directory = functions.count_files_in_directory
file_count = count_files_in_directory(directory) - 1# 定义要遍历的文件夹路径
folder_path = output_folder
# 每帧计数
frame_count = 0
# 数据数组
data_str = []
# 丢失数组
data_lost = []# ocr imgs
ocr_imgs = ocr_imgs.ocr_imgs(file_count, folder_path, interval, data_str, data_lost)data_float = [float(x) for x in data_str]# 绘图
# 定义万用表绘制的数据列表
Real_time_value = []
Maximum = []
Average = []
Minimum = []for i in range(len(data_float)):if i % 4 == 0:Real_time_value.append(data_float[i])Maximum.append(data_float[i + 1])Average.append(data_float[i + 2])Minimum.append(data_float[i + 3])fps = interval  # 30
Real_time_value = np.array(Real_time_value)
Maximum = np.array(Maximum)
Average = np.array(Average)
Minimum = np.array(Minimum)x_y_lj = int(input("Whether to set x and y axis scale( default x_scale=2, y_scale=0.500)(1/0): "))
if x_y_lj:x_scale = float(input("input x axis scale: "))y_scale = float(input("input y axis scale: "))title_lj = int(input("Whether to set the title of plot ( default \"wyb_plot\")(1/0): "))
if title_lj:title = input("enter a title for plot: ")title = "wyb_plot"
wyb_plot = img_to_plot.wyb_plot(Real_time_value, Maximum, Average, Minimum, fps, title, x_scale=2, y_scale=0.500)img_del_lj = int(input("Whether to delete imgs of imgs folder( default delete)(1/0): "))
if img_del_lj:folder_path = output_folderdel_imgs  = functions.del_imgs(folder_path)
# ocr_imgs.py
from cnocr import CnOcr
import redef ocr_imgs(file_count, folder_path, interval, data_str, data_lost):# 遍历文件夹文件(图片),进行文字识别for frame_count in range(file_count):img_fp = f"{folder_path}/frame_{interval}_{frame_count}.jpg"ocr = CnOcr()  # 所有参数都使用默认值out_list = ocr.ocr(img_fp)data_list = []for dict in out_list:text = dict.get('text')match = re.search(r'[0-9Oo][.,][0-9Oo][0-9Oo][0-9Oo][0-9Oo]|[Q][0-9Oo][0-9Oo][0-9Oo][0-9Oo]', text)  # 正则化匹配if match:result = match.group()# print(result)# with open('output.txt', 'a') as f:#     print(result, file=f)result = result.replace('O', '0').replace('o', '0').replace(',', '.')  # 修正数据data_list.append(result)# with open('output.txt', 'a') as f:#     print(result, file=f)if len(data_list) % 4 == 0:data_str += data_listelse:print("数据丢失," + "frame_" + str(interval) + "_" + str(frame_count) + ".jpg" + "未采集")data_lost.append(frame_count)# 手动采集图片数据 / manual captureman_cap = int(input("Whether manual collection(1/0): "))if man_cap:for frame in data_lost:data_ins = 0for i in range(4):if i == 0:data_ins = (input("rea: "))if i == 1:data_ins = (input("max: "))if i == 2:data_ins = (input("ave: "))if i == 3:data_ins = (input("min: "))data_str.insert((file_count - len(data_list) + 1) * 4 + i, data_ins)

五、代码、python环境包链接

wyb_project https://www.alipan.com/s/dKwQhvHpb4Z 提取码: 6mm1
点击链接保存,或者复制本段内容,打开「阿里云盘」APP ,无需下载极速在线查看,视频原画倍速播放。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Springboot整合Mybaits启动过程

Springboot整合Mybaits启动过程 1.前言2.MybatisAutoConfiguration3.SqlSessionFactoryBean3.1 XMLConfigBuilder.parse()3.1.1 XMLMapperBuilder.parse()3.1.1.1 XMLStatementBuilder.parse() 4.SqlSession4.1 Executor 1.前言 直接加载mybatis配置文件,然后创建S…

Matlab|【EI复现】电动汽车集群并网的分布式鲁棒优化调度模型

目录 1 内容简介 2 关键知识点 2.1 三类电动汽车模型 3 程序结果 4 下载链接 1 内容简介 电动汽车的数据模型种类繁多,但是用到比较高阶数学方法的并不多,本次分享的程序是下图所示的文章。 采用分布鲁棒优化模型,用到鲁棒对等转换&…

MyBatis3源码深度解析(七)JDBC单连接事务

文章目录 前言2.7 JDBC单连接事务2.7.1 事务的开启与提交2.7.2 事务隔离级别2.7.2.1 并发访问问题(1)脏读(2)不可重复读(3)幻读 2.7.2.2 事务隔离级别(1)TRANSACTION_NONE&#xff1…

ChatGPT 串接到 Discord - 团队协作好助理

ChatGPT 串接到 Discord - 团队协作好助理 ChatGPT 是由 OpenAI 开发的一个强大的语言模型,本篇文章教你如何串接 Discord Bot ,协助团队在工作上更加高效并促进沟通与协作。使 ChatGPT 发挥出最大的功效,进一步提升工作效率和团队协作能力。…

Redis 内存的优化

目录 前言 Redis 的内存碎片问题 判断Redis 内存碎片 如何清理内存碎片? 前言 我想讲一下怎么提高Redis 内存的利用率,redis 的数据是保存在内存中。对内存的利用率低,意味着存的数据很少,并不意味着就没有内存了&#xff0c…

【解读】OWASP大语言模型应用程序十大风险

OWASP大型语言模型应用程序前十名项目旨在教育开发人员、设计师、架构师、经理和组织在部署和管理大型语言模型(LLM)时的潜在安全风险。该项目提供了LLM应用程序中常见的十大最关键漏洞的列表,强调了它们的潜在影响、易利用性和在现实应用程序…

利用华为CodeArts持续交付项目演示流程

软件开发生产线(CodeArts)是面向开发者提供的一站式云端平台,即开即用,随时随地在云端交付软件全生命周期,覆盖需求下发、代码提交、代码检查、代码编译、验证、部署、发布,打通软件交付的完整路径&#xf…

力扣---腐烂的橘子

题目&#xff1a; bfs思路&#xff1a; 感觉bfs还是很容易想到的&#xff0c;首先定义一个双端队列&#xff08;队列也是可以的~&#xff09;&#xff0c;如果值为2&#xff0c;则入队列&#xff0c;我这里将队列中的元素定义为pair<int,int>。第一个int记录在数组中的位…

day15_集合_ArrayList

今日内容 零、 复习昨日 一、集合框架体系 二、Collection 三、泛型 四、迭代 五、List(ArrayList、LinkedList) 零、 复习昨日 日期解析的方法签名(字符串–>日期) Date parse(String s) 日期格式化的方法签名(日期–>字符串) String format(Date date) 运行时异常有哪些…

19、电源管理入门之微内核中的电源管理

目录 1. QNX电源管理框架 2. QNX客户端API库 3. QNX代码分析 4. Fuchsia中的电源管理 5. Minix中的电源管理 6. Harmony OS中的电源管理 之前介绍的电源管理机制基本都是在Linux中实现的,可以看到很复杂,各种框架,明明一个操作非要转来转去,而且在内核里面实现,跟内…

【HarmonyOS】ArkTS-联合类型

目录 联合类型实例 联合类型 联合类型是一种灵活的数据类型&#xff0c;它修饰的变量可以存储不同类型的数据。 语法&#xff1a;let 变量: 类型1 | 类型2 | 类型3 值 基于联合类型&#xff0c;变量可存不同类型数据 实例 // 需求&#xff1a;定义一个变量&#xff0c;存放…

Spring web开发(入门)

1、我们在执行程序时&#xff0c;运行的需要是这个界面 2、简单的web接口&#xff08;127.0.0.1表示本机IP&#xff09; package com.example.demo;import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestCont…

【OD】算法二

开源项目热度榜单 某个开源社区希望将最近热度比较高的开源项目出一个榜单&#xff0c;推荐给社区里面的开发者。对于每个开源项目&#xff0c;开发者可以进行关注(watch)、收藏(star)、fork、提issue、提交合并请求(MR)等。 数据库里面统计了每个开源项目关注、收藏、fork、…

垃圾回收:JavaScript内存管理的利器

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

ChatGPT 控制机器人的基本框架

过去的一年&#xff0c;OpenAI的chatGPT将自然语言的大型语言模型&#xff08;LLM&#xff09;推向了公众的视野&#xff0c;人工智能AI如一夜春风吹遍了巴黎&#xff0c;全世界都为AI而疯狂。 OpenAI ChatGPT是一个使用人类反馈进行微调的预训练生成文本模型。不像以前的模型主…

MYSQL | 数据库到底是怎么来的?

“以史为鉴&#xff0c;可以让我们更深刻地理解现在&#xff0c;预见未来。” 要想知道一件东西是怎么发生的, 我们不妨把时间拨回关系型数据库被提出前后来探索。在信息技术飞速发展的今天&#xff0c;回望数据库管理系统的演进之路&#xff0c;我们可以深刻理解到技术进步如…

Go语言数据结构(二)堆/优先队列

文章目录 1. container中定义的heap2. heap的使用示例3. 刷lc应用堆的示例 更多内容以及其他Go常用数据结构的实现在这里&#xff0c;感谢Star&#xff1a;https://github.com/acezsq/Data_Structure_Golang 1. container中定义的heap 在golang中的"container/heap"…

Linux网络套接字之预备知识

(&#xff61;&#xff65;∀&#xff65;)&#xff89;&#xff9e;嗨&#xff01;你好这里是ky233的主页&#xff1a;这里是ky233的主页&#xff0c;欢迎光临~https://blog.csdn.net/ky233?typeblog 点个关注不迷路⌯▾⌯ 目录 一、预备知识 1.理解源IP地址和目的IP地址 …

【解读】OWASP 大语言模型(LLM)安全测评基准V1.0

大语言模型&#xff08;LLM&#xff0c;Large Language Model&#xff09;是指参数量巨大、能够处理海量数据的模型, 此类模型通常具有大规模的参数&#xff0c;使得它们能够处理更复杂的问题&#xff0c;并学习更广泛的知识。自2022 年以来&#xff0c;LLM技术在得到了广泛的应…

leetcode 热题 100_搜索二维矩阵

题解一&#xff1a; 二叉搜索树&#xff1a;从矩阵右上角观察&#xff0c;结构类似二叉搜索树&#xff0c;因此可以用类似的解法来做。具体做法是双指针从右上角开始&#xff0c;向左下角逐步搜索&#xff0c;如果当前值比目标值大&#xff0c;则向下移动&#xff0c;如果当前值…