Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >iOS MachineLearning 系列(5)—— 视频中的物体运动跟踪

iOS MachineLearning 系列(5)—— 视频中的物体运动跟踪

作者头像
珲少
发布于 2023-04-27 12:38:49
发布于 2023-04-27 12:38:49
72200
代码可运行
举报
文章被收录于专栏:一“技”之长一“技”之长
运行总次数:0
代码可运行

iOS MachineLearning 系列(5)—— 视频中的物体运动追踪

本系列的前面几篇文章中,我们将静态图片分析相关的API做了详尽的介绍。在Vision框架中,还提供了视频中物体追踪的能力。

仔细想来,其实视频的分析和静态图片的分析本质上并无太大的区别,我们可以将视频拆解成图片帧,之后再对图片进行静态分析。将所有图片帧的分析结果反馈到视频上,即实现了对视频的分析能力。

视频中物体运动的跟踪常在一些AR游戏中应用,这些现实增强类的应用常常需要实时追踪显示中的物体。

1 - 先看一个简单的示例

我们以矩形区域追踪为例,与前面文章介绍的静态分析类似,运动追踪实现的核心点也只有三个:

1. 请求操作句柄。

2. 构建请求。

3. 处理分析请求的回调。

首先我们先来构建操作句柄:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
lazy var handler = VNSequenceRequestHandler()

构建请求:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
lazy var request: VNTrackRectangleRequest = {    
    let req = VNTrackRectangleRequest(rectangleObservation: observation) { result, error in
        // 处理结果
        if let error {
            print(error)
        }
        // 处理结果
        self.handleResult(request: result as! VNTrackRectangleRequest)
    }
    // 选择快速模式
    req.trackingLevel = .fast
    return req
}()

在构建请求时,需要我们传入一个初始的描述矩形区域的VNRectangleObservation对象,之后的追踪会以参数为对象。VNRectangleObservation的构建示例如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 预检测得到的
var observation = VNRectangleObservation(boundingBox: CGRect(x: 0.3728713095188141, y: 0.833836019039154, width: 0.16493645310401917, height: 0.07572066783905029))

需要注意,这里的数据是我使用静态分析预先处理视频首帧得到的,实际应用中,我们也可以先对首帧进行静态分析,找到要追踪的矩形区域。

之外,我们还需要对视频资源进行一些处理,简单来说,即是解析视频帧,之后逐帧进行分析,示例代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
func readVideo() {
    // 视频路径
    let videoURL = URL(fileURLWithPath: Bundle.main.path(forResource: "video1", ofType: ".mp4")!)
    // 读取视频资源
    let videoAsset = AVURLAsset(url: videoURL)
    // 创建视频资源解析器
    let videoProcessor = AVAssetImageGenerator(asset: videoAsset)
    videoProcessor.requestedTimeToleranceBefore = CMTime.zero
    videoProcessor.requestedTimeToleranceAfter = CMTime.zero
    // 获取视频时长
    let durationSeconds: Float64 = CMTimeGetSeconds(videoAsset.duration)
    // 存储要截取的视频帧时间点
    var times = [NSValue]()
    // 以每秒60帧为标准,获取总帧数
    let totalFrames: Float64 = durationSeconds * 60
    // 定义 CMTime 即请求缩略图的时间间隔
    for i in 0...Int(totalFrames) {
       let timeFrame = CMTimeMake(value: Int64(i), timescale: 60)
       let timeValue = NSValue(time: timeFrame)
       times.append(timeValue)
    }
    // 进行图片解析
    videoProcessor.generateCGImagesAsynchronously(forTimes: times) { time, cgImage, actualTime, resultCode, error  in
        if let cgImage = cgImage {
            let image = UIImage(cgImage: cgImage)
            self.images.append(image)
        }
    }
}

