Mac 上的 vImage:无法从 Core Video 转换
vImage on the Mac: unable to convert from Core Video
编辑: 已修复。工作示例位于 https://github.com/halmueller/vImage-mac-sample.
我正在尝试读取 MacBook Pro 的 Facetime 摄像头的提要,以使用 vImage 框架对其进行处理。我正在按照 Apple VideoCaptureSample 中的示例进行操作,该示例是为 iOS 编写的。
我对创建 vImageConverter 挂断了,它创建了一个 vImage 可以使用的图像缓冲区。我对 vImageConverter_CreateForCVToCGImageFormat()
的调用失败,控制台错误 "insufficient information in srcCVFormat to decode image. 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
returns 的调用为零,我看到:
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 我缺少什么?
-21601
错误代码表示源 CV 格式缺少色度定位信息(有关色度定位的漂亮背景,请参阅 http://dougkerr.net/Pumpkin/articles/Subsampling.pdf)。您可以通过使用 vImageCVImageFormat_SetChromaSiting
显式设置来解决此问题。因此,在设置格式的颜色 space 之后,在创建转换器之前(即你有 print(cvImageFormat)
的地方),立即添加以下内容:
vImageCVImageFormat_SetChromaSiting(cvImageFormat,
kCVImageBufferChromaLocation_Center)
干杯!
西蒙
因此,虽然关于在 vImage 格式上调用设置 chorma 属性 的答案确实有效,但有更好的方法可以做到这一点。只需在核心视频像素缓冲区上设置 属性,然后当您调用 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);
为了加分,您还可以使用 kCVImageBufferICCProfileKey 和 CGColorSpaceCopyICCData() 设置颜色空间参考 API。
编辑: 已修复。工作示例位于 https://github.com/halmueller/vImage-mac-sample.
我正在尝试读取 MacBook Pro 的 Facetime 摄像头的提要,以使用 vImage 框架对其进行处理。我正在按照 Apple VideoCaptureSample 中的示例进行操作,该示例是为 iOS 编写的。
我对创建 vImageConverter 挂断了,它创建了一个 vImage 可以使用的图像缓冲区。我对 vImageConverter_CreateForCVToCGImageFormat()
的调用失败,控制台错误 "insufficient information in srcCVFormat to decode image. 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
returns 的调用为零,我看到:
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 我缺少什么?
-21601
错误代码表示源 CV 格式缺少色度定位信息(有关色度定位的漂亮背景,请参阅 http://dougkerr.net/Pumpkin/articles/Subsampling.pdf)。您可以通过使用 vImageCVImageFormat_SetChromaSiting
显式设置来解决此问题。因此,在设置格式的颜色 space 之后,在创建转换器之前(即你有 print(cvImageFormat)
的地方),立即添加以下内容:
vImageCVImageFormat_SetChromaSiting(cvImageFormat,
kCVImageBufferChromaLocation_Center)
干杯!
西蒙
因此,虽然关于在 vImage 格式上调用设置 chorma 属性 的答案确实有效,但有更好的方法可以做到这一点。只需在核心视频像素缓冲区上设置 属性,然后当您调用 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);
为了加分,您还可以使用 kCVImageBufferICCProfileKey 和 CGColorSpaceCopyICCData() 设置颜色空间参考 API。