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

简介: 本系列的前面几篇文章中,我们将静态图片分析相关的API做了详尽的介绍。在Vision框架中,还提供了视频中物体追踪的能力。仔细想来,其实视频的分析和静态图片的分析本质上并无太大的区别,我们可以将视频拆解成图片帧,之后再对图片进行静态分析。将所有图片帧的分析结果反馈到视频上,即实现了对视频的分析能力。视频中物体运动的跟踪常在一些AR游戏中应用,这些现实增强类的应用常常需要实时追踪显示中的物体。

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

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

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

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

1 - 先看一个简单的示例

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

1. 请求操作句柄。

2. 构建请求。

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

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

lazy var handler = VNSequenceRequestHandler()

构建请求:

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的构建示例如下:

// 预检测得到的
var observation = VNRectangleObservation(boundingBox: CGRect(x: 0.3728713095188141, y: 0.833836019039154, width: 0.16493645310401917, height: 0.07572066783905029))

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

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

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)
        }
    }
}

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

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来结束分析,释放资源。

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

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的定义如下:

open class VNTrackingRequest : VNImageBasedRequest {
    // 输入追踪区域的Observation对象 每次根据中要刷新
    open var inputObservation: VNDetectedObjectObservation
    // 追踪模式
    open var trackingLevel: VNRequestTrackingLevel
    // 是否是最后一帧,如果设置为true,将停止后续分析
    open var isLastFrame: Bool
}

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

public enum VNRequestTrackingLevel : UInt, @unchecked Sendable {
    // 精准优先
    case accurate = 0
    // 速度优先
    case fast = 1
}

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

https://github.com/ZYHshao/MachineLearnDemo

目录
相关文章
|
3月前
|
图形学 Android开发 iOS开发
穿越数字洪流,揭秘Unity3d中的视频魔法!Windows、Android和iOS如何征服RTSP与RTMP的终极指南!
【8月更文挑战第15天】在数字媒体的海洋中,实时视频流是连接世界的桥梁。对于那些渴望在Unity3d中搭建这座桥梁的开发者来说,本文将揭示如何在Windows、Android和iOS平台上征服RTSP与RTMP的秘密。我们将深入探讨这两种协议的特性,以及在不同平台上实现流畅播放的技巧。无论你是追求稳定性的RTSP拥趸,还是低延迟的RTMP忠实粉丝,这里都有你需要的答案。让我们一起穿越数字洪流,探索Unity3d中视频魔法的世界吧!
64 2
|
机器学习/深度学习 API iOS开发
iOS MachineLearning 系列(17)—— 几个常用的对象识别 CoreML 模型
上一篇文章中,我们介绍了几个官方的图片分类的模型,图片分类模型的应用场景在于将图片中最主要的事物进行识别,在已有的词库中找到最可能得事物。而对象识别则要更高级一些。再之前的文章,我们介绍过可以使用官方提供的API来进行矩形识别,文本识别,二维码识别以及人脸识别等,这类识别功能的特点是我们不仅可以将图片中的物体位置和尺寸分析出来,还可以对其进行类别的分类。
356 0
|
视频直播 API iOS开发
微信团队分享:详解iOS版微信视频号直播中因帧率异常导致的功耗问题
功耗优化一直是 app 性能优化中让人头疼的问题,尤其是在直播这种用户观看时长特别久的场景。怎样能在不影响主体验的前提下,进一步优化微信iOS端视频号直播的功耗占用,本文给出了一个不太一样的答案。
165 0
|
机器学习/深度学习 人工智能 自然语言处理
iOS MachineLearning 系列(22)——将其他三方模型转换成CoreML模型
本篇文章将是本系列文章的最后一篇。本专题将iOS中有关Machine Learning的相关内容做了整体梳理。下面是专题中的其他文章地址,希望如果你有需要,本专题可以帮助到你。
355 0
|
数据可视化 数据挖掘 iOS开发
iOS MachineLearning 系列(21)——CoreML模型的更多训练模板
前面文章中,有介绍如何训练生成定制化需求的 CoreML 模型,以图像分类为例做了演示.
215 0
|
人工智能 数据挖掘 API
iOS MachineLearning 系列(20)—— 训练生成CoreML模型
本系列前面的文章详细的介绍了在iOS中与AI能力相关的API的使用,也介绍了如何使用训练好的CoreML模型来实现更强大的AI能力。然而,无论是成熟的API提供的能力,还是各种各样的三方模型,有时候都并不能满足某一领域内的定制化需求。当我们拥有很多的课训练数据,且需要定制化的AI能力时,其实就可以自己训练生成CoreML模型,将此定制化的模型应用到工程中去。
421 0
iOS MachineLearning 系列(20)—— 训练生成CoreML模型
|
自然语言处理 搜索推荐 iOS开发
iOS MachineLearning 系列(19)—— 分析文本中的问题答案
本篇文章将介绍Apple官方推荐的唯一的一个文本处理模型:BERT-SQuAD。此模型用来分析一段文本,并根据提供的问题在文本中寻找答案。需要注意,BERT模型不会生成新的句子,它会从提供的文本中找到最有可能的答案段落或句子。
195 0
iOS MachineLearning 系列(19)—— 分析文本中的问题答案
|
存储 API vr&ar
iOS MachineLearning 系列(18)—— PoseNet,DeeplabV3与FCRN-DepthPrediction模型
本篇文章将再介绍三个官方的CoreML模型:PoseNet,DeeplabV3和FCRN-DepthPrediction。
328 0
iOS MachineLearning 系列(18)—— PoseNet,DeeplabV3与FCRN-DepthPrediction模型
|
JavaScript Android开发 iOS开发
layui框架实战案例(6):上传图片和视频自动调用IOS或安卓系统的摄像头功能
layui框架实战案例(6):上传图片和视频自动调用IOS或安卓系统的摄像头功能
506 0
|
机器学习/深度学习 iOS开发 计算机视觉
iOS MachineLearning 系列(16)—— 几个常用的图片分类CoreML模型
对于图片识别分类的模型来说,其输入和输出都一样,输入都为图像参数,输入为两部分,一部分为最佳预测结果,一部分为可能得预测结果及其可信度。
413 0