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

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析DNS,个人版 1个月
全局流量管理 GTM,标准版 1个月
简介: 轨迹分析是比物体追踪更上层的一种应用。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天前
|
Java 开发工具 Android开发
安卓与iOS开发环境对比分析
【8月更文挑战第20天】在移动应用开发的广阔天地中,Android和iOS两大平台各自占据着重要的位置。本文将深入探讨这两种操作系统的开发环境,从编程语言到开发工具,从用户界面设计到性能优化,以及市场趋势对开发者选择的影响。我们旨在为读者提供一个全面的比较视角,帮助理解不同平台的优势与挑战,并为那些站在选择十字路口的开发者提供有价值的参考信息。
|
11天前
|
开发框架 Android开发 Swift
安卓与iOS应用开发对比分析
【8月更文挑战第20天】在移动应用开发的广阔天地中,安卓和iOS两大平台各占半壁江山。本文将深入探讨这两大操作系统在开发环境、编程语言、用户界面设计、性能优化及市场分布等方面的差异和特点。通过比较分析,旨在为开发者提供一个宏观的视角,帮助他们根据项目需求和目标受众选择最合适的开发平台。同时,文章还将讨论跨平台开发框架的利与弊,以及它们如何影响着移动应用的开发趋势。
|
11天前
|
安全 搜索推荐 Android开发
安卓与iOS应用开发的对比分析
【8月更文挑战第20天】在移动应用开发领域,安卓和iOS两大平台各领风骚。本文通过深入探讨两者的开发环境、编程语言、用户界面设计、应用市场及分发机制等方面的差异,揭示了各自的优势和挑战。旨在为开发者提供决策支持,同时帮助理解为何某些应用可能优先选择在一个平台上发布。
22 2
|
15天前
|
开发工具 Android开发 Swift
安卓与iOS开发环境对比分析
在移动应用开发的大舞台上,安卓与iOS两大操作系统各占半壁江山。本文将深入浅出地比较两者的开发环境,从开发工具、编程语言到用户界面设计等多个维度进行剖析,旨在为初入行的开发者们提供一盏明灯,帮助他们选择适合自己的开发路径。通过实例分析和数据支持,我们将揭示这两个平台的独特优势和潜在挑战,以及它们如何影响应用的性能和用户体验。
34 1
|
24天前
|
开发框架 开发工具 Android开发
安卓与iOS开发环境对比分析
【8月更文挑战第7天】在移动应用开发的广阔天地中,安卓和iOS两大平台各据一方。本文将深入探讨这两个平台的异同,从开发环境、工具支持到市场定位等方面进行比较。我们将不涉及具体的代码示例,而是聚焦于开发生态的宏观视角,为即将踏入这一领域的开发者提供一个全面的视角。
68 6
|
25天前
|
Android开发 Swift iOS开发
安卓与iOS开发环境的差异性分析
【8月更文挑战第6天】在移动应用开发的广阔天地中,安卓和iOS两大平台各自占据半壁江山。本文将深入探讨这两个操作系统在开发环境方面的主要差异,从编程语言、工具框架到开发成本等多个维度进行比较。通过分析,旨在为开发者提供一个清晰的平台选择指导,帮助他们根据项目需求和个人偏好做出更明智的决策。
70 5
|
23天前
|
开发工具 Android开发 Swift
安卓与iOS开发环境对比分析
在移动应用开发的广阔天地中,安卓与iOS两大平台各占半壁江山。本文通过浅显的语言和直观的比喻,探讨了这两大操作系统在开发环境上的差异与特点,旨在为初入行的开发者们提供一个清晰的指南。我们将从开发工具、编程语言、用户界面设计以及生态系统四个方面进行比较,帮助读者理解每个平台的优势与局限。
|
24天前
|
Java 开发工具 Android开发
安卓与iOS开发环境对比分析
在移动应用开发的大潮中,安卓和iOS两大平台各自展现出独特的开发环境和生态系统。本文将从开发者的角度出发,深入探讨这两个平台在编程语言、开发工具、用户界面设计以及市场分布等方面的不同特点。通过比较分析,旨在为移动应用开发者提供一份实用的参考,帮助他们在项目初期做出更加明智的平台选择。
|
24天前
|
开发工具 Android开发 Swift
安卓与iOS开发环境对比分析
在移动应用开发的广阔天地中,安卓和iOS平台如同双子星座般耀眼。本文将深入探讨这两大操作系统的开发环境,从语言、工具到生态系统,揭示它们的独特魅力与挑战。通过比较,我们不仅能更清晰地看到各自的特点,还能理解开发者如何在这两个平台上进行高效工作。无论你是安卓的忠实拥趸还是iOS的狂热粉丝,这篇文章都将为你提供一个全面的视角,让你对移动应用开发有更深的认识。
33 1
|
26天前
|
开发工具 Android开发 Swift
安卓与iOS开发环境对比分析
在移动应用开发的广阔舞台上,Android和iOS两大操作系统各据一方,它们各自拥有独特的开发环境。本文将深入探讨这两种平台的开发环境,从编程语言、工具、集成开发环境(IDE)到用户界面设计等方面进行比较。我们旨在揭示两者的异同点,并试图理解这些差异如何影响开发者的选择和应用的性能。通过实例分析,我们将探索如何在不同的环境下优化开发流程,以期为开发者提供实用的指导。
下一篇
云函数