Ala*_*lak 6 iphone avfoundation ios swift apple-vision
我尝试使用 Vision (VNRequest) 中检测到的人脸的 boundingBox 裁剪 CVImageBuffer(来自 AVCaptureOutput)。当我使用以下方法绘制 AVCaptureVideoPreviewLayer 时:
let origin = previewLayer.layerPointConverted(fromCaptureDevicePoint: rect.origin)
let size = previewLayer.layerPointConverted(fromCaptureDevicePoint: rect.size.cgPoint)
Run Code Online (Sandbox Code Playgroud)
将边界框矩形转换为 previewLayer 坐标,一切都按预期工作。但是当我尝试应用到 CVImageBuffer(大小不同)时,结果是错误的。
下面你可以看到我如何转换返回的边界框的坐标以及我如何裁剪 CVPixelBuffer
class ViewController: UIViewController {
var sequenceHandler = VNSequenceRequestHandler()
func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
// 1
guard let imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else { return }
// 2
let detectFaceRequest = VNDetectFaceLandmarksRequest(completionHandler: { [weak self] (request, error) in
guard error == nil else { return }
let cropedImage = self?.crop(request: request, imageBuffer: imageBuffer) // Croped buffer
})
// 3
do {
try sequenceHandler.perform(
[detectFaceRequest],
on: imageBuffer,
orientation: .leftMirrored)
} catch {
print(error.localizedDescription)
}
}
func crop(request: VNRequest, imageBuffer: CVImageBuffer) -> CVImageBuffer? {
guard let results = request.results as? [VNFaceObservation], let result = results.first else { return nil }
let width = CGFloat(CVPixelBufferGetWidth(imageBuffer)) // 1080
let height = CGFloat(CVPixelBufferGetHeight(imageBuffer)) // 1920
let cropRect = VNImageRectForNormalizedRect(result.boundingBox, Int(width), Int(height)) // Converting the boundingbox rect to the the image
CVPixelBufferLockBaseAddress(imageBuffer, .readOnly)
guard let baseAddress = CVPixelBufferGetBaseAddress(imageBuffer) else { return nil }
let bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer)
let bytesPerPixel = 4
let startAddress = baseAddress + Int(cropRect.origin.y) * bytesPerRow + Int(cropRect.origin.x) * bytesPerPixel
guard let context = CGContext(data: startAddress, width: Int(cropRect.size.width), height: Int(cropRect.size.height), bitsPerComponent: 8, bytesPerRow: bytesPerRow, space: CGColorSpaceCreateDeviceRGB(), bitmapInfo: CGImageAlphaInfo.noneSkipFirst.rawValue | CGBitmapInfo.byteOrder32Little.rawValue), let data = context.data else {
return nil
}
var pixelBuffer: CVPixelBuffer?
let createBufferResult = CVPixelBufferCreateWithBytes(kCFAllocatorDefault, Int(cropRect.size.width), Int(cropRect.size.height), kCVPixelFormatType_32BGRA, data, bytesPerRow, nil, nil, nil, &pixelBuffer)
guard createBufferResult != 0 else {
print(createBufferResult)
return nil
}
CVPixelBufferUnlockBaseAddress(imageBuffer, .readOnly)
return pixelBuffer
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
452 次 |
| 最近记录: |