当所有视频帧处理完成后,我们即可以对其进行矩形追踪,示例方法如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
func start() {
    var count = 0
    // 这里定时器的作用是逐帧的刷新页面,同时进行追踪
    Timer.scheduledTimer(withTimeInterval: 0.03, repeats: true) { t in
        if count < self.images.count {
            // 设置页面展示的图片
            self.imageView.image = self.images[count]
            // 将inputObservation设置为上一次的分析结果
            self.request.inputObservation = self.observation
            // 进行追踪分析
            try? self.handler.perform([self.request], on: self.images[count].cgImage!, orientation: .up)
            count += 1
        } else {
            // 当循环结束时,设置isLastFrame表情请求已经到了最后一帧
            self.request.isLastFrame = true
            // 停止定时器
            t.invalidate()
            print("end")
        }
    }
    print(images.count)
}

需要注意,追踪分析的本质是对矩形区域的前后状态进行比较,将其运行情况进行分析。因此,每次进行分析请求时需要将上一次的结果作为inputObservation进行输入,当视频结束时,设置起isLastFrame来结束分析,释放资源。

最后,分析结果的处理很简单:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
func handleResult(request: VNTrackRectangleRequest) {
    print(request.results)
    for r in request.results ?? [] {
        guard let result = r as? VNRectangleObservation else {
            return
        }
        observation = result
        var box = result.boundingBox
        // 坐标系转换
        box.origin.y = 1 - box.origin.y - box.size.height
        print("box:", result.boundingBox)
        DispatchQueue.main.async {
            let size = self.imageView.frame.size
            self.boxView.frame = CGRect(x: box.origin.x * size.width, y: box.origin.y * size.height, width: box.size.width * size.width, height: box.size.height * size.height)
        }
    }
}

其中,box是我们定义好的一个UIView蒙层,用来表示追踪的结果,效果如下GIF图所示:

其中,白色的色块是原始视频中的矩形物体,红色的色块是我们的追踪结果。

2 - 几个重要的类

VNSequenceRequestHandle类无需多说了,它的作用就是发起请求,其与VNImageRequestHandler类的最大区别在于VNSequenceRequestHandle在创建对象时无需设置一个图片资源,VNSequenceRequestHandle主要是用来分析一系列图片的,因此其是在请求执行时设置图片资源的。

VNTrackRectangleRequest类用来创建矩形区域追踪请求,继承自VNTrackingRequest类,VNTrackingRequest的定义如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
open class VNTrackingRequest : VNImageBasedRequest {
    // 输入追踪区域的Observation对象 每次根据中要刷新
    open var inputObservation: VNDetectedObjectObservation
    // 追踪模式
    open var trackingLevel: VNRequestTrackingLevel
    // 是否是最后一帧,如果设置为true,将停止后续分析
    open var isLastFrame: Bool
}

其中trackingLevel用了设置追踪的算法模式:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public enum VNRequestTrackingLevel : UInt, @unchecked Sendable {
    // 精准优先
    case accurate = 0
    // 速度优先
    case fast = 1
}

更多时候,我们要追踪的物体可能不是规则的矩形,也可能是会进行翻转和形变的物体,例如行驶中的汽车,飞行中的球类,奔跑中的人等。对于这类需求,我们需要使用VNTrackObjectRequest来进行追踪,其用法与VNTrackRectangleRequest几乎完全一致,这里就不再赘述,示例代码可以在下面找到:

https://github.com/ZYHshao/MachineLearnDemo

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-04-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Tomcat启动失败(闪退)和启动之后localhost:8080出现404
为了伟大的房产事业
2024/03/15
1890
Tomcat启动失败(闪退)和启动之后localhost:8080出现404
在tomcat中部署静态资源访问
如果你想让你的服务器直接能访问某一个目录,不需要经过servlet,也不需要用ftp。
zhangheng
2020/04/29
1.8K0
tomcat部署war包访问显示404
在eclipse导出的maven项目war包,放到tomcat下启动,顺利启动且无报错,但是浏览器访问该项目时显示404
全栈程序员站长
2022/06/28
2.6K0
tomcat部署war包访问显示404
tomcat相关配置技巧梳理
tomcat常用架构: 1)nginx+tomcat;即前端放一台nginx,然后通过nginx反向代理到tomcat端口(可参考:分享一例测试环境下nginx+tomcat的视频业务部署记录) 2)tomcat直接部署站点,不通过nginx反向代理。 下面针对tomcat的有关配置使用进行说明: 1)默认站点根目录 tomcat的默认站点根目录是webapps/ROOT,配置文件是server.xml, 配置文件server.xml 里的主要内容是: [root@huanqiu-test ~]# vim
洗尽了浮华
2018/01/23
1.2K0
Tomcat部署WAR包访问不带项目名的方式
2、在Tomcat的安装目录的conf下找到server.xml的文件,如:D:\apache-tomcat-9.0.8\conf\server.xml
全栈程序员站长
2022/08/29
1.7K0
IIS、apache、tomcat服务器虚拟主机配置
首先我们有一个域名  xxx.com;(注,两个一级域名不相同也可以) 有两个二级域名   priject.xxx.com 和 movie.xxx.com 有一台主机 ,现在假设访问主机电脑 IIS服务器虚拟主机配置方法 1、在IIS中添加网站 其中  绑定一栏中的主机名为 priject.xxx.com,在分配好网站的文件路径 2、添加isapi筛选器 其中可执行文件位置为php的安装位置 3、处理程序映射->添加脚本映射 4、最后重启IIS服务器,就可以用域名访问了 再添加站点,同样的步骤。 tomcat服务器虚拟主机配置方法 在Engine节点下增加host节点 <Host name="priject.xxx.com"  appBase="webapps/priject"             unpackWARs="true" autoDeploy="true">         <!-- SingleSignOn valve, share authentication between web applications              Documentation at: /docs/config/valve.html -->         <!--         <Valve className="org.apache.catalina.authenticator.SingleSignOn" />         -->         <!-- Access log processes all example.              Documentation at: /docs/config/valve.html              Note: The pattern used is equivalent to using pattern="common" -->         <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"                prefix="localhost_access_log." suffix=".txt"                pattern="%h %l %u %t &quot;%r&quot; %s %b" /> </Host> <Host name= "movie.xxx.com"  appBase="webapps/movie"             unpackWARs="true" autoDeploy="true">         <!-- SingleSignOn valve, share authentication between web applications              Documentation at: /docs/config/valve.html -->         <!--         <Valve className="org.apache.catalina.authenticator.SingleSignOn" />         -->         <!-- Access log processes all example.              Documentation at: /docs/config/valve.html              Note: The pattern used is equivalent to using pattern="common" -->         <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"                prefix="localhost_access_log." suffix=".txt"                pattern="%h %l %u %t &quot;%r&quot; %s %b" /> </Host> 注在webapps目录下的movie要创建ROOT目录才可以,而且ROOT必须大写。在ROOT目录先放置jsp代码。 tomcat会根据主机名称自动寻找相应的目录去访问 apache服务器虚拟主机配置方法 打开httpd.conf文件 去掉LoadModule vhost_alias_module modules/mod_vhost_alias.so 这句前面的#号 和 Include conf/extra/httpd-vhosts.conf这句前面的#号 Include conf/e
张泽旭
2018/12/10
2.9K0
nginx+tomcat绑定二级域名,部署多个应用
本文介绍在阿里云上开通二级域名,并使用单个tomcat部署多个应用和ngnix+tomcat(多个)两种方式实现多个应用的部署,以下为操作步骤。
三哥
2019/05/13
3.9K0
nginx+tomcat绑定二级域名,部署多个应用
配置tomcat限制指定IP地址访问后端应用
1. 场景 后端存在N个tomcat实例,前端通过nginx反向代理和负载均衡。 tomcat1 tomcatN | | | | ----------------- | nginx 2. 需求 为了保护后端应用,tomcat实例只允许前端nginx服务器IP访问,其他任何地址的访问都被拒绝。
编程随笔
2019/09/11
3.2K0
配置tomcat限制指定IP地址访问后端应用
【腾讯云的1001种玩法】IIS、apache、tomcat服务器虚拟主机配置
张泽旭
2017/03/15
6.1K0
Tomcat闪退解决方案[通俗易懂]
Tomcat启动后闪退, tomcat可以通过命令行startup或直接双击startup.bat执行 通常发生闪退时,我们可以尝试在命令行中执行一下startup命令
全栈程序员站长
2022/09/02
2.2K0
Tomcat闪退解决方案[通俗易懂]
Tomcat 配置局域网内的Https
Tomcat 配置局域网内的Https 1、生成证书 可以使用jdk自带的keytool生成证书 keytool -genkeypair -alias "tomcat" -keyalg "RSA"
季鸟猴
2022/11/14
1.1K0
Tomcat 配置局域网内的Https
Tomcat搭建文件服务器
①. 进入tomcat下的conf目录,找到server.xml文件,在Host标签下加入如下标签     path:表示对外映射的路径,     docBase:物理磁盘路径,可以是绝对路径,也可以是相对路径,甚至是共享磁盘目录     debug参数不用管     reloadable表示是否重新加载 <Context path="/files" docBase="D://files" debug="0" reloadable="true"/> 访问http://localhost/files/a.t
用户1215919
2018/02/27
3.2K0
Tomcat配置通过域名直接访问项目首页的完整步骤
我们以tomcat为例通过输入域名直接访问项目首页的配置方法。我的域名为:www.nnjskz.cn,也欢迎大家访问。
Jensen_97
2023/07/20
2.3K0
Pinpoint
sudo scp [email protected]:/Users/M/Downloads/pinpoint-web-1.6.2.war /root/pinpoint sudo scp [email protected]:/Users/M/Downloads/pinpoint-collector-1.6.2.war /root/pinpoint sudo scp [email protected]:/Users/M/Downloads/hbase-create.hbase /root/pinpoint
XING辋
2019/03/26
8210
Apache Tomcat服务部署网站
Tomcat是Apache软件基金会的Jakarta项目中的一个核心项目,由Apache、Sun 和其他一些公司及个人共同开发而成.由于有了Sun的参与和支持,最新的Servlet和JSP规范总是能在Tomcat中得到体现,因为Tomcat 技术先进、性能稳定,而且免费,因而深受Java爱好者的喜爱并得到了部分软件开发商的认可,成为目前比较流行的Web应用服务器.
王瑞MVP
2022/12/28
6820
Eclipse工程部署到Tomcat时出现中文乱码问题
1、修改Server.xml文件:添加URIEncoding="UTF-8" <?xml version="1.0" encoding="UTF-8"?> <!-- Licensed to the
JQ实验室
2022/02/09
4820
windows服务器使用Tomcat发布Springboot的war包项目
(1)Tomcat 8.x 下载地址:https://tomcat.apache.org/download-80.cgi
Mr.Vv
2022/05/11
1.6K0
windows服务器使用Tomcat发布Springboot的war包项目
Springboot部署war项目文件到Tomcat静态文件(css、js和图片等)加载不出来的解决方法
(2)/elec/WEB-INF/classes/static/:项目实际war包解决后,静态文件地址
Mr.Vv
2022/05/11
2.6K0
Springboot部署war项目文件到Tomcat静态文件(css、js和图片等)加载不出来的解决方法
Tomcat的Session复制集群
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
ruochen
2021/11/24
1.3K0
Tomcat最佳优化方案总结 原
1. BIO由于每个请求都要创建一个线程来处理,线程开销比较大,不能再高并发的场景,性能也是最低的。 2. NIO是一个基于缓冲区、并能提供非阻塞I/O操作的Java API,比传统的bio更好的并发性能。 3. APR(Apache Portable Run-time libraries)简单理解,就是从操作系统级别解决异步IO问题,大幅度的提高服务器的处理和响应性能, 也是Tomcat运行高并发应用的首选模式。 
wuweixiang
2018/08/14
3.5K0
Tomcat最佳优化方案总结
                                                                            原
推荐阅读
相关推荐
Tomcat启动失败(闪退)和启动之后localhost:8080出现404
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验