iOS裁剪视频文件面对

时间:2016-03-25 09:07:39

标签: ios swift video core-image core-video

我的目标是:

1)将视频文件从磁盘读入CMSampleBuffer的数组。 2)对于每个样本缓冲区,将其转换为CIImage。 3)在每个图像上,运行面部检测并获取面部边界。 4)将每个图像裁剪到该边界。 5)生成CIImage s数组后,将其写回临时文件。

我有一个基本的实现,读取视频:

private func retrieveSampleBuffersForAsset(asset: AVAsset) -> [CMSampleBuffer] {
    var samples: [CMSampleBuffer] = []
    do {

        let reader = try AVAssetReader(asset: asset)
        if let videoTrack = asset.tracksWithMediaType(AVMediaTypeVideo).last {
            let videoSettings: [String: AnyObject] = [kCVPixelBufferPixelFormatTypeKey as String : NSNumber(unsignedInt: kCVPixelFormatType_420YpCbCr8BiPlanarFullRange)]
            let readerOutput = AVAssetReaderTrackOutput(track: videoTrack, outputSettings: videoSettings)
            reader.addOutput(readerOutput)
            reader.startReading()
            while let sample = readerOutput.copyNextSampleBuffer() {
                samples.append(sample)
            }
        }
    } catch {
        return []
    }
    return samples
}

然后我将缓冲区转换为CIImage并将其裁剪为:

let detector = CIDetector(ofType: CIDetectorTypeFace, context: self.context, options: [CIDetectorImageOrientation: NSNumber(integer: 6)])
let features = detector.featuresInImage(self.inputImage)
guard let firstFeature = features.first else {
    return
}

let cropFilter = CIFilter(name: "CICrop")
let cropRect: CIVector = CIVector(CGRect: firstFeature.bounds)
print(firstFeature.bounds)

cropFilter?.setValue(self.inputImage, forKey: "inputImage")
cropFilter?.setValue(cropRect, forKey: "inputRectangle")

self.outputImage = cropFilter?.outputImage

对于每个缓冲区,我创建一个图像,通过上面的自定义过滤器运行它并裁剪它。然后我将输出的裁剪图像并将其附加到列表中。

我被困的地方如下:

1)这是一种疯狂的记忆密集型。

如果没有应用程序崩溃,我无法处理单个视频,这是有道理的,因为如果为每个缓冲区创建一个图像,内存将会变得越来越大。

我在考虑解决这个问题的方法是裁剪图像,然后立即使用资产编写器将其写入磁盘,这样我就不必保留图像了。

2)这很慢。

人脸检测相对优化,但是当我尝试对我的相机胶卷中的所有视频资源执行此操作时,延迟非常明显。

理想情况下,我想使用GPUImage来读取文件并从那里获取样本缓冲区,但我不确定如何。

0 个答案:

没有答案