前言

因为业务需要,要做这样一个转换。目前写了两种转换方法。

在iphonex真机上运行,一种方法需要24ms一帧,CPU占用率85%,另一种需要17ms一帧,CPU占用率140%。下面就来详细说说。

方法一

转换思路是CVPixelBufferRef->UIImage->cv::Mat的路线。

直接上方法:

先是CVPixelBufferRef->UIImage的方法

- (UIImage*)uiImageFromPixelBuffer:(CVPixelBufferRef)p {CIImage* ciImage = [CIImage imageWithCVPixelBuffer : p];CIContext* context = [CIContext contextWithOptions : @{kCIContextUseSoftwareRenderer : @(YES)}];CGRect rect = CGRectMake(0, 0, CVPixelBufferGetWidth(p), CVPixelBufferGetHeight(p));CGImageRef videoImage = [context createCGImage : ciImage fromRect : rect];UIImage* image = [UIImage imageWithCGImage : videoImage];CGImageRelease(videoImage);return image;
}

然后是UIImage->cv::Mat的方法

- (cv::Mat)cvMatFromUIImage:(UIImage *)image
{CGColorSpaceRef colorSpace = CGImageGetColorSpace(image.CGImage);CGFloat cols = image.size.width;CGFloat rows = image.size.height;cv::Mat cvMat(rows, cols, CV_8UC4); // 8 bits per component, 4 channels (color channels + alpha)CGContextRef contextRef = CGBitmapContextCreate(cvMat.data,                 // Pointer to  datacols,                       // Width of bitmaprows,                       // Height of bitmap8,                          // Bits per componentcvMat.step[0],              // Bytes per rowcolorSpace,                 // ColorspacekCGImageAlphaNoneSkipLast |kCGBitmapByteOrderDefault); // Bitmap info flagsCGContextDrawImage(contextRef, CGRectMake(0, 0, cols, rows), image.CGImage);CGContextRelease(contextRef);return cvMat;
}

这两个方法调用的时候需要加自动释放池,否则内存会爆掉。

这条转换路线就是速度慢但是CPU占用率不高的。

方法二

转换思路是CVPixelBufferRef->YUV cv::Mat->RGB cv::Mat

先上方法

- (cv::Mat)cvMatFromPixelBuffer:(CVPixelBufferRef)p
{CVPixelBufferLockBaseAddress(p, 0);unsigned char *base = (unsigned char *)CVPixelBufferGetBaseAddress(p);uint8_t *src_y = (unsigned char *)CVPixelBufferGetBaseAddressOfPlane(p, 0);uint8_t *src_uv =(unsigned char *) CVPixelBufferGetBaseAddressOfPlane(p, 1);int height = (int)CVPixelBufferGetHeight( p );int width = (int)CVPixelBufferGetWidth(p);cv::Mat yuvimg(height*3/2, width, CV_8UC1);for(int i=0; i<height*width; i++){*(yuvimg.data + i) = *(src_y + i);}int delta_h = height*3/2 - height;for(int i=0; i<delta_h; i++){for(int j=0; j<width; j++){*(yuvimg.data + (height + i)*width + j) = *(src_uv + i*width + j);}}//writeImage2Document("testim.jpg", yuvimg);cv::Mat rgbimg(height, width, CV_8UC4);cv::cvtColor(yuvimg, rgbimg, cv::COLOR_YUV2RGBA_NV21);//CVPixelBufferRef testimg = [self getImageBufferFromMat:rgbimg];CVPixelBufferUnlockBaseAddress( p, 0 );return rgbimg;
}

这种方法直接使用opencv来转换,速度会快一些, 但是CPU占用率高。

另外需要注意的是,YUV数据需要Y和UV分开写入到cv::Mat中,而不是直接获取CVPixelBufferGetBaseAddress的地址写入。我不知道为什么,直接取CVPixelBufferGetBaseAddress的地址的话,在起始地址会有一段乱码,然后导致整个画面右移。

收工~

超级好用的调试
前往应用市场

在IOS上YUV NV21格式的CVPixelBufferRef转opencv的RGB格式cv::Mat的方法相关推荐

  1. 在Python中使用OpenCV将RGB格式的图像转换为HSV格式的图像

    An HSV is another type of color space in which H stands for Hue, S stands for Saturation and V stand ...

  2. RAW格式 RAW RGB格式

    1.1  图像传感器 ( 通过一个一个的感光点对光进行采样和量化)           通常所说的130万像素等,指的是有130万个感光点.每一个感光点只能感光RGB中的一种颜色.但是,要还原一个真正 ...

  3. new Date()时间格式转时间戳在苹果机iOS上无效

    安卓和苹果的差异,今天又遇到一个,记下来方便以后查找. 后台传来的时间格式是'2020-09-16 11:11:11'.我想转化为时间戳就直接用 // time是后台传来的数据,时间格式是'2020- ...

  4. 什么是epub格式,IOS上有什么好用的epub阅读器

    有关于EPUB,大家可能都有所耳闻,但却不知道它到底是一种什么格式?又应用于哪些方面?有哪些支持软件?今天我就来给大家解释一下: 关于EPUB,维基百科上是这么解释的:EPUB(Electronic ...

  5. iOS系统上HEIC格式的图片如何转换成JPG格式的

    iOS系统上HEIC格式的图片如何转换成JPG格式的?想必很多人都有这个烦恼吧.那么怎么进行转换呢? iOS11和以后的系统为了更好地保护苹果用户的隐私,于是就将手机用户拍摄下来的图片,保存为IOS系 ...

  6. YUV与RGB格式详解

    YUV 是一种颜色编码方法,和它等同的还有 RGB 颜色编码方法. RGB 颜色编码 RGB 三个字母分别代表了 红(Red).绿(Green).蓝(Blue),这三种颜色称为 三原色,将它们以不同的 ...

  7. raw/rgb/yuv/nv21图像格式总结

    1.RAW raw格式sensor的输出格式,是sensor将光信号转换为电信号时的电平高低的原始记录,没有经过处理的原始数据 raw数据在输出的时候使用一定的顺序的,主要有四种: GRBG, RGG ...

  8. ios 系统提示框_经验分享:新购买移动硬盘格式化为Windows系统和Mac系统同时可以使用的方法...

    经常使用硬盘的小伙伴们都知道,新买的移动硬盘,要想在Windows系统使用的话是可以直接使用的,因为一般情况下新买的移动硬盘格式是适用于Windows系统的NTFS格式:如果想让该移动硬盘也能在苹果的 ...

  9. Pluto - iOS 上一个高性能的排版渲染引擎

    Pluto 是 iOS 上的一个排版渲染引擎,通过 JSON/JS 文件可以很方便地描述界面元素,开发效率很高,并且在流畅度,内存等方便有保证.pluto.oa.com 上有更多详细资料. Qzone ...

最新文章

  1. 求循环小数的表示以及循环节长度
  2. TOMCAT为什么打破双亲委派的类加载模型
  3. 关于GPS的1PPS时间同步功能探索与测试
  4. 语音识别(四)——DTW, Spectrogram, Cepstrum Analysis
  5. php 数组值sum,php sum数组值(如果特定列的值重复)
  6. ArcGIS斜坡单元工具箱
  7. CMD命令之BAT脚本语法详解
  8. Windows10 中在指定目录下启动Powershell
  9. 免费的Andr​​oid最好的视频播放器应用程序2012
  10. 【随机过程】第一章 随机过程概念与基本类型课后习题及答案
  11. 软考 软件设计师考试经验分享、题型分析
  12. 判断是否是IE浏览器或IE内核浏览器
  13. 将MP4视频和MP4音频合并成MP4文件
  14. 生命的火花盛开与如幻如梦
  15. 2019年安徽大学ACM/ICPC实验室新生赛
  16. 【源码学习】正则表达式
  17. RK3399 Android7.1 ACOVP导致系统死机
  18. windows 技术篇-共享地址里的共享文件显示为灰色叉叉不可用问题原因及解决方法
  19. mac改成类似微软键盘偏好设置
  20. 浅谈游戏数据分析------留存篇一---留存折损

热门文章

  1. 如何在UE5中重建哥特式建筑场景?
  2. ecmall mysql调用_ECMall系统请求跳转分析
  3. 最新计算机视觉学习路线教程
  4. R语言建立和可视化混合效应模型mixed effect model
  5. SpringCloud模块打包部署
  6. AR初体验:使用HP Reveal制作Aura进行presentation
  7. PBlaze5 920系列特性——可变Sector Size管理(上)
  8. 遥感理论基础——电磁波(一)
  9. VS2010/MFC对话框程序调用Windows Media Player播放器控件
  10. PCIe扫盲——PCIe错误报告机制