Как создать данные глубины и добавить их к изображению?
Извините, я продублировал этот вопрос. Как собрать AVDepthData вручную, потому что у него нет ответов, которые я хочу, и у меня недостаточно представителей, чтобы комментировать там. Если вы не возражаете, я мог бы удалить свой вопрос в будущем и попросить кого-нибудь переместить будущие ответы на эту тему.
Итак, моя цель - создать данные глубины и прикрепить их к произвольному изображению. Есть статья о том, как это сделать, https://developer.apple.com/documentation/avfoundation/avdepthdata/creating_auxiliary_depth_data_manually, но я не знаю, как реализовать какой-либо шаг в этом направлении. Я не буду публиковать все вопросы сразу и начну с первого.
В качестве первого шага изображение глубины должно быть преобразовано на пиксель из градаций серого в значения глубины или диспаратности. Я взял этот фрагмент из вышеупомянутой темы:
func buildDepth(image: UIImage) -> AVDepthData? {
let width = Int(image.size.width)
let height = Int(image.size.height)
var maybeDepthMapPixelBuffer: CVPixelBuffer?
let status = CVPixelBufferCreate(kCFAllocatorDefault, width, height, kCVPixelFormatType_DisparityFloat32, nil, &maybeDepthMapPixelBuffer)
guard status == kCVReturnSuccess, let depthMapPixelBuffer = maybeDepthMapPixelBuffer else {
return nil
}
CVPixelBufferLockBaseAddress(depthMapPixelBuffer, .init(rawValue: 0))
guard let baseAddress = CVPixelBufferGetBaseAddress(depthMapPixelBuffer) else {
return nil
}
let buffer = unsafeBitCast(baseAddress, to: UnsafeMutablePointer<Float32>.self)
for i in 0..<width * height {
buffer[i] = 0 // disparity must be calculated somehow, but set to 0 for testing purposes
}
CVPixelBufferUnlockBaseAddress(depthMapPixelBuffer, .init(rawValue: 0))
let info: [AnyHashable: Any] = [kCGImagePropertyPixelFormat: kCVPixelFormatType_DisparityFloat32,
kCGImagePropertyWidth: image.size.width,
kCGImagePropertyHeight: image.size.height,
kCGImagePropertyBytesPerRow: CVPixelBufferGetBytesPerRow(depthMapPixelBuffer)]
let metadata = generateMetadata(image: image)
let dic: [AnyHashable: Any] = [kCGImageAuxiliaryDataInfoDataDescription: info,
// I get an error when converting baseAddress to CFData
kCGImageAuxiliaryDataInfoData: baseAddress as! CFData,
kCGImageAuxiliaryDataInfoMetadata: metadata]
guard let depthData = try? AVDepthData(fromDictionaryRepresentation: dic) else {
return nil
}
return depthData
}
Затем в статье говорится, чтобы загрузить базовый адрес буфера пикселей (в котором находится карта диспаратности) в виде CFData и передать его как kCGImageAuxiliaryDataInfoData
значение в CFDictionary. Но я получаю сообщение об ошибке при преобразовании baseAddress в CFData. Я тоже пытался конвертировать пиксельный буфер, но без удачи. Что я должен передать как kCGImageAuxiledDataInfoData? Правильно ли я создал буфер несоответствия?
Помимо этой проблемы было бы здорово, если бы кто-то мог направить меня к некоторому образцу кода о том, как сделать все это.
1 ответ
Ваш вопрос действительно помог мне перейти от cvPixelBuffer к AVDepthData, так что спасибо. Это было около 95% пути туда.
Чтобы исправить вашу (и мою) проблему, я добавил следующее:
let bytesPerRow = CVPixelBufferGetBytesPerRow(depthMapPixelBuffer)
let size = bytesPerRow * height;
... code code code ...
CVPixelBufferLockBaseAddress(depthMapPixelBuffer!, .init(rawValue: 0))
let baseAddress = CVPixelBufferGetBaseAddressOfPlane(depthMapPixelBuffer!, 0)
let data = NSData(bytes: baseAddress, length: size);
... code code code ...
let dic: [AnyHashable: Any] = [kCGImageAuxiliaryDataInfoDataDescription: info,
kCGImageAuxiliaryDataInfoData: data,
kCGImageAuxiliaryDataInfoMetadata: metadata]