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

2023-11-21 17:04

本文主要是介绍使用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集成,同时提供简便的接口给上层应用使用。

这篇关于使用OpenCV将图像转换为NV12格式并加载NV12数据的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/403767

相关文章

详解如何通过Python批量转换图片为PDF

《详解如何通过Python批量转换图片为PDF》:本文主要介绍如何基于Python+Tkinter开发的图片批量转PDF工具,可以支持批量添加图片,拖拽等操作,感兴趣的小伙伴可以参考一下... 目录1. 概述2. 功能亮点2.1 主要功能2.2 界面设计3. 使用指南3.1 运行环境3.2 使用步骤4. 核

使用Python自建轻量级的HTTP调试工具

《使用Python自建轻量级的HTTP调试工具》这篇文章主要为大家详细介绍了如何使用Python自建一个轻量级的HTTP调试工具,文中的示例代码讲解详细,感兴趣的小伙伴可以参考一下... 目录一、为什么需要自建工具二、核心功能设计三、技术选型四、分步实现五、进阶优化技巧六、使用示例七、性能对比八、扩展方向建

使用Python实现一键隐藏屏幕并锁定输入

《使用Python实现一键隐藏屏幕并锁定输入》本文主要介绍了使用Python编写一个一键隐藏屏幕并锁定输入的黑科技程序,能够在指定热键触发后立即遮挡屏幕,并禁止一切键盘鼠标输入,这样就再也不用担心自己... 目录1. 概述2. 功能亮点3.代码实现4.使用方法5. 展示效果6. 代码优化与拓展7. 总结1.

使用Python开发一个简单的本地图片服务器

《使用Python开发一个简单的本地图片服务器》本文介绍了如何结合wxPython构建的图形用户界面GUI和Python内建的Web服务器功能,在本地网络中搭建一个私人的,即开即用的网页相册,文中的示... 目录项目目标核心技术栈代码深度解析完整代码工作流程主要功能与优势潜在改进与思考运行结果总结你是否曾经

Linux中的计划任务(crontab)使用方式

《Linux中的计划任务(crontab)使用方式》:本文主要介绍Linux中的计划任务(crontab)使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、前言1、linux的起源与发展2、什么是计划任务(crontab)二、crontab基础1、cro

kotlin中const 和val的区别及使用场景分析

《kotlin中const和val的区别及使用场景分析》在Kotlin中,const和val都是用来声明常量的,但它们的使用场景和功能有所不同,下面给大家介绍kotlin中const和val的区别,... 目录kotlin中const 和val的区别1. val:2. const:二 代码示例1 Java

C++变换迭代器使用方法小结

《C++变换迭代器使用方法小结》本文主要介绍了C++变换迭代器使用方法小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录1、源码2、代码解析代码解析:transform_iterator1. transform_iterat

C++中std::distance使用方法示例

《C++中std::distance使用方法示例》std::distance是C++标准库中的一个函数,用于计算两个迭代器之间的距离,本文主要介绍了C++中std::distance使用方法示例,具... 目录语法使用方式解释示例输出:其他说明:总结std::distance&n编程bsp;是 C++ 标准

Python将博客内容html导出为Markdown格式

《Python将博客内容html导出为Markdown格式》Python将博客内容html导出为Markdown格式,通过博客url地址抓取文章,分析并提取出文章标题和内容,将内容构建成html,再转... 目录一、为什么要搞?二、准备如何搞?三、说搞咱就搞!抓取文章提取内容构建html转存markdown

Python获取中国节假日数据记录入JSON文件

《Python获取中国节假日数据记录入JSON文件》项目系统内置的日历应用为了提升用户体验,特别设置了在调休日期显示“休”的UI图标功能,那么问题是这些调休数据从哪里来呢?我尝试一种更为智能的方法:P... 目录节假日数据获取存入jsON文件节假日数据读取封装完整代码项目系统内置的日历应用为了提升用户体验,