Я хочу иметь возможность хранить данные глубины захваченного кадра ARframe в iOS в файле со сжатием без потерь.
Согласно этому докладу WWDC:
«В iOS 11 мы поддерживаем два типа изображений с глубиной. Первый - это HEIF HEVC, новый формат, также называемый файлами HEIC, и там первоклассная поддержка глубины ... Второй поддерживаемый нами формат - это JPEG. Боже, JPEG не предназначался для подобных трюков, но мы все равно сделали этот трюк. Карта представляет собой 8-битный JPEG с потерями, если он отфильтрован, или если в нем нет чисел, мы используем 16-битный JPEG без потерь. Кодирование JPEG, чтобы сохранить все не числа, и мы храним его как второе изображение внизу JPEG, так что это похоже на объект с несколькими изображениями, если вы знакомы с этим ».
Когда я сравниваю исходный буфер глубины (16-битный) с буфером глубины, который я извлекаю из сохраненного изображения по пикселям, я получаю следующие результаты:
First Second
0.61865234 0.6196289
0.62109375 0.6196289
0.6269531 0.6274414
0.6298828 0.63134766
0.6328125 0.63134766
nan 0.003921509
nan 0.0
nan 0.0
nan 0.007843018
nan 0.003921509
Даже когда у меня есть нефильтрованные данные глубины с NAN в них, сохраненные данные не могут их сохранить, и при этом они не используют кодирование без потерь, как кажется.
Это код, который я написал:
if let currentFrame = session.currentFrame, let depthData = currentFrame.capturedDepthData { // The session variable is an ARSession object
let outputURL: URL? = filePath(forKey: "test")
guard let cgImageDestination = CGImageDestinationCreateWithURL(outputURL! as CFURL, kUTTypeJPEG, 1, nil) else {
return
}
depthData.depthDataMap.normalize() // Normalizing depth data between 0.0 and 1.0
let sixteenBitDepthData = depthData.converting(toDepthDataType: kCVPixelFormatType_DepthFloat16)
let ciImage = CIImage(cvPixelBuffer: currentFrame.capturedImage)
let context = CIContext(options: nil)
let dict: NSDictionary = [
kCGImageDestinationLossyCompressionQuality: 1.0,
kCGImagePropertyIsFloat: kCFBooleanTrue,
]
if let cgImage: CGImage = context.createCGImage(ciImage, from: ciImage.extent) {
CGImageDestinationAddImage(cgImageDestination, cgImage, nil)
}
var auxDataType: NSString?
let auxData = sixteenBitDepthData.dictionaryRepresentation(forAuxiliaryDataType: &auxDataType)
CGImageDestinationAddAuxiliaryDataInfo(cgImageDestination, auxDataType!, auxData! as CFDictionary)
CGImageDestinationFinalize(cgImageDestination)
if let second = getDepthBufferFromFile(key: "test") {
self.compareBuffers(first: sixteenBitDepthData.depthDataMap, second: second)
}
}