Apple的新CoreML框架具有预测功能,需要一个CVPixelBuffer
.为了分类,UIImage
必须在两者之间进行转换.
我从Apple工程师处获得的转换代码:
1 // image has been defined earlier
2
3 var pixelbuffer: CVPixelBuffer? = nil
4
5 CVPixelBufferCreate(kCFAllocatorDefault, Int(image.size.width), Int(image.size.height), kCVPixelFormatType_OneComponent8, nil, &pixelbuffer)
6 CVPixelBufferLockBaseAddress(pixelbuffer!, CVPixelBufferLockFlags(rawValue:0))
7
8 let colorspace = CGColorSpaceCreateDeviceGray()
9 let bitmapContext = CGContext(data: CVPixelBufferGetBaseAddress(pixelbuffer!), width: Int(image.size.width), height: Int(image.size.height), bitsPerComponent: 8, bytesPerRow: CVPixelBufferGetBytesPerRow(pixelbuffer!), space: colorspace, bitmapInfo: 0)!
10
11 bitmapContext.draw(image.cgImage!, in: CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height))
Run Code Online (Sandbox Code Playgroud)
这个解决方案很快,适用于灰度图像.必须根据图像类型进行的更改包括:
kCVPixelFormatType_OneComponent8
到另一个OSType
(kCVPixelFormatType_32ARGB
对于RGB)colorSpace
到另一个CGColorSpace
( …如何从CVPixelBufferRef获取RGB(或任何其他格式)像素值?我尝试了很多方法,但还没有成功.
func captureOutput(captureOutput: AVCaptureOutput!,
didOutputSampleBuffer sampleBuffer: CMSampleBuffer!,
fromConnection connection: AVCaptureConnection!) {
let pixelBuffer: CVPixelBufferRef = CMSampleBufferGetImageBuffer(sampleBuffer)!
CVPixelBufferLockBaseAddress(pixelBuffer, 0)
let baseAddress = CVPixelBufferGetBaseAddress(pixelBuffer)
//Get individual pixel values here
CVPixelBufferUnlockBaseAddress(pixelBuffer, 0)
}
Run Code Online (Sandbox Code Playgroud) 我正试图CVPixelBuffer
从Apple的ARKit 获得RGB色彩空间.在我获取实例的func session(_ session: ARSession, didUpdate frame: ARFrame)
方法ARSessionDelegate
中ARFrame
.在页面上显示使用金属的AR体验我发现此像素缓冲区位于YCbCr(YUV)颜色空间中.
我需要将其转换为RGB色彩空间(我实际需要CVPixelBuffer
而不是UIImage
).我在iOS上找到了一些关于颜色转换的东西,但我无法在Swift 3中使用它.
我正在为我的某个应用构建视频导出功能.从本质上讲,视频是一系列六种不同图像中的一种,持续时间不同(短).
当我导出包含283个不同持续时间图像的东西时,导出工作正常,但是当我尝试导出803中的一个时,我得到了可怕的"操作无法完成"错误(AKA"我们不知道是什么爆炸因为AVFoundation错误报告很糟糕").
当我尝试使用my AVAssetWriterInputPixelBufferAdaptor
,return appendPixelBuffer:withPresentationTime:
返回第754帧(总是第754帧)时NO
,AVAssetWriter
状态失败,错误是这样的:
Error Domain=AVFoundationErrorDomain Code=-11800 "The operation could not be completed" UserInfo={NSLocalizedDescription=The operation could not be completed, NSUnderlyingError=0x17ab2050 {Error Domain=NSOSStatusErrorDomain Code=-16364 "(null)"}, NSLocalizedFailureReason=An unknown error occurred (-16364)}
Run Code Online (Sandbox Code Playgroud)
我不能为我的生活找出底层错误(OSStatus
-16364)是什么.www.osstatus.com不知道,macerror
说没有这样的东西,这个用于搜索SDK标题的Python脚本什么也没发现.它也不是像一些OSStatus错误那样的四字符代码(除非我搞砸了这个).
我已经排除了我发现的"操作无法完成"错误的每个常见原因.它与文件系统权限或覆盖无关,没有两个调用appendPixelBuffer
具有相同的显示时间.
它不是内存(视频导出期间内存使用率保持在165MB),CPU保持在3%左右.
如果它具有任何重要性,我会对CVPixelBuffer
6个图像反复重复使用相同的6 秒,而不是UIImage
每次都从s 创建新的图像.这似乎有助于性能,并且每次都将其更改为新的并不会改变任何东西(除了让它在第753帧上失败),但谁知道.
有谁知道这可能是什么?
我提供了pixelbuffer,我需要从lf.swift库附加到rtmpStream对象以将其流式传输到youtube.它看起来像这样:rtmpStream.appendSampleBuffer(sampleBuffer: CMSampleBuffer, withType: CMSampleBufferType)
所以,我需要以某种方式将CVPixelbuffer转换为CMSampleBuffer以附加到rtmpStream.
var sampleBuffer: CMSampleBuffer? = nil
var sampleTimingInfo: CMSampleTimingInfo = kCMTimingInfoInvalid
sampleTimingInfo.presentationTimeStamp = presentationTime
var formatDesc: CMVideoFormatDescription? = nil
_ = CMVideoFormatDescriptionCreateForImageBuffer(kCFAllocatorDefault, pixelBuffer, &formatDesc)
if let formatDesc = formatDesc {
CMSampleBufferCreateReadyWithImageBuffer(kCFAllocatorDefault, pixelBuffer, formatDesc, &sampleTimingInfo, &sampleBuffer)
}
if let sampleBuffer = sampleBuffer {
self.rtmpStream.appendSampleBuffer(sampleBuffer, withType: CMSampleBufferType.video)
}
Run Code Online (Sandbox Code Playgroud)
但是,不幸的是,这不起作用.流媒体库经过测试,在我流式摄像机输入或screenCapture时工作正常.我认为问题可能是sampleTimingInfo,因为它需要decodeTime和Duration,我不知道如何获得提供的CVPixelBuffer.
我正在我的应用程序中的一个函数将我的示例缓冲区中的图像写入AVAssetWriter.奇怪的是,这在10.5英寸iPad Pro上运行良好,但在7.9英寸iPad Mini 2上造成了崩溃.我无法理解相同的代码在两个不同的设备上是如何出问题的.但这是我的代码;
func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
// Setup the pixel buffer image
let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)!
// Setup the format description
let formatDescription = CMSampleBufferGetFormatDescription(sampleBuffer)!
// Setup the current video dimensions
self.currentVideoDimensions = CMVideoFormatDescriptionGetDimensions(formatDescription)
// Setup the current sample time
self.currentSampleTime = CMSampleBufferGetOutputPresentationTimeStamp(sampleBuffer)
// Handle record
if self.isCapturing {
// Setup auto release pool
autoreleasepool {
// Setup the output image
let outputImage = CIImage(cvPixelBuffer: pixelBuffer)
// …
Run Code Online (Sandbox Code Playgroud) 我需要创建 a 的副本,CVPixelBufferRef
以便能够使用副本中的值以按位方式操作原始像素缓冲区。我似乎无法通过CVPixelBufferCreate
, 或CVPixelBufferCreateWithBytes
.
根据这个问题,它也可以用 memcpy() 来完成。但是,没有解释如何实现这一点,并且无论如何都需要调用哪些核心视频库。
我正在使用AVCaptureSession
&AVCapturePhotoOutput
以格式从设备的相机捕获RAW照片数据kCVPixelFormatType_14Bayer_RGGB
.
我已经获得了AVCapturePhotoCaptureDelegate
回调中的原始照片样本缓冲区:
func capture(captureOutput: AVCapturePhotoOutput,
didFinishProcessingRawPhotoSampleBuffer rawSampleBuffer: CMSampleBuffer?,
previewPhotoSampleBuffer: CMSampleBuffer?,
resolvedSettings: AVCaptureResolvedPhotoSettings,
bracketSettings: AVCaptureBracketedStillImageSettings?,
error: Error?) {
guard let rawSampleBuffer = rawSampleBuffer else { return }
guard let pixelBuffer = CMSampleBufferGetImageBuffer(rawSampleBuffer) else { return }
}
Run Code Online (Sandbox Code Playgroud)
我现在正试图按照这个问题的答案来获取像素值,CVPixelBufferRef
但是当使用14位拜耳RGGB像素格式而不是答案中提到的32位RGB格式时,我无法弄清楚如何做到这一点.
我有一个 IOSurface 支持的 CVPixelBuffer,它正在以 30fps 的速度从外部源更新。我想在 NSView 中渲染图像数据的预览——对我来说最好的方法是什么?
我可以直接在视图上设置 CALayer 的 .contents ,但这只会在我的视图第一次更新时更新(或者,如果我调整了视图的大小)。我一直在研究文档,但我无法弄清楚在图层或视图上正确调用 NeedDisplay 以让视图基础结构知道自己刷新,尤其是当更新来自视图外部时。
理想情况下,我只是将 IOSurface 绑定到我的图层,我对它所做的任何更改都会被传播,但我不确定这是否可能。
class VideoPreviewController: NSViewController, VideoFeedConsumer {
let customLayer : CALayer = CALayer()
override func viewDidLoad() {
super.viewDidLoad()
// Do view setup here.
print("Loaded our video preview")
view.layer?.addSublayer(customLayer)
customLayer.frame = view.frame
// register our view with the browser service
VideoFeedBrowser.instance.registerConsumer(self)
}
override func viewWillDisappear() {
// deregister our view from the video feed
VideoFeedBrowser.instance.deregisterConsumer(self)
super.viewWillDisappear()
}
// This callback gets called at 30fps whenever …
Run Code Online (Sandbox Code Playgroud) 我有一个使用 ScreenCaptureKit 的项目。由于超出问题范围的各种原因,我配置 ScreenCaptureKit 使用的格式是kCVPixelFormatType_32BGRA
——我需要原始 BGRA 数据,稍后会对其进行操作。
当我从数据构造一个CGImage
或时,显示和一些窗口看起来很好(完整的代码包含在问题的底部 - 这只是转换的摘录)。NSImage
guard let cvPixelBuffer = sampleBuffer.imageBuffer else { return }
CVPixelBufferLockBaseAddress(cvPixelBuffer, .readOnly)
defer { CVPixelBufferUnlockBaseAddress(cvPixelBuffer, .readOnly) }
let vImageBuffer: vImage_Buffer = vImage_Buffer(data: CVPixelBufferGetBaseAddress(cvPixelBuffer),
height: vImagePixelCount(CVPixelBufferGetHeight(cvPixelBuffer)),
width: vImagePixelCount(CVPixelBufferGetWidth(cvPixelBuffer)),
rowBytes: CVPixelBufferGetWidth(cvPixelBuffer) * 4)
let cgImageFormat: vImage_CGImageFormat = vImage_CGImageFormat(
bitsPerComponent: 8,
bitsPerPixel: 32,
colorSpace: CGColorSpaceCreateDeviceRGB(),
bitmapInfo: CGBitmapInfo(rawValue: CGImageAlphaInfo.last.rawValue),
renderingIntent: .defaultIntent
)!
if let cgImage: CGImage = try? vImageBuffer.createCGImage(format: cgImageFormat) {
let nsImage = NSImage(cgImage: cgImage, …
Run Code Online (Sandbox Code Playgroud) cvpixelbuffer ×10
swift ×7
ios ×6
avfoundation ×2
arkit ×1
calayer ×1
cgimage ×1
coreml ×1
metal ×1
nsview ×1
objective-c ×1
osstatus ×1
uiimage ×1