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

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 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的值。

目录
相关文章
|
1月前
|
开发框架 前端开发 Android开发
Flutter 与原生模块(Android 和 iOS)之间的通信机制,包括方法调用、事件传递等,分析了通信的必要性、主要方式、数据传递、性能优化及错误处理,并通过实际案例展示了其应用效果,展望了未来的发展趋势
本文深入探讨了 Flutter 与原生模块(Android 和 iOS)之间的通信机制,包括方法调用、事件传递等,分析了通信的必要性、主要方式、数据传递、性能优化及错误处理,并通过实际案例展示了其应用效果,展望了未来的发展趋势。这对于实现高效的跨平台移动应用开发具有重要指导意义。
166 4
|
1月前
|
安全 Android开发 数据安全/隐私保护
深入探讨iOS与Android系统安全性对比分析
在移动操作系统领域,iOS和Android无疑是两大巨头。本文从技术角度出发,对这两个系统的架构、安全机制以及用户隐私保护等方面进行了详细的比较分析。通过深入探讨,我们旨在揭示两个系统在安全性方面的差异,并为用户提供一些实用的安全建议。
|
3月前
|
开发工具 Android开发 Swift
安卓与iOS开发环境对比分析
在移动应用开发的广阔舞台上,安卓和iOS这两大操作系统无疑是主角。它们各自拥有独特的特点和优势,为开发者提供了不同的开发环境和工具。本文将深入浅出地探讨安卓和iOS开发环境的主要差异,包括开发工具、编程语言、用户界面设计、性能优化以及市场覆盖等方面,旨在帮助初学者更好地理解两大平台的开发特点,并为他们选择合适的开发路径提供参考。通过比较分析,我们将揭示不同环境下的开发实践,以及如何根据项目需求和目标受众来选择最合适的开发平台。
55 2
|
26天前
|
Java 开发工具 Android开发
安卓与iOS开发环境对比分析
在移动应用开发的广阔天地中,安卓和iOS两大平台各自占据半壁江山。本文深入探讨了这两个平台的开发环境,从编程语言、开发工具到用户界面设计等多个角度进行比较。通过实际案例分析和代码示例,我们旨在为开发者提供一个清晰的指南,帮助他们根据项目需求和个人偏好做出明智的选择。无论你是初涉移动开发领域的新手,还是寻求跨平台解决方案的资深开发者,这篇文章都将为你提供宝贵的信息和启示。
30 8
|
29天前
|
安全 Android开发 数据安全/隐私保护
深入探索Android与iOS系统安全性的对比分析
在当今数字化时代,移动操作系统的安全已成为用户和开发者共同关注的重点。本文旨在通过比较Android与iOS两大主流操作系统在安全性方面的差异,揭示两者在设计理念、权限管理、应用审核机制等方面的不同之处。我们将探讨这些差异如何影响用户的安全体验以及可能带来的风险。
38 1
|
3月前
|
安全 Android开发 数据安全/隐私保护
探索安卓与iOS的安全性差异:技术深度分析与实践建议
本文旨在深入探讨并比较Android和iOS两大移动操作系统在安全性方面的不同之处。通过详细的技术分析,揭示两者在架构设计、权限管理、应用生态及更新机制等方面的安全特性。同时,针对这些差异提出针对性的实践建议,旨在为开发者和用户提供增强移动设备安全性的参考。
155 3
|
2月前
|
开发工具 Android开发 Swift
安卓与iOS开发环境的差异性分析
【10月更文挑战第8天】 本文旨在探讨Android和iOS两大移动操作系统在开发环境上的不同,包括开发语言、工具、平台特性等方面。通过对这些差异性的分析,帮助开发者更好地理解两大平台,以便在项目开发中做出更合适的技术选择。
|
3月前
|
安全 Linux Android开发
探索安卓与iOS的安全性差异:技术深度分析
本文深入探讨了安卓(Android)和iOS两个主流操作系统平台在安全性方面的不同之处。通过比较它们在架构设计、系统更新机制、应用程序生态和隐私保护策略等方面的差异,揭示了每个平台独特的安全优势及潜在风险。此外,文章还讨论了用户在使用这些设备时可以采取的一些最佳实践,以增强个人数据的安全。
|
3月前
|
IDE 开发工具 Android开发
安卓与iOS开发环境对比分析
本文将探讨安卓和iOS这两大移动操作系统在开发环境上的差异,从工具、语言、框架到生态系统等多个角度进行比较。我们将深入了解各自的优势和劣势,并尝试为开发者提供一些实用的建议,以帮助他们根据自己的需求选择最适合的开发平台。
59 1
|
4月前
|
开发框架 Android开发 Swift
安卓与iOS应用开发对比分析
【8月更文挑战第20天】在移动应用开发的广阔天地中,安卓和iOS两大平台各占半壁江山。本文将深入探讨这两大操作系统在开发环境、编程语言、用户界面设计、性能优化及市场分布等方面的差异和特点。通过比较分析,旨在为开发者提供一个宏观的视角,帮助他们根据项目需求和目标受众选择最合适的开发平台。同时,文章还将讨论跨平台开发框架的利与弊,以及它们如何影响着移动应用的开发趋势。