使用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

相关文章

Linux中压缩、网络传输与系统监控工具的使用完整指南

《Linux中压缩、网络传输与系统监控工具的使用完整指南》在Linux系统管理中,压缩与传输工具是数据备份和远程协作的桥梁,而系统监控工具则是保障服务器稳定运行的眼睛,下面小编就来和大家详细介绍一下它... 目录引言一、压缩与解压:数据存储与传输的优化核心1. zip/unzip:通用压缩格式的便捷操作2.

关于集合与数组转换实现方法

《关于集合与数组转换实现方法》:本文主要介绍关于集合与数组转换实现方法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、Arrays.asList()1.1、方法作用1.2、内部实现1.3、修改元素的影响1.4、注意事项2、list.toArray()2.1、方

使用Python实现可恢复式多线程下载器

《使用Python实现可恢复式多线程下载器》在数字时代,大文件下载已成为日常操作,本文将手把手教你用Python打造专业级下载器,实现断点续传,多线程加速,速度限制等功能,感兴趣的小伙伴可以了解下... 目录一、智能续传:从崩溃边缘抢救进度二、多线程加速:榨干网络带宽三、速度控制:做网络的好邻居四、终端交互

Python中注释使用方法举例详解

《Python中注释使用方法举例详解》在Python编程语言中注释是必不可少的一部分,它有助于提高代码的可读性和维护性,:本文主要介绍Python中注释使用方法的相关资料,需要的朋友可以参考下... 目录一、前言二、什么是注释?示例:三、单行注释语法:以 China编程# 开头,后面的内容为注释内容示例:示例:四

Go语言数据库编程GORM 的基本使用详解

《Go语言数据库编程GORM的基本使用详解》GORM是Go语言流行的ORM框架,封装database/sql,支持自动迁移、关联、事务等,提供CRUD、条件查询、钩子函数、日志等功能,简化数据库操作... 目录一、安装与初始化1. 安装 GORM 及数据库驱动2. 建立数据库连接二、定义模型结构体三、自动迁

MyBatisPlus如何优化千万级数据的CRUD

《MyBatisPlus如何优化千万级数据的CRUD》最近负责的一个项目,数据库表量级破千万,每次执行CRUD都像走钢丝,稍有不慎就引起数据库报警,本文就结合这个项目的实战经验,聊聊MyBatisPl... 目录背景一、MyBATis Plus 简介二、千万级数据的挑战三、优化 CRUD 的关键策略1. 查

python实现对数据公钥加密与私钥解密

《python实现对数据公钥加密与私钥解密》这篇文章主要为大家详细介绍了如何使用python实现对数据公钥加密与私钥解密,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录公钥私钥的生成使用公钥加密使用私钥解密公钥私钥的生成这一部分,使用python生成公钥与私钥,然后保存在两个文

mysql中的数据目录用法及说明

《mysql中的数据目录用法及说明》:本文主要介绍mysql中的数据目录用法及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、背景2、版本3、数据目录4、总结1、背景安装mysql之后,在安装目录下会有一个data目录,我们创建的数据库、创建的表、插入的

ModelMapper基本使用和常见场景示例详解

《ModelMapper基本使用和常见场景示例详解》ModelMapper是Java对象映射库,支持自动映射、自定义规则、集合转换及高级配置(如匹配策略、转换器),可集成SpringBoot,减少样板... 目录1. 添加依赖2. 基本用法示例:简单对象映射3. 自定义映射规则4. 集合映射5. 高级配置匹

Spring 框架之Springfox使用详解

《Spring框架之Springfox使用详解》Springfox是Spring框架的API文档工具,集成Swagger规范,自动生成文档并支持多语言/版本,模块化设计便于扩展,但存在版本兼容性、性... 目录核心功能工作原理模块化设计使用示例注意事项优缺点优点缺点总结适用场景建议总结Springfox 是