cv::Mat转AVFrame相互转换

最近在使用ffmpeg取鱼眼相机的视频流做全景播放时遇到需要cv::Mat转AVFrame的转换,看到了这篇文章,记录一下

1.OpenCV cv::Mat转换为FFmpeg AVFrame

下面是两种方法

void CvMatToAVFrame(const cv::Mat& input_mat, AVFrame* out_avframe)
{int image_width = input_mat.cols;int image_height = input_mat.rows;int cvLinesizes[1];cvLinesizes[0] = input_mat.step1();SwsContext* openCVBGRToAVFrameSwsContext = sws_getContext(image_width,image_height,AVPixelFormat::AV_PIX_FMT_BGR24,image_width,image_height,AVPixelFormat::AV_PIX_FMT_YUV420P,SWS_FAST_BILINEAR,nullptr, nullptr, nullptr);sws_scale(openCVBGRToAVFrameSwsContext,&input_mat.data,cvLinesizes,0,image_height,out_avframe->data,out_avframe->linesize);if (openCVBGRToAVFrameSwsContext != nullptr){sws_freeContext(openCVBGRToAVFrameSwsContext);openCVBGRToAVFrameSwsContext = nullptr;}
}
#include <opencv2/opencv.hpp>extern "C" {
#include <libavcodec/avcodec.h>
#include <libavutil/frame.h>
#include <libavutil/imgutils.h>
}void convertMatToAVPicture(const cv::Mat& mat, AVFrame* frame)
{int width = mat.cols;int height = mat.rows;int channels = mat.channels();int ret;frame->width = width;frame->height = height;frame->format = AV_PIX_FMT_BGR24;enum AVPixelFormat pix_fmt = AV_PIX_FMT_BGR24;// 为AVFrame分配内存ret = av_image_alloc(frame->data, frame->linesize, width, height, pix_fmt , 32);if (ret < 0){return;}// 将opencv的Mat转换成AVFrameint step = width * channels;for (int row = 0; row < height; row++) {memcpy(frame->data[0] + row * frame->linesize[0], mat.data + row * step, step);}
}

2.FFmpeg AVFrame转换为OpenCV cv::Mat

cv::Mat AVFrameToCvMat(AVFrame* input_avframe)
{int image_width = input_avframe->width;int image_height = input_avframe->height;cv::Mat resMat(image_height, image_width, CV_8UC3);int cvLinesizes[1];cvLinesizes[0] = resMat.step1();SwsContext* avFrameToOpenCVBGRSwsContext = sws_getContext(image_width,image_height,AVPixelFormat::AV_PIX_FMT_YUV420P,image_width,image_height,AVPixelFormat::AV_PIX_FMT_BGR24,SWS_FAST_BILINEAR,nullptr, nullptr, nullptr);sws_scale(avFrameToOpenCVBGRSwsContext,input_avframe->data,input_avframe->linesize,0,image_height,&resMat.data,cvLinesizes);if (avFrameToOpenCVBGRSwsContext != nullptr){sws_freeContext(avFrameToOpenCVBGRSwsContext);avFrameToOpenCVBGRSwsContext = nullptr;}return resMat;
}

3.使用示例

#include <iostream>// ffmpeg
extern "C" {
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libavutil/avutil.h"
#include "libswscale/swscale.h"
#include <libavutil/imgutils.h>
}// opencv
#include "opencv/cv.h"
#include "opencv2/opencv.hpp"void CvMatToAVFrame(const cv::Mat& input_mat, AVFrame* out_avframe)
{int image_width = input_mat.cols;int image_height = input_mat.rows;int cvLinesizes[1];cvLinesizes[0] = input_mat.step1();SwsContext* openCVBGRToAVFrameSwsContext = sws_getContext(image_width,image_height,AVPixelFormat::AV_PIX_FMT_BGR24,image_width,image_height,AVPixelFormat::AV_PIX_FMT_YUV420P,SWS_FAST_BILINEAR,nullptr, nullptr, nullptr);sws_scale(openCVBGRToAVFrameSwsContext,&input_mat.data,cvLinesizes,0,image_height,out_avframe->data,out_avframe->linesize);if (openCVBGRToAVFrameSwsContext != nullptr){sws_freeContext(openCVBGRToAVFrameSwsContext);openCVBGRToAVFrameSwsContext = nullptr;}
}cv::Mat AVFrameToCvMat(AVFrame* input_avframe)
{int image_width = input_avframe->width;int image_height = input_avframe->height;cv::Mat resMat(image_height, image_width, CV_8UC3);int cvLinesizes[1];cvLinesizes[0] = resMat.step1();SwsContext* avFrameToOpenCVBGRSwsContext = sws_getContext(image_width,image_height,AVPixelFormat::AV_PIX_FMT_YUV420P,image_width,image_height,AVPixelFormat::AV_PIX_FMT_BGR24,SWS_FAST_BILINEAR,nullptr, nullptr, nullptr);sws_scale(avFrameToOpenCVBGRSwsContext,input_avframe->data,input_avframe->linesize,0,image_height,&resMat.data,cvLinesizes);if (avFrameToOpenCVBGRSwsContext != nullptr){sws_freeContext(avFrameToOpenCVBGRSwsContext);avFrameToOpenCVBGRSwsContext = nullptr;}return resMat;
}int main()
{cv::Mat input_image = cv::imread("C:/Users/Administrator/Desktop/example.jpg");AVFrame* avFrame = av_frame_alloc();avFrame->format = AVPixelFormat::AV_PIX_FMT_YUV420P;avFrame->width = input_image.cols;avFrame->height = input_image.rows;// 为需要创建的YUV Frame分配内存if (av_frame_get_buffer(avFrame, 0) < 0){av_frame_free(&avFrame);avFrame = nullptr;return -1;}cv::imshow("解码前", input_image);// OpenCV cv::Mat转换成AVFrameCvMatToAVFrame(input_image,avFrame);// 将AVFrame转换成OpenCV cv::Matcv::Mat out_avFrameToMat = AVFrameToCvMat(avFrame);cv::imshow("解码后", out_avFrameToMat);cv::waitKey(0);cv::destroyAllWindows();// free memoryif (avFrame != nullptr){av_frame_free(&avFrame);avFrame = nullptr;}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/612590.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

windows10 装docker和docker compose

一.windows环境准备 开启过程中的问题&#xff0c;进入bios修复 二.docker下载安装 1.下载 Docker Desktop: The #1 Containerization Tool for Developers | Docker 下载最新版有问题&#xff0c;下载老版本试试 Docker Desktop release notes | Docker Docs 2.安装 三.do…

系统存储架构升级分享

一、业务背景 系统业务功能&#xff1a;系统内部进行数据处理及整合, 对外部系统提供结果数据的初始化(写)及查询数据结果服务。 系统网络架构: • 部署架构对切量上线的影响 - 内部管理系统上线对其他系统的读业务无影响 •分布式缓存可进行单独扩容, 与存储及查询功能升级…

出版实务 | 出版物的成本及其构成

文章目录 出版物成本的总体构成直接成本开发成本制作成本 间接成本期间费用 本量利分析原则特点和作用变动成本项目固定成本项目本量利分析的基本公式及其应用定价发行折扣率销售数量单位销售收入销售收入总额单位销售税金销售税金总额变动成本总额单位变动成本固定成本总额单位…

CMake入门教程【高级篇】CPack打包项目Linux的deb和windows的msi

😈「CSDN主页」:传送门 😈「Bilibil首页」:传送门 😈「动动你的小手」:点赞👍收藏⭐️评论📝 文章目录 1. 什么是CPack?2. 如何使用CPack?2.1 在CMakeLists.txt中包含CPack模块2.2 设置CPack变量2.3 创建分发包3.CPack命

转专业(UPC练习)

题目描述 根据教育部的规定&#xff0c;大学生进校后符合条件的可申请转专业。在校本科生在完成大学一年级课程&#xff0c;进入二年级之前&#xff0c;符合以下条件之一者&#xff0c;可以申请转专业&#xff1a;&#xff08;1&#xff09;在某一学科方面确有特长的学生&#…

谁将掌控工业界的命脉?揭秘工业互联网巨头的秘密角逐!

大数据产业创新服务媒体 ——聚焦数据 改变商业 在这个快速发展的数字化时代&#xff0c;一个新兴的巨兽——工业互联网&#xff0c;正以惊人的速度崛起&#xff0c;它不仅预示着生产力的飞跃性进步&#xff0c;更是引领着整个工业世界走向一个前所未有的新时代。 然而&#x…

微信小程序中路由跳转的方式有哪些?区别?

面试官&#xff1a;说说微信小程序中路由跳转的方式有哪些&#xff1f;区别&#xff1f; 一、是什么 微信小程序拥有web网页和Application共同的特征&#xff0c;我们的页面都不是孤立存在的&#xff0c;而是通过和其他页面进行交互&#xff0c;来共同完成系统的功能 在微信小…

【FPGA/verilog -入门学习17】vivado 实现串口自发自收程序

1&#xff0c;需求 PC使用串口助手给FPGA板发送9600 波特率的数据&#xff0c;FPGA板接收到数据后&#xff0c;回复同样的数据给PC 2&#xff0c;需求分析 按模块可以划分为&#xff1a; rx接收模块&#xff0c;将输入的8位并行rx 数据转换成[7:0]rx_data 信号&#xff0c;当…

C++面试宝典第18题:旋转数组

题目 给定一个数组,将数组中的元素向右移动k个位置,其中k是非负数。要求如下: (1)尽可能想出更多的解决方案,至少有三种不同的方法可以解决这个问题。 (2)使用时间复杂度为O(n)和空间复杂度为O(1)的原地算法解决这个问题。 示例 1: 输入: [1, 2, 3, 4, 5, 6, 7] 和 k…

NR中如何判断是否需要measurement gap来做邻区的测量?

先看下NR中定义的测量。 intra-freq 测量和inter-freq测量可以分为以下几类&#xff1a; 1 SSB based intra-freq 测量&#xff1a;serving cell SSB的center freq与邻区 SSB的center freq 相同并且两个SSB 的SCS也相同。 2 SSB based inter-freq 测量&#xff1a;serving ce…

vue3中ref和reactive联系与区别以及如何选择

vue3中ref和reactive区别与联系 区别 1、ref既可定义基本数据类型&#xff0c;也可以定义引用数据类型&#xff0c;reactive只能定义应用数据类型 2、ref在js中取响应值需要使用 .value&#xff0c;而reactive则直接取用既可 3、ref定义的对象通过.value重新分配新对象时依旧…

ROS中私有节点句柄(Private Node Handle)和非私有节点句柄(Global Node Handle)辨析

文章目录 私有节点句柄&#xff08;Private Node Handle&#xff09;例子 非私有节点句柄&#xff08;Global Node Handle&#xff09;例子 总结节点补充内容 在ROS&#xff08;Robot Operating System&#xff09;中&#xff0c;节点句柄&#xff08;ros::NodeHandle&#xff…

自学Python,需要注意哪些?

为什么要学习Python&#xff1f; 在学习Python之前&#xff0c;你不要担心自己没基础或“脑子笨”&#xff0c;我始终认为&#xff0c;只要你想学并为之努力&#xff0c;就能学好&#xff0c;就能用Python去做很多事情。在这个喧嚣的时代&#xff0c;很多技术或概念会不断兴起…

php 函数声明与调用

在 PHP 中&#xff0c;函数声明和调用的语法如下&#xff1a; 函数声明的一般形式为&#xff1a; function functionName($param1, $param2, ...) {// 函数体return $result; // 可选 } 例如&#xff1a; function add($a, $b) {return $a $b; } 函数调用的一般形式为&am…

vue模板判断-不要再傻傻写if()了

在vue开发中&#xff0c;有时会遇到需要在模板里写 v-if"userType AGENCY || userType PLACE || userType MANAGEMENT"但是这样写可能不太美观 这时可以改为用计算属性加include或者some computed: {isAgencyUser() {const { userType } this// return [AGENCY, P…

2. 条件构造器

构造器结构及作用&#xff1a; Wrapper&#xff1a;条件构造器抽象类&#xff0c;最顶端的父类 AbstractWrapper&#xff1a;查询条件封装抽象类&#xff0c;生成 SQL 的 where 条件 QueryWrapper&#xff1a;用于对象封装UpdateWrapper&#xff1a;用于条件封装 AbstractLamb…

hive sql 和 spark sql的区别

Hive SQL 和 Spark SQL 都是用于在大数据环境中处理结构化数据的工具&#xff0c;但它们有一些关键的区别&#xff1a; 底层计算引擎&#xff1a; Hive SQL&#xff1a;Hive 是建立在 Hadoop 生态系统之上的&#xff0c;使用 MapReduce 作为底层计算引擎。因此&#xff0c;它的…

Elasticsearch 地理空间搜索 - 远超 OpenSearch

作者&#xff1a;来自 Elastic Nathan_Reese 2021 年&#xff0c;OpenSearch 和 OpenSearch Dashboards 开始作为 Elasticsearch 和 Kibana 的分支。 尽管 OpenSearch 和 OpenSearch Dashboards 具有相似的血统&#xff0c;但它们不提供相同的功能。 在分叉时&#xff0c;只能克…

第二十章 调用Callout Library函数 - 使用 $ZF(-6) 按用户索引访问库

文章目录 第二十章 调用Callout Library函数 - 使用 $ZF(-6) 按用户索引访问库使用 $ZF(-6) 按用户索引访问库使用 $ZF(-4,5) 定义系统索引条目使用 $ZF(-6) 调用函数 第二十章 调用Callout Library函数 - 使用 $ZF(-6) 按用户索引访问库 使用 $ZF(-6) 按用户索引访问库 $ZF(…

纯化蛋白质树脂ES-4060_用于吸附蛋白质树脂

蛋白纯化树脂是一种固定在基质中的化学物质&#xff0c;具有选择性地与目标蛋白结合&#xff0c;并通过洗脱将其从混合物中分离出来。蛋白纯化树脂的工作原理主要分为三个步骤:吸附、洗脱和再生。 吸附 蛋白纯化树脂通过与目标蛋白之间的特定相互作用来吸附目标蛋白。这些相互…