- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我想保留来自摄像机的流式视频的 YUV420 格式以避免转换为灰度时的损失,但我也想保留颜色分量。最终目标是使用像 OpenCV 这样的计算机视觉库进行处理。虽然我最终可能会选择 BGRA,但我仍然希望能够使用 YUV 测试一个可行的解决方案。那么如何将像素格式为 kCVPixelFormatType_420YpCbCr8BiPlanarFullRange
的 CVImageBuffer 转换为单个内存块?
被拒绝的解决方案:
最佳答案
这将根据指定的像素格式将数据填充到包含字节的 NSObject 中。我继续为 BGRA 或 YUV 像素格式提供检测和 malloc 内存的能力。所以这个解决方案非常适合测试这两者。
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection
{
CVImageBufferRef videoImageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
CVPixelBufferLockBaseAddress(videoImageBuffer, 0);
void *baseAddress = NULL;
NSUInteger totalBytes = 0;
size_t width = CVPixelBufferGetWidth(videoImageBuffer);
size_t height = 0;
size_t bytesPerRow = CVPixelBufferGetBytesPerRow(videoImageBuffer);
OSType pixelFormat = CVPixelBufferGetPixelFormatType(videoImageBuffer);
if (pixelFormat == kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange ||
pixelFormat == kCVPixelFormatType_420YpCbCr8BiPlanarFullRange) {
size_t planeCount = CVPixelBufferGetPlaneCount(videoImageBuffer);
baseAddress = CVPixelBufferGetBaseAddressOfPlane(videoImageBuffer, 0);
for (int plane = 0; plane < planeCount; plane++) {
size_t planeHeight = CVPixelBufferGetHeightOfPlane(videoImageBuffer, plane);
size_t bytesPerRow = CVPixelBufferGetBytesPerRowOfPlane(videoImageBuffer, plane);
height += planeHeight;
totalBytes += (int)planeHeight * (int)bytesPerRow;
}
} else if (pixelFormat == kCVPixelFormatType_32BGRA) {
baseAddress = CVPixelBufferGetBaseAddress(videoImageBuffer);
height = CVPixelBufferGetHeight(videoImageBuffer);
size_t bytesPerRow = CVPixelBufferGetBytesPerRow(videoImageBuffer);
totalBytes += (int)height * (int)bytesPerRow;
}
// Doesn't have to be an NSData object
NSData *rawPixelData = [NSData dataWithBytes:baseAddress length:totalBytes];
// Just a plain-ol-NSObject with the following properties
NTNUVideoFrame *videoFrame = [[NTNUVideoFrame alloc] init];
videoFrame.width = width;
videoFrame.height = height;
videoFrame.bytesPerRow = bytesPerRow;
videoFrame.pixelFormat = pixelFormat;
// Alternatively if you switch rawPixelData to void *
// videoFrame.rawPixelData = baseAddress;
videoFrame.rawPixelData = rawPixelData;
[self.delegate didUpdateVideoFrame:videoFrame];
CVPixelBufferUnlockBaseAddress(videoImageBuffer, 0);
}
你唯一需要记住的是,如果你计划切换线程,你将需要 malloc
和 memcpy
基地址,或者 dispatch_async 而你不这样做使用 NSData
。解锁基地址后,像素数据将不再有效。
void *rawPixelData = malloc(totalBytes);
memcpy(rawPixelData, baseAddress, totalBytes);
此时您需要考虑在完成后对该内存块调用 free 的问题。
关于ios - 将 CVImageBuffer 转换为 YUV420 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27889825/
我在 Swift 中有这段代码并收到错误:CVImageBuffer 不可转换为 Unmanaged func getTextureFromSampleBuffer(sampleBuffer: C
我知道可以在 session 配置期间设置镜像,但假设这对于这个特定项目来说不可行,那么当 CVImageBuffer 时它仍然可以有效地完成吗?已经获得了吗? // To set mirroring
我正在尝试使用 cocoa 从网络摄像头抓取图像。我可以使用 QTKit 和 didOutputVideoFrame 委托(delegate)调用获取 RGBA 格式的图像,并将 CVImageBuf
我有一个任务 - 缩小我从相机获得的图像。我需要它来对较小版本的图像执行繁重的操作,这将帮助我节省一些处理能力。 我决定使用 Accelerate 的 vImage_Buffer。这是我的代码,只有很
我正在从我的 AVCaptureSession 中获取一个 CVImageBufferRef,我想获取该图像缓冲区并通过网络上传它。为了节省空间和时间,我想在不将图像渲染成 CIImage 和 NSB
我遇到了一些与使用 iOS9 SDK 裁剪相关的问题。 我有以下代码来调整图像大小(通过在中间裁剪从 4:3 转换为 16:9)。这在 iOS8 SDK 之前都可以正常工作。在 iOS 9 中,底部区
如果你从 apple 查看这个文档 https://developer.apple.com/library/tvos/documentation/QuartzCore/Reference/CVBuff
CVImageBuffer 之间有什么区别?由 CMSampleBufferGetmageBuffer 和 CVPixelBuffer 返回?我只想检索图像平面 (RGBA),但我不知道如何从 CVI
我正在使用框架 (MoodMe) 来检测 iPhone 相机上的人脸,我需要将图像或帧传递给 MoodMe 实例。 我已将相机输出转换为 UIImage,但框架未检测到任何人脸。 (我觉得) 所以我想
我有临时变量 tmpPixelBuffer 和像素缓冲区数据,它不是 nil,当检测到元数据对象时,我想从该缓冲区创建图像,所以我可以从该图像裁剪元数据图像。 图像总是nil,我做错了什么? func
关于我的前两个问题,我花了一周的时间试图弄清楚如何针对核心视频缓冲区运行多个着色器。我知道我需要做什么,但坦率地说,我无法让代码工作(下面粘贴的是原始的非乒乓版本)。 缺少“ Eureka ”时刻,我
我想保留来自摄像机的流式视频的 YUV420 格式以避免转换为灰度时的损失,但我也想保留颜色分量。最终目标是使用像 OpenCV 这样的计算机视觉库进行处理。虽然我最终可能会选择 BGRA,但我仍然希
我正在使用 CVMetalTextureCacheCreateTextureFromImage 从 CVImageBuffer(来自相机和播放器)创建一个 MTLTexture 以获得 CVMetal
我已经设法设置了一个基本的 AVCaptureSession,它使用 AVCaptureFileOutputRecordingDelegate 录制视频并将其保存在设备上。我一直在搜索文档以了解我们如
在高层次上,我创建了一个应用程序,让用户可以将他或她的 iPhone 摄像头指向四周,并查看经过视觉效果处理的视频帧。此外,用户可以点击一个按钮将当前预览的定格画面作为高分辨率照片保存在他们的 iPh
我在 iPhone 上使用 OpenCV 2.2 检测人脸。我正在使用 IOS 4 的 AVCaptureSession 来访问相机流,如以下代码所示。 我的挑战是视频帧以 CVBufferRef(指
我是一名优秀的程序员,十分优秀!