vImage на Mac: невозможно преобразовать из Core Video
Редактировать: Исправлено. Рабочий образец находится по адресу https://github.com/halmueller/vImage-mac-sample.
Я пытаюсь прочитать поток с камеры MacBook Pro Facetime, чтобы обработать ее с помощью инфраструктуры vImage. Я следую примеру в Apple VideoCaptureSample, который написан для iOS.
Я зациклен на создании vImageConverter, который создает буфер изображения, который может использовать vImage. Мой звонок vImageConverter_CreateForCVToCGImageFormat()
завершается с ошибкой консоли "недостаточно информации в srcCVFormat для декодирования изображения. vImageCVImageFormatError = -21601".
Тот же звонок работает на iOS. Но форматы изображений разные на iOS и macOS. В iOS конструктор vImageConverter может выводить информацию о формате, а в macOS - нет.
Вот мой установочный код:
func displayEqualizedPixelBuffer(pixelBuffer: CVPixelBuffer) {
var error = kvImageNoError
if converter == nil {
let cvImageFormat = vImageCVImageFormat_CreateWithCVPixelBuffer(pixelBuffer).takeRetainedValue()
let deviceRGBSpace = CGColorSpaceCreateDeviceRGB()
let dcip3SolorSpace = CGColorSpace(name: CGColorSpace.dcip3)
vImageCVImageFormat_SetColorSpace(cvImageFormat,
deviceRGBSpace)
print(cvImageFormat)
if let unmanagedConverter = vImageConverter_CreateForCVToCGImageFormat(
cvImageFormat,
&cgImageFormat,
nil,
vImage_Flags(kvImagePrintDiagnosticsToConsole),
&error) {
guard error == kvImageNoError else {
return
}
converter = unmanagedConverter.takeRetainedValue()
} else {
return
}
}
Когда я запускаю на iOS, я вижу в консоли:
vImageCVFormatRef 0x101e12210:
type: '420f'
matrix:
0.29899999499321 0.58700001239777 0.11400000005960
-0.16873589158058 -0.33126410841942 0.50000000000000
0.50000000000000 -0.41868758201599 -0.08131241053343
chroma location: <RGB Base colorspace missing>
RGB base colorspace: =Bo
На macOS, однако, вызов vImageConverter_CreateForCVToCGImageFormat
возвращает ноль, и я вижу:
vImageCVFormatRef 0x10133a270:
type: '2vuy'
matrix:
0.29899999499321 0.58700001239777 0.11400000005960
-0.16873589158058 -0.33126410841942 0.50000000000000
0.50000000000000 -0.41868758201599 -0.08131241053343
chroma location: <RGB Base colorspace missing>
RGB base colorspace: Ð ü
2018-03-13... kvImagePrintDiagnosticsToConsole: vImageConverter_CreateForCVToCGImageFormat error:
insufficient information in srcCVFormat to decode image. vImageCVImageFormatError = -21601
Обратите внимание, что тип изображения (4-буквенный код) отличается, как и базовое цветовое пространство RGB. Я пробовал на Mac использовать dcip3ColorSpace вместо deviceRGB, и результаты те же.
Чего мне не хватает, чтобы создать этот vImageConverter?
1 ответ
-21601
Код ошибки означает, что в исходном формате CV отсутствует информация о расположении цветов (см. http://dougkerr.net/Pumpkin/articles/Subsampling.pdf чтобы узнать об истории размещения цветов). Вы можете исправить это, явно установив vImageCVImageFormat_SetChromaSiting
, Итак, сразу после установки цветового пространства формата и до создания конвертера (т.е. где у вас есть print(cvImageFormat)
), добавьте следующее:
vImageCVImageFormat_SetChromaSiting(cvImageFormat,
kCVImageBufferChromaLocation_Center)
Ура!
Саймон
Таким образом, хотя ответ о вызове установки свойства chorma в формате vImage работает, есть лучший способ сделать это. Просто установите свойство в основном пиксельном буфере видео, а затем, когда вы вызовете vImageCVImageFormat_CreateWithCVPixelBuffer(), оно будет просто работать так:
NSDictionary *pbAttachments = @{
(__bridge NSString*)kCVImageBufferChromaLocationTopFieldKey:(__bridge NSString*)kCVImageBufferChromaLocation_Center,
(__bridge NSString*)kCVImageBufferAlphaChannelIsOpaque: (id)kCFBooleanTrue,
};
CVBufferRef pixelBuffer = cvPixelBuffer;
CVBufferSetAttachments(pixelBuffer, (__bridge CFDictionaryRef)pbAttachments, kCVAttachmentMode_ShouldPropagate);
Для дополнительных точек вы также можете установить цветовое пространство ref с помощью kCVImageBufferICCProfileKey и CGColorSpaceCopyICCData() API.