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

这篇具有很好参考价值的文章主要介绍了在IOS上YUV NV21格式的CVPixelBufferRef转opencv的RGB格式cv::Mat的方法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

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

在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  data
                                                 cols,                       // Width of bitmap
                                                 rows,                       // Height of bitmap
                                                 8,                          // Bits per component
                                                 cvMat.step[0],              // Bytes per row
                                                 colorSpace,                 // Colorspace
                                                 kCGImageAlphaNoneSkipLast |
                                                 kCGBitmapByteOrderDefault); // Bitmap info flags
  CGContextDrawImage(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的地址的话,在起始地址会有一段乱码,然后导致整个画面右移。

收工~文章来源地址https://www.toymoban.com/news/detail-655248.html

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

到了这里,关于在IOS上YUV NV21格式的CVPixelBufferRef转opencv的RGB格式cv::Mat的方法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • c++ java rgb与nv21互转

    目录 jni函数 c++ rgb转nv21,可以转,不报错,但是转完只有黑白图 java yuv420保存图片,先转nv21,再保存ok: c++ yuv420月bgr互转,测试ok

    2024年02月11日
    浏览(41)
  • 【Unity-Shader脚本】0基础学会通过用Unity-Shader脚本渲染图像数据(NV21,NV12,RGBA数据)详细教程--附demo,NV21测试图像,YUV图像查看器。

      最近有一个需求是需要我在Unity中将获取到的图像数据来展示在Unity的界面之中。功能其实很简单,熟悉Unity-Shader的小伙伴可能很快就可以做出来。然而我很少和图像的渲染打交道,基本上是0基础了,在做这个需求之前连Shader是什么都不知道。本文记录了自己做这个需求

    2024年02月03日
    浏览(58)
  • 【音视频原理】图像相关概念 ⑥ ( YUV 与 RGB 之间的转换 | YUV444 颜色编码格式 转为 RGB 格式 | RGB 颜色编码格式 转为 YUV444 格式 )

    YUV 与 RGB 颜色格式之间进行转换时 , 涉及一系列的数学运算 ; YUV 颜色编码格式 转为 RGB 格式 的 转换公式 取决于 于 YUV 的具体子采样格式 : YUV444 YUV422 YUV420 YUV444 格式 转为 RGB 格式 的 转换公式如下 : R = Y + 1.13983 * (V - 128) G = Y - 0.39465 * (U - 128) - 0.58060 * (V - 128) B = Y + 2.03211 * (U

    2024年01月24日
    浏览(63)
  • RAW、RGB、YUV 图像格式区别

    颜色是人的视觉系统对光谱中可见区域的感知效果,它仅存在于人的眼睛和大脑中。为了准确地描述颜色,必须引入色彩空间的概念。正如几何上用坐标空间来描述坐标集合,色彩空间用数学方式来描述颜色集合。 RAW 图像就是图像感应器将捕捉到的光源信号转化为数字信号

    2024年02月04日
    浏览(43)
  • OpenCV中的RGB与YUV转换

            YUV 颜色空间从模拟电视时代开始就被广泛应用于彩色图像的转换与处理。其基于一个 3x3 的矩阵,通过线性变换将 RGB 像素转换为一个亮度(Luma)分量 Y 以及两个色度(Chroma)分量 U 和 V。由于模拟电视存在着多种制式,如 NTSC 与 PAL 等等,考虑到具体硬件与技术上的

    2024年02月14日
    浏览(35)
  • Android和JNI交互 : 常见的图像格式转换 : NV21、RGBA、Bitmap等

    最近在使用 OpenCV 处理图片的时候,经常会遇到需要转换图像的情况,网上相关资料比较少,也不全,有时候得费劲老半天才能搞定。 自己踩了坑后,在这里记录下,都是我在项目中遇到的图像转化操作,是一些常用的图像格式转换操作。 具体包括: nv21、rgba、rgb 转换 OpenC

    2024年02月05日
    浏览(46)
  • Android JNI和原生交互,常见的图像格式转换 : NV21、RGBA、Bitmap等

    最近在使用 OpenCV 处理图片的时候,经常会遇到需要转换图像的情况,网上相关资料比较少,也不全,有时候得费劲老半天才能搞定。 自己踩了坑后,在这里记录下,都是我在项目中遇到的图像转化操作,是一些常用的图像格式转换操作。 具体包括: nv21、rgba、rgb 转换 OpenC

    2024年02月06日
    浏览(46)
  • 如何将yuv420p图像数据转换为RGB数据并使用opencv保存为jpg图片

    yuv420是用4个byte存储4个Y的信息,用1个Byte存储U的信息,一个Byte存储V的信息, 这4个Y共用这2个U和V ,也就是用6个Byte 存储4个像素信息,也就是一个像素需要12个Bits(6*8/4),也就是12bpp。 注意yuv420p里面的p是指planar,也就是分层存储,先存全部Y的信息,然后是U的信息,最后

    2024年02月16日
    浏览(39)
  • 使用OpenCV将图像转换为NV12格式并加载NV12数据

    摘要:在新项目中,需要为上层应用开放几个接口,但又不想让上层应用过多依赖OpenCV。本文将详细介绍如何使用C++和OpenCV,通过加载图片并转换为NV12格式,实现对图像数据的处理,以及如何加载NV12数据并显示。这些步骤对于在相机等设备中处理YUV数据并与OpenCV进行无缝集

    2024年01月19日
    浏览(87)
  • 一文看懂图像格式 RAW、RGB、YUV、Packed/Unpacked、Bayer、MIPI、Planar、Semi-Planar、Interleaved

    目录 一、通用属性 1. Packed/Unpacked 2. 压缩/非压缩 二、RAW 1. Bayer格式 2. 分类 3. MIPI RAW 三、RGB 分类 四、YUV 1. YUV与RGB转换 2. 分类 3. 内存计算 五、压缩格式 有的人,错过了,一生再也找寻不到。 本文详细分析各种图像格式(RAW、RGB、YUV)的分类、内存分布。一篇文章让你看懂

    2024年02月06日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包