iOS MachineLearning 系列(6)—— 视频中的物体轨迹分析

简介: 轨迹分析是比物体追踪更上层的一种应用。Vision框架中提供了检测视频中多个物体的运动轨迹等能力,在健身,体育类应用中非常有用。

iOS MachineLearning 系列(6)—— 视频中的物体轨迹分析

轨迹分析是比物体追踪更上层的一种应用。Vision框架中提供了检测视频中多个物体的运动轨迹等能力,在健身,体育类应用中非常有用。

轨迹检测需要一系列的运动状态来分析,因此这类的请求是有状态的,有状态的请求可以被句柄多次调用,其会自动记录之前的状态,从而进行轨迹路径分析。需要注意,在进行轨迹检测时,要保证摄像机的相对静止,镜头的移动可能会影响检测的准确性。

在日常生活中,我们可以使用轨迹检测来进行投球的矫正,球类落点的推测等等。

1 - 解析视频中的物体飞行轨迹

轨迹检测需要保存状态,因此其传入的图像分析参数需要为包含CMTime信息的CMSampleBuffer数据。对于一个视频文件,我们首先要做的是将其中的图像帧解析出来,即获取到CMSampleBuffer数据。示例代码如下:

func detectTrajectories() {
    // 视频资源url
    let videoURL = URL(fileURLWithPath: Bundle.main.path(forResource: "video2", ofType: ".mov")!)
    // 读取视频资源
    let asset =  AVAsset(url: videoURL)
    guard let videoTrack = asset.tracks(withMediaType: .video).first else { return }
    // 获取帧率
    let frameRate = videoTrack.nominalFrameRate
    // 获取总时长
    let frameDuration = CMTime(seconds: 1 / Double(frameRate), preferredTimescale: CMTimeScale(NSEC_PER_SEC))
    // 解析参数
    let assetReaderOutputSettings: [String: Any] = [
        kCVPixelBufferPixelFormatTypeKey as String: kCVPixelFormatType_32BGRA
    ]
    // 解析输出类实例
    let assetReaderOutput = AVAssetReaderTrackOutput(track: videoTrack, outputSettings: assetReaderOutputSettings)
    // 创建视频reader实例
    let assetReader = try! AVAssetReader(asset: asset)
    // 添加输出对象
    assetReader.add(assetReaderOutput)
    // 开始解析
    if assetReader.startReading() {
        // 读取帧
        while let sampleBuffer = assetReaderOutput.copyNextSampleBuffer() {
            autoreleasepool {
                if CMSampleBufferDataIsReady(sampleBuffer) {
                    let timestamp = CMSampleBufferGetPresentationTimeStamp(sampleBuffer)
                    // 进行轨迹分析
                    processFrame(sampleBuffer, atTime: timestamp, withDuration:frameDuration)
                }
            }
        }
    }
}

processFram方法进行轨迹分析,实现如下:

func processFrame(_ sampleBuffer: CMSampleBuffer, atTime time : CMTime, withDuration duration : CMTime) {
    // 创建句柄
    let handler = VNImageRequestHandler(cmSampleBuffer: sampleBuffer, orientation: .up)
    // 发起分析请求
    try? handler.perform([request])
}

request对象的构建如下:

lazy var request: VNDetectTrajectoriesRequest = {
    let req = VNDetectTrajectoriesRequest(frameAnalysisSpacing:.zero, trajectoryLength: 10) { result, error in
        if let error {
            print(error)
        }
        self.handleResult(request: result as! VNDetectTrajectoriesRequest)
    }
    return req
}()

这里的参数后面会详细解释。

在示例中,我们可以添加一个AVPlayer来播放原视频,然后将分析出的轨迹绘制到视频对应的位置上进行对比。handleResult方法示例如下:

func handleResult(request: VNDetectTrajectoriesRequest) {
    for res in request.results ?? [] {
        // 校正后的轨迹点
        let points = res.projectedPoints
        for p in points {
            DispatchQueue.main.async {
                let v = UIView()
                // 视频宽高比
                let scale = self.image.size.width / self.image.size.height
                let width = self.view.frame.width
                let height = width / scale
                let size = CGSize(width: width, height:height)
                v.backgroundColor = .red
                // 播放器充满页面,居中播放视频的y轴偏移
                let offsetY = self.view.frame.height / 2 - height / 2
                v.frame = CGRect(x: p.x * size.width, y: (1 - p.y) * size.height + offsetY, width: 4, height: 4)
                self.view.addSubview(v)
            }
        }
    }
}

轨迹分析效果如下所示:

2 - VNDetectTrajectoriesRequest与VNTrajectoryObservation 类

VNDetectTrajectoriesRequest类一种有状态的分析请求类,继承自VNStatefulRequest,VNDetectTrajectoriesRequest定义如下:

open class VNDetectTrajectoriesRequest : VNStatefulRequest {
    // 构造方法
    // frameAnalysisSpacing参数设置采样间隔  
    // trajectoryLength设置确定一条轨迹的点数 最小为5
    public init(frameAnalysisSpacing: CMTime, trajectoryLength: Int, completionHandler: VNRequestCompletionHandler? = nil)
    // 轨迹点数
    open var trajectoryLength: Int { get }
    // 设置要检测的对象的最小半径
    open var objectMinimumNormalizedRadius: Float
    open var minimumObjectSize: Float

    // 设置要检测对象的最大半径
    open var objectMaximumNormalizedRadius: Float
    open var maximumObjectSize: Float
    
    // 检测的目标帧的时间
    open var targetFrameTime: CMTime

    // 分析结果
    open var results: [VNTrajectoryObservation]? { get }
}

VNTrajectoryObservatio类是轨迹分析的结果类,其内封装了组成轨迹的点。定义如下:

open class VNTrajectoryObservation : VNObservation {
    // 检测出的未处理前的原始点
    open var detectedPoints: [VNPoint] { get }
    // 矫正后的轨迹点
    open var projectedPoints: [VNPoint] { get }
    // 描述轨迹的抛物线方程
    open var equationCoefficients: simd_float3 { get }
    // 测量的物体的半径平均值
    open var movingAverageRadius: CGFloat { get }
}

其中equationCoefficients属性是模拟出的抛物线方程,即下面的公式:

y = a x^2 + bx + c

simd_float3结构中会封装a,b和c的值。

目录
相关文章
|
11天前
|
搜索推荐 Android开发 iOS开发
安卓与iOS系统的用户界面设计对比分析
本文通过对安卓和iOS两大操作系统的用户界面设计进行对比分析,探讨它们在设计理念、交互方式、视觉风格等方面的差异及各自特点,旨在帮助读者更好地理解和评估不同系统的用户体验。
35 1
|
11天前
|
Android开发 数据安全/隐私保护 iOS开发
安卓与iOS系统的发展趋势与比较分析
【2月更文挑战第6天】 在移动互联网时代,安卓和iOS系统作为两大主流移动操作系统,各自呈现出不同的发展趋势。本文将从技术角度出发,对安卓和iOS系统的发展方向、特点及未来趋势进行比较分析,以期为读者提供更深入的了解和思考。
49 4
|
8月前
|
C语言 索引
09-iOS之load和initialize底层调用原理分析
09-iOS之load和initialize底层调用原理分析
61 0
|
11天前
|
安全 搜索推荐 Android开发
Android 与 iOS 的比较分析
【2月更文挑战第5天】 Android 和 iOS 是目前市场上两种最流行的移动操作系统,它们都拥有自己的特点和优势。本文将会分别从操作系统设计、应用生态、安全性等方面对这两种操作系统进行比较和分析,希望能够帮助读者更好地选择适合自己的移动设备。
|
6月前
|
视频直播 API iOS开发
微信团队分享:详解iOS版微信视频号直播中因帧率异常导致的功耗问题
功耗优化一直是 app 性能优化中让人头疼的问题,尤其是在直播这种用户观看时长特别久的场景。怎样能在不影响主体验的前提下,进一步优化微信iOS端视频号直播的功耗占用,本文给出了一个不太一样的答案。
94 0
|
10月前
|
机器学习/深度学习 人工智能 自然语言处理
iOS MachineLearning 系列(22)——将其他三方模型转换成CoreML模型
本篇文章将是本系列文章的最后一篇。本专题将iOS中有关Machine Learning的相关内容做了整体梳理。下面是专题中的其他文章地址,希望如果你有需要,本专题可以帮助到你。
246 0
|
10月前
|
数据可视化 数据挖掘 iOS开发
iOS MachineLearning 系列(21)——CoreML模型的更多训练模板
前面文章中,有介绍如何训练生成定制化需求的 CoreML 模型,以图像分类为例做了演示.
133 0
|
10月前
|
JavaScript Android开发 iOS开发
layui框架实战案例(6):上传图片和视频自动调用IOS或安卓系统的摄像头功能
layui框架实战案例(6):上传图片和视频自动调用IOS或安卓系统的摄像头功能
257 0
|
10月前
|
存储 编解码 缓存
HTTP Live Streaming直播(iOS直播)技术分析与实现
HTTP Live Streaming直播(iOS直播)技术分析与实现
139 1
|
12月前
|
人工智能 数据挖掘 API
iOS MachineLearning 系列(20)—— 训练生成CoreML模型
本系列前面的文章详细的介绍了在iOS中与AI能力相关的API的使用,也介绍了如何使用训练好的CoreML模型来实现更强大的AI能力。然而,无论是成熟的API提供的能力,还是各种各样的三方模型,有时候都并不能满足某一领域内的定制化需求。当我们拥有很多的课训练数据,且需要定制化的AI能力时,其实就可以自己训练生成CoreML模型,将此定制化的模型应用到工程中去。
289 0
iOS MachineLearning 系列(20)—— 训练生成CoreML模型