使用OpenCV将图像转换为NV12格式并加载NV12数据

这篇具有很好参考价值的文章主要介绍了使用OpenCV将图像转换为NV12格式并加载NV12数据。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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

用处

新项目需要开放接口给上层应用使用,而相机直接输出的是YUV数据。为了减少上层应用对OpenCV的依赖,需要在函数内部将YUV数据转化为cv::Mat格式。这样,上层应用就无需调用OpenCV的任何操作。测试接口需要使用YUV数据,因此我们还需要保存图像数据为YUV格式,并加载YUV数据进行进一步处理。

步骤

步骤1:加载图片,转换成YUV并保存成NV12数据

void convert2NV12(const std::string& imagePath, const std::string& outputFilePath)
{
    cv::Mat mat = cv::imread(imagePath);
    int cropWidth = mat.cols/2*2;
    int cropHeight = mat.rows/2*2;

    cv::Mat cropImage = mat(cv::Rect(0 , 0, cropWidth, cropHeight));

    std::ofstream ofs;
    ofs.open(outputFilePath, std::ios::binary);

    // 创建一个YUV图像来存储转换后的数据
    cv::Mat yuvImage(cropImage.rows *3/2, cropImage.cols, CV_8UC1, cv::Scalar(0)); // Y分量
    cv::Mat uvImage(cropImage.rows *3/ 2, cropImage.cols, CV_8UC1, cv::Scalar(0)); // UV分量 (NV12)

    // 进行BGR到YUV颜色空间转换
    cv::cvtColor(cropImage, yuvImage, cv::COLOR_BGR2YUV_I420);

    memcpy(uvImage.data, yuvImage.data, cropImage.cols*cropImage.rows);

    int yLen  = cropImage.cols * cropImage.rows;
    int uvLen = cropImage.cols*cropImage.rows/4;
    // 将UV分量(U和V)从I420格式提取并排列为NV12格式
    for (int el = 0; el < uvLen; el++) {
        uvImage.data[yLen + 2*el] = yuvImage.data[yLen + el];
        uvImage.data[yLen + 2*el + 1] = yuvImage.data[yLen + el + uvLen];
    } 

    if(ofs.is_open()){
        // 写入YUV数据到文件
        ofs.write(reinterpret_cast<char*>(uvImage.data), uvImage.total() * uvImage.elemSize());
        // ofs.write(reinterpret_cast<char*>(uvImage.data), cropImage.cols*cropImage.rows*3/2);
        ofs.flush();
        ofs.close();
    }
}

在这个步骤中,我们加载一张图片,将其转换为NV12格式,并保存为NV12文件。convertToNV12 函数接受图片文件路径和输出NV12文件路径两个参数。

步骤2:加载NV12数据并转化成BGR数据显示
cv::Mat loadNV12(const std::string& filePath, int width, int height) {
    std::ifstream file(filePath, std::ios::binary | std::ios::ate);
    
    if (!file.is_open()) {
        std::cerr << "Error: Unable to open NV12 file " << filePath << std::endl;
        return cv::Mat();
    }

    std::streamsize size = file.tellg();
    file.seekg(0, std::ios::beg);

    std::vector<char> buffer(size);
    if (!file.read(buffer.data(), size)) {
        std::cerr << "Error: Unable to read NV12 data from file " << filePath << std::endl;
        return cv::Mat();
    }

    cv::Mat nv12Mat(height + height / 2, width, CV_8UC1, buffer.data());

    return nv12Mat.clone();  // Clone to ensure data ownership
}

这个函数负责加载NV12数据并将其转化为cv::Mat格式。接受NV12文件路径、图像宽度和高度三个参数,并返回cv::Mat格式的NV12数据。

步骤3:主函数
int main() {
    int width = 640;
    int height = 480;
    convertToNV12("input_image.jpg", "output_image.nv12");
    cv::Mat nv12Image = loadNV12("output_image.nv12", width, height);

    if (!nv12Image.empty()) {
        // 此时nv12Image包含了NV12格式的数据,你可以对其进行进一步处理
        cv::imshow("NV12 Image", nv12Image);
        cv::waitKey(0);
    }

    return 0;
}

主函数演示了如何调用前述两个函数,将图像转换为NV12格式并加载NV12数据进行显示。你可以根据实际需求进一步处理nv12Image

通过这些步骤,你可以轻松地在新项目中处理YUV数据并与OpenCV集成,同时提供简便的接口给上层应用使用。文章来源地址https://www.toymoban.com/news/detail-806467.html

到了这里,关于使用OpenCV将图像转换为NV12格式并加载NV12数据的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • Android JNI和原生交互,常见的图像格式转换 : NV21、RGBA、Bitmap等

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

    2024年02月06日
    浏览(33)
  • yuv数据(nv12和nv21)和RGB数据之间转换的c++代码

    nv21 Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y V U V U V U V U nv21 Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y Y U V U V U V U V 主要就是UV的顺序不同,交互一下UV的位置就可以互换NV12和NV21. 一般手机等移动端的数据流格式都是yuv格式,而神经网络的输入一般都是rgb格式,所以需要进行转换,这里给出c++的代码示例。 cv

    2024年02月11日
    浏览(31)
  • 如何将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日
    浏览(27)
  • 在IOS上YUV NV21格式的CVPixelBufferRef转opencv的RGB格式cv::Mat的方法

    因为业务需要,要做这样一个转换。目前写了两种转换方法。 在iphonex真机上运行,一种方法需要24ms一帧,CPU占用率85%,另一种需要17ms一帧,CPU占用率140%。下面就来详细说说。 转换思路是CVPixelBufferRef-UIImage-cv::Mat的路线。 直接上方法: 先是CVPixelBufferRef-UIImage的方法 然后是

    2024年02月12日
    浏览(28)
  • C++中OpenCV、Armadillo矩阵数据格式的转换方式

      本文介绍在 C++ 语言中,矩阵库 Armadillo 的 mat 、 vec 格式数据与计算机视觉库 OpenCV 的 Mat 格式数据相互转换的方法。   在 C++ 语言的矩阵库 Armadillo 与计算机视觉库 OpenCV 中,都有 矩阵 格式的数据类型;而这两个库在运行能力方面各有千秋,因此实际应用过程中,难免

    2024年03月09日
    浏览(32)
  • C++ 使用opencv加载并显示RGB图像和深度图像

    rgb图像是一般的彩色图像格式,深度图像是存储在xml文件中,c++读取代码如下: 当然,需要安装并配置opencv,配置opencv细节可参考其他博客 效果如下: 若opencv加载深度数据集失败,就请参考这篇博客,这是作者在加载深度数据时失败所写解决方法:https://mp.csdn.net/mp_blog/cr

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

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

    2024年02月03日
    浏览(39)
  • Baumer工业相机堡盟工业相机如何联合BGAPI SDK和OpenCV实现Mono12和Mono16格式位深度的图像保存(C++)

    ​ 持之以恒挑战赛 Baumer工业相机堡盟相机是一种高性能、高质量的工业相机,可用于各种应用场景,如物体检测、计数和识别、运动分析和图像处理。 Baumer的万兆网相机拥有出色的图像处理性能,可以实时传输高分辨率图像。此外,该相机还具有快速数据传输、低功耗、易

    2023年04月19日
    浏览(32)
  • iTOP-3568开发板使用OpenCV处理图像-颜色转换

    本小节代码在配套资料“iTOP-3568 开发板\\03_【iTOP-RK3568 开发板】指南教程 \\04_OpenCV 开发配套资料\\05”目录下,如下图所示: cv2.cvtColor()函数功能: 将一幅图像从一个色彩空间转换到另一个色彩空间。 函数原型: cv2.cvtColor(src,code,dst=None,dstCn=None) 参数定义: src:要转换的源文件

    2024年02月12日
    浏览(27)
  • 在 Python 中使用 OpenCV 通过透视校正转换图像

    在计算机视觉和图像处理领域,透视变换是一个强大的工具。它允许我们改变图像的视角以获得新的视点,通常用于校正扭曲或模拟不同的相机角度。本文将探讨一个 Python 脚本,该脚本使用计算机视觉领域流行的 OpenCV 库对图像执行透视变换。我们将详细介绍该脚本的工作原

    2024年01月25日
    浏览(34)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包