3

我试图通过一个帧中的每一帧AVAsset并处理每一帧,就好像它是一个图像一样。我无法从我的搜索中找到任何东西。

我试图完成的任务在伪代码中看起来像这样

for each frame in asset

      take the frame as an image and convert to a cvMat
      Process and store data of center points
      Store center points in array

该伪代码中唯一我不知道如何编写的部分是遍历每一帧并将其捕获到图像中。

任何人都可以帮忙吗?

4

2 回答 2

4

一种答案是使用AVAssetImageGenerator

1) 将电影文件加载到AVAsset对象中。
2) 创建一个AVAssetImageGenerator对象。
3) 传入您想要从电影中获取图像的帧的估计时间。

将 2 个属性requestedTimeToleranceBefore和对象设置为requestedTimeToleranceAfter将增加获取单个帧的能力,但会增加处理时间。AVAssetImageGeneratorkCMTimeZero

但是这种方法很慢,我还没有找到更快的方法。

//Load the Movie from a URL
self.movieAsset = [AVAsset assetWithURL:self.movieURL];
NSArray *movieTracks = [self.movieAsset tracksWithMediaType:AVMediaTypeVideo];
AVAssetTrack *movieTrack = [movieTracks objectAtIndex:0];

//Make the image Generator    
AVAssetImageGenerator *imageGenerator = [[AVAssetImageGenerator alloc] initWithAsset:self.movieAsset];

//Create a variables for the time estimation
Float64 durationSeconds = CMTimeGetSeconds(self.movieAsset.duration);
Float64 timePerFrame = 1.0 / (Float64)movieTrack.nominalFrameRate;
Float64 totalFrames = durationSeconds * movieTrack.nominalFrameRate;

//Step through the frames
for (int counter = 0; counter <= totalFrames; counter++){
    CMTime actualTime;
    Float64 secondsIn = ((float)counter/totalFrames)*durationSeconds;
    CMTime imageTimeEstimate = CMTimeMakeWithSeconds(secondsIn, 600);
    NSError *error;
    CGImageRef image = [imageGenerator copyCGImageAtTime:imageTimeEstimate actualTime:&actualTime error:&error];

    ...Do some processing on the image

    CGImageRelease(image);    
}
于 2014-12-28T17:30:19.437 回答
2

您可以使用 AVAssetReaderTrackOutput 简单地生成每一帧:

            let asset = AVAsset(url: inputUrl)
            let reader = try! AVAssetReader(asset: asset)
            let videoTrack = asset.tracks(withMediaType: .video).first!
            let outputSettings = [String(kCVPixelBufferPixelFormatTypeKey): NSNumber(value: kCVPixelFormatType_32BGRA)]
            let trackReaderOutput = AVAssetReaderTrackOutput(track: videoTrack,
                                                             outputSettings: outputSettings)

            reader.add(trackReaderOutput)
            reader.startReading()

            while let sampleBuffer = trackReaderOutput.copyNextSampleBuffer() {
                if let imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) {
                    // do what you want
                }
            }
于 2019-11-01T13:36:15.157 回答