当前位置: 首页 > article >正文

使用opencv解析视频,通过图片比对,筛选出每一帧视频的变化

记录瞬间

最近碰到一个问题,在客户端上操作时,存在背景判断的情况,对自动化实现此操作增加难度。

所以考虑到实际的使用,将一些计算机视觉技术加入到实际的使用中,来解决此问题。

import os
import cv2
import numpy# 打开视频文件
video = cv2.VideoCapture('./video/path.mp4')
phone_width = 1080      # 手机设备的宽度
phone_height = 2400     # 手机设备的高度
# 获取视频的帧率和尺寸
fps = video.get(cv2.CAP_PROP_FPS)
width = int(video.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(video.get(cv2.CAP_PROP_FRAME_HEIGHT))
print("fps:", fps, "width:", width, "height:", height)# 创建VideoWriter对象以保存提取的帧为新的视频文件
# output = cv2.VideoWriter('path_to_output_file.mp4', cv2.VideoWriter_fourcc(*'mp4v'), fps, (width, height))
count = 0
# 循环读取视频帧并保存
while video.isOpened():ret, frame = video.read()if not ret:break# 将帧写入输出文件# output.write(frame)# 显示帧(可选)# cv2.imshow('Video', frame)new_img = frame[:phone_height, :phone_width, :]cv2.imwrite(f"./image/{count}.png", new_img)count += 1if cv2.waitKey(1) & 0xFF == ord('q'):break# 释放资源
video.release()
# output.release()
cv2.destroyAllWindows()"""
# 以下是判断图片内容,以第一个图片为准,其他图片作为对比结果,对比相似度
# 但是此方法需要设定一个对比的相似度的值,不是很能说明问题,这个值的取值怎么定,为啥这么定,谁能给出解释?
all_values = {}
img0 = "./image/0.png"
read_img0 = cv2.imread(img0)
H1 = cv2.calcHist([read_img0], [1], None, [256], [0, 256])
H1 = cv2.normalize(H1, H1, 0, 1, cv2.NORM_MINMAX, -1)
for img in os.listdir("./image"):compare = cv2.imread(f"./image/{img}")H2 = cv2.calcHist([compare], [1], None, [256], [0, 256])H2 = cv2.normalize(H2, H2, 0, 1, cv2.NORM_MINMAX, -1)similarity = cv2.compareHist(H1, H2, 0)if similarity > 0.99:try:all_values[similarity] = f"./image/{img}"except:print(f"存在相同的key值{similarity}的数据,预判一下这个预判。好像也没啥用")continueelse:print(f"./image/{img}", similarity)keys = list(all_values.keys())
keys.sort()
print(keys[0], keys[-1], all_values[keys[0]], all_values[keys[-1]])
for data in keys:print(all_values[data])
"""def match_template(source, template, threshod=0.9, method=cv2.TM_CCOEFF_NORMED):"""返回小图左上角的点,在大图中的坐标。:param threshod: 相似度:param template: 目标对比图片:param source: 原始图片:param method::return: list[tuple(x,y),...]"""try:result = cv2.matchTemplate(source, template, method)locations = numpy.where(result >= threshod)res = list(zip(locations[1], locations[0]))  # 返回的是匹配到的template左上角那个坐标点在image中的位置,可能有多个值return resexcept cv2.error as e:print(e)# 另一个方法,是可以通过某一个图片的坐标来判断,主要是判断y坐标的最大值变化,来进行实际操作
img0 = "./image/0.png"
source = cv2.imread(img0, cv2.IMREAD_UNCHANGED)
images = ["./image/pic_path.png", "./image/pic_path.png"]      # 判断一个不变的元素图片
exist_img = ""
for img in images:template = cv2.imread(img, cv2.IMREAD_UNCHANGED)get_pos = match_template(source, template)print(get_pos)if len(get_pos) > 0:exist_img = img
if len(exist_img) > 0:target = cv2.imread(exist_img, cv2.IMREAD_UNCHANGED)max_y_pos = 0max_target_image = ""for img in os.listdir("./image"):temp_img = cv2.imread(f"./image/{img}", cv2.IMREAD_UNCHANGED)get_pos = match_template(temp_img, target, threshod=0.86)print(get_pos, img)try:if get_pos[0][1] > max_y_pos:max_y_pos = get_pos[0][1]max_target_image = imgexcept:print(img)print(max_target_image, max_y_pos)

其中图片相似的判断方法,可以参考:https://blog.csdn.net/qq_39706141/article/details/118730137

以上简单的代码逻辑,实现了设备录屏后,抓取视频文件,解析视频每一帧,并保存每一帧为图片,后续将图片进行解析,判断固定元素在图片中 纵坐标的最大值,即为查看结果的最终图片数据。

录屏可以通过客户端工具如 airtest、appium等。

from airtest.core.api import *
import timeauto_setup(__file__)init_device(platform="Android", uuid="phoneid")
dev = device()wake()
stop_app('appname')
start_app('appname')sleep(3.0)touch(Template(r"pic.png", record_pos=(-0.002, 1.046), resolution=(1080, 2400)))# 录屏开始
dev.start_recording()swipe(Template(r"pic_swipe.png", record_pos=(0.002, 0.076), resolution=(1080, 2400)), vector=[0.0722, 0.3658], duration=1.0)
sleep(8.0)# 结束录屏
dev.stop_recording()

相关文章:

使用opencv解析视频,通过图片比对,筛选出每一帧视频的变化

记录瞬间 最近碰到一个问题,在客户端上操作时,存在背景判断的情况,对自动化实现此操作增加难度。 所以考虑到实际的使用,将一些计算机视觉技术加入到实际的使用中,来解决此问题。 import os import cv2 import numpy#…...

思翼遥控器疑问?

1.地面端与遥控端对频,地面端选择数传2为串口,天空端的UART2通过USB转TTL模块连接电脑,通过串口助手观察得有1Hz输出帧(开启遥控器APP时间段为10Hz),共21字节,请问,这个是什么含义&a…...

anaconda中可以import cv2,但是notebook中cv2 module not found

一、问题 anaconda中成功import cv2 但是jupyter notebook中却无法导入cv2 二、排查 anaconda中使用python路径如下: jupyter notebook中使用python路径如下: 可以发现路径不一致。 三、解决 ①查看可用的kernel ②选中想要修改的kernel,打…...

如何解决 Linux 文件系统挂载失败的问题

当遇到Linux文件系统挂载失败的问题时,您可以通过以下步骤来解决问题: 解决方法: 检查挂载点: 确保要挂载的目标文件系统存在,并且挂载点是正确的。检查挂载点是否已经被其他文件系统占用。 检查文件系统状态&#x…...

PHP填表统计预约打卡表单系统小程序

📋 填表统计预约打卡表单系统——专属定制,信息互动新纪元 📊 填表统计预约打卡表单系统,一款专为现代快节奏生活量身打造的多元化自定义表单统计小程序,集信息填表、预约报名、签到打卡、活动通知、报名投票、班级统…...

PAT乙级( 1009 说反话 1010 一元多项式求导)C语言版本超详细解析

1009 说反话 给定一句英语,要求你编写程序,将句中所有单词的顺序颠倒输出。 输入格式: 测试输入包含一个测试用例,在一行内给出总长度不超过 80的字符串。字符串由若干单词和若干空格组成,其中单词是由英文字母&#x…...

LVSNAT服务搭建

LVSNAT实验环境搭建 在虚拟机上,我的NAT模式ip划分为:172.25.254.0 仅主机模式IP为:192.168.0.0 拓补图如下 配置服务:LVS服务端添加两个网卡,分别为NAT模式和仅主机模式 LVS服务端配置: systemctl st…...

websocket自动重连封装

websocket自动重连封装 前端代码封装 import { ref, onUnmounted } from vue;interface WebSocketOptions {url: string;protocols?: string | string[];reconnectTimeout?: number; }class WebSocketService {private ws: WebSocket | null null;private callbacks: { [k…...

2. Mellanox 网卡的参数调优-LINK_TYPE_P1(GPU-AI-大模型,底层调优-测试)

命令详细分析 echo yes | sudo mlxconfig -d $line set LINK_TYPE_P1=1 这个命令用于设置 Mellanox 网卡设备的 LINK_TYPE_P1 参数为 1。以下是该命令的详细解析: 各部分解释 echo yes |: 这个部分通过管道将字符串 yes 传递给后续命令,以自动确认任何需要用户输入确认的…...

apisix网关ip-restriction插件使用说明

ip-restriction插件可以在网关层进行客户端请求ip拦截。 当然了,一般不推荐使用该方法,专业的事专业工具做。建议有条件,还是上防火墙或者waf来做。 官方文档:ip-restriction | Apache APISIX -- Cloud-Native API Gateway whit…...

使用 Docker 和 PM2 构建高并发 Node.js API 网关

在现代 Web 开发中,构建高并发、高可用的 API 网关是一个常见的需求。本文将介绍如何结合 Docker 和 PM2 构建一个高性能的 Node.js API 网关,并深入探讨分布式限流器的原理与实现。 1. 背景与需求 1.1 高并发 API 网关的挑战 在高并发场景下&#xff…...

现代前端工程化实践:高效构建的秘密

一、前端工程化错误监控 这种监控可以帮助开发人员及时发现和解决问题,提高应用程序的稳定性和可靠性。 1. Sentry:Sentry是一款开源的错误监控平台,可以监控前端、后端以及移动端应用程序中的错误和异常。Sentry提供了实时错误报告、错误分…...

react高级面试题

以下是一些React高级面试题: 一、组件相关 React组件的生命周期有哪些(类组件)?在函数组件中如何实现类似功能? 答案: 类组件生命周期: componentDidMount:组件挂载后调用&#xff…...

html 列动态布局

样式说明: /* 列动态布局,列之间以空格填充 */ li {display: flex;/* flex-direction: column; */justify-content: space-between; }...

C++小等于的所有奇数和=最大奇数除2加1的平方。

缘由 三种思路解题&#xff1a;依据算术推导得到一个规律&#xff1a;小等于的所有奇数和等于最大奇数除以2加1的平方。将在后续发布&#xff0c;总计有十种推导出来的实现代码。 int a 0,aa 1,aaa 0;cin >> a; while (aa<a) aaa aa, aa 2;cout << aaa;i…...

政采云业务网关实践:使用 Higress 统一替代 APISIX/Kong/Istio Ingress

作者&#xff1a;政采云基础架构团队技术专家 朱海峰&#xff08;片风&#xff09; 业务网关项目背景 由于一些历史的背景&#xff0c;政采云平台在网关建设上遇到一些问题&#xff1a; 容器网关配置较多&#xff0c;配置方式多样&#xff0c;运维压力较大&#xff1a; 配置…...

【嵌入式 Linux 音视频+ AI 实战项目】瑞芯微 Rockchip 系列 RK3588-基于深度学习的人脸门禁+ IPC 智能安防监控系统

前言 本文主要介绍我最近开发的一个个人实战项目&#xff0c;“基于深度学习的人脸门禁 IPC 智能安防监控系统”&#xff0c;全程满帧流畅运行。这个项目我目前全网搜了一圈&#xff0c;还没发现有相关类型的开源项目。这个项目只要稍微改进下&#xff0c;就可以变成市面上目前…...

安卓7以上抓包证书安装

安卓7以上抓包证书安装 fiddler 用户可以直接试试这个文件 前提是要root过了&#xff0c;如果是模拟器就很容易开启 前提&#xff1a;要有openssl工具&#xff0c;在linux一个指令就可以下载了&#xff1a;sudo apt-get install openssl,windons则是在https://www.openssl.org/…...

【C#】任务调度的实现原理与组件应用Quartz.Net

Quartz 是一个流行的开源作业调度库&#xff0c;最初由 Terracotta 开发&#xff0c;现在由 Terracotta 的一部分 Oracle 所有。它主要用于在 Java 应用程序中调度作业的执行。Quartz 使用了一种复杂的底层算法来管理任务调度&#xff0c;其中包括任务触发、执行、持久化以及集…...

C语言:深入了解指针4(超级详细)

看之前必须得掌握有一定指针的知识&#xff0c;不然会看不懂&#xff0c;如果有不懂的可以看我博客 指针1&#xff0c;指针2&#xff0c;指针3 这三个讲了指针全部的基础知识超级详细&#xff0c;这篇只要是讲一些指针练习题也是非常详细 1. sizeof和strlen的对⽐ 1. 基本定义…...

C#+Redis接收数据并定时3秒钟频率异步保存到数据库

要在C#中实现从Redis接收数据,并以每3秒的频率异步保存到数据库,你可以使用System.Threading.Tasks.Task.Delay或System.Timers.Timer来创建一个定时任务。不过,对于更复杂的定时和调度需求,System.Threading.Tasks.Timer或Quartz.NET等库可能更合适。 在这个场景中,由于…...

CEF132 编译指南 Windows 篇 - 拉取 CEF 源码 (五)

1. 引言 获取 CEF 132 源码是开始编译工作的前提和关键步骤。在完成 depot_tools 的安装和配置后&#xff0c;我们需要通过正确的方式下载和同步 CEF 的源代码。由于 CEF 项目依赖于 Chromium 的大量组件&#xff0c;因此源码的获取过程需要特别注意同步策略和版本管理&#x…...

【鸿蒙开发】第二十四章 AI - Core Speech Kit(基础语音服务)

目录 1 简介 1.1 场景介绍 1.2 约束与限制 2 文本转语音 2.1 场景介绍 2.2 约束与限制 2.3 开发步骤 2.4 设置播报策略 2.4.1 设置单词播报方式 2.4.2 设置数字播报策略 2.4.3 插入静音停顿 2.4.4 指定汉字发音 2.5 开发实例 3 语音识别 3.1 场景介绍 3.2 约束…...

DeepSeek与llama本地部署(含WebUI)

DeepSeek从2025年1月起开始火爆&#xff0c;成为全球最炙手可热的大模型&#xff0c;各大媒体争相报道。我们可以和文心一言一样去官网进行DeepSeek的使用&#xff0c;那如果有读者希望将大模型部署在本地应该怎么做呢&#xff1f;本篇文章将会教你如何在本地傻瓜式的部署我们的…...

让万物「听说」:AI 对话式智能硬件方案和发展洞察

本文整理自声网 SDK 新业务探索组技术负责人&#xff0c;IoT 行业专家 吴方方 1 月 18 日在 RTE 开发者社区「Voice Agent 硬件分享会」上的分享。本次主要介绍了 AI 对话式智能硬件的发展历程&#xff0c;新一波 AI 浪潮所带来的创新机遇、技术挑战以及未来的展望。 在语音交…...

Day38-【13003】短文,二叉树,完全二叉树,二叉树的顺序存储,和链式存储

文章目录 第二节 二叉树二叉树的定义及重要性质n个结点&#xff0c;能组合成多少个不同的二叉树满二叉树、完全二叉树完全二叉树的性质二叉树的性质二叉树的结点数完全二叉树的高度 二叉树的存储顺序存储方式链式存储方式二叉链表的程序实现二叉链表空指针域计算 第二节 二叉树…...

MyBatis常见知识点

#{} 和 ${} 的区别是什么&#xff1f; 答&#xff1a; ${}是 Properties 文件中的变量占位符&#xff0c;它可以用于标签属性值和 sql 内部&#xff0c;属于原样文本替换&#xff0c;可以替换任意内容&#xff0c;比如${driver}会被原样替换为com.mysql.jdbc. Driver。 一个…...

4. 【.NET 8 实战--孢子记账--从单体到微服务--转向微服务】--什么是微服务--微服务设计原则与最佳实践

相比传统的单体应用&#xff0c;微服务架构通过将大型系统拆分成多个独立的小服务&#xff0c;不仅提升了系统的灵活性和扩展性&#xff0c;也带来了许多设计和运维上的挑战。如何在设计和实现微服务的过程中遵循一系列原则和最佳实践&#xff0c;从而构建一个稳定、高效、易维…...

【AI】在Ubuntu中使用docker对DeepSeek的部署与使用

这篇文章前言是我基于部署好的deepseek-r1:8b模型跑出来的 关于部署DeepSeek的前言与介绍 在当今快速发展的技术环境中&#xff0c;有效地利用机器学习工具来解决问题变得越来越重要。今天&#xff0c;我将引入一个名为DeepSeek 的工具&#xff0c;它作为一种强大的搜索引擎&a…...

Linux后台运行进程

linux 后台运行进程&#xff1a;& , nohup-腾讯云开发者社区-腾讯云 进程 &&#xff0c;后台运行&#xff0c;结束终端退出时结束进程。 nohup 进程 &&#xff0c;后台运行&#xff0c;结束终端后依然保持运行。...