cv::Mat转AVFrame相互转换

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

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

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

下面是两种方法文章来源地址https://www.toymoban.com/news/detail-819664.html

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转换成AVFrame
    int 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转换成AVFrame
    CvMatToAVFrame(input_image,avFrame);


    // 将AVFrame转换成OpenCV cv::Mat
    cv::Mat out_avFrameToMat = AVFrameToCvMat(avFrame);

    cv::imshow("解码后", out_avFrameToMat);


    cv::waitKey(0);
    cv::destroyAllWindows();

    // free memory
    if (avFrame != nullptr)
    {
        av_frame_free(&avFrame);
        avFrame = nullptr;
    }

    return 0;
}

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

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

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

相关文章

  • 【人工智能】自然语言转换成 DSL的技术方案

    在本文中,我们将探讨将自然语言转换为领域特定语言(DSL)的三种可行技术方案。我们将分析这些技术方案的原理,以及提供一些代码实例。 基于规则的

    2024年02月08日
    浏览(65)
  • 【实践探索】人工智能语音转换技术的实践经验和优化建议

    [toc] 【实践探索】人工智能语音转换技术的实践经验和优化建议 随着人工智能技术的快速发展,语音识别技术作为其基础应用之一,也得到了越来越广泛的应用。针对目前市场上主流的人工智能语音识别技术,本文将深入探讨其原理、实现过程以及优化建议。本文将重点分析

    2024年02月06日
    浏览(74)
  • ffmpeg解码数据转换为cv::Mat

    ffmpeg解码数据转换为cv::Mat flyfish ffmpeg:ffmpeg-6.0 头文件 实现文件

    2024年02月12日
    浏览(42)
  • 【人工智能124种任务大集合】-集齐了自然语言处理(NLP),计算机视觉(CV),语音识别,多模态等任务

    大家好,我是微学AI,今天给大家介绍一下人工智能124种任务大集合,任务集合主要包括4大类:自然语言处理(NLP)、计算机视觉(CV)、语音识别、多模态任务。 我这里整理了124种应用场景任务大集合,每个任务目录如下: 句子嵌入(Sentence Embedding):将句子映射到固定维

    2024年02月13日
    浏览(76)
  • 【实用技巧】掌握人工智能语音转换的核心技术,轻松实现多语言语音转换和语音合成

    作者:禅与计算机程序设计艺术 【实用技巧】掌握人工智能语音转换的核心技术,轻松实现多语言语音转换和语音合成 1.1. 背景介绍 随着全球化的加速,跨文化交流需求日益增长,多语言语音转换和语音合成技术应运而生。人工智能技术的发展为语音合成和转换提供了便利

    2024年02月08日
    浏览(109)
  • deepart.io:基于人工智能的在线AI绘画风格转换工具

      【产品介绍】​ 名称​              deepart.io​ 具体描述​              deepart.io是一个基于人工智能的在线AI绘画平台,它可以让你用简单的几步,把你的照片转换成       不同风格的艺术作品。它利用了一种叫做神经风格迁移(neura

    2024年02月06日
    浏览(58)
  • 人工智能-OpenCV+Python实现人脸识别(人脸检测)

    在OpenCV中使用Haar特征检测人脸,那么需要使用OpenCV提供的xml文件(级联表)在haarcascades目录下。这张级联表有一个训练好的AdaBoost训练集。首先要采用样本的Haar特征训练分类器,从而得到一个级联的AdaBoost分类器。Haar特征值反映了图像的灰度变化情况。例如:脸部的一些特征

    2024年02月06日
    浏览(104)
  • 【最新应用】人工智能语音转换技术的最新应用案例和未来发展方向

    作者:禅与计算机程序设计艺术 引言 1.1. 背景介绍 随着人工智能技术的快速发展,语音识别技术作为其基础技术之一,已经在各个领域得到了广泛应用。为了提高语音识别的效率和准确性,人工智能语音转换技术逐渐崭露头角。本文将介绍人工智能语音转换技术的最新应用

    2024年02月07日
    浏览(69)
  • OpenCV buffer转cv::Mat

    void convertBuf2Mat(void* input_ptr, vx_uint32 width, vx_uint32 height, cv::Mat frame) {     // 计算亮度通道和色度通道的大小     size_t y_size = width * height;     size_t uv_size = y_size / 2;     // 创建一个只包含亮度通道的 cv::Mat 对象     cv::Mat y_channel(height, width, CV_8UC1, (unsigned char*)input_ptr);     // 设

    2024年02月07日
    浏览(32)
  • opencv学习(9):cv::Scalar、cv::Mat::zeros

            cv::Scalar是opencv的一个结构体,其定义如下:(c++中的结构体如下,可以存放1~4个数值。)         表示图像颜色时,单通道图像用下标[0]即可,三通道图像用下标[0]、[1]、[2]分别表示B、G、R通道         其中:                 白色:rgb(255,255,255)  

    2024年02月08日
    浏览(54)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包