西安免费建网站设计,合肥网版制作,做金融网站,天堂2免费服务器最近在使用ffmpeg取鱼眼相机的视频流做全景播放时遇到需要cv::Mat转AVFrame的转换#xff0c;看到了这篇文章#xff0c;记录一下
1.OpenCV cv::Mat转换为FFmpeg AVFrame
下面是两种方法
void CvMatToAVFrame(const cv::Mat input_mat, AVFrame* out_avframe)
{int i…最近在使用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.hppextern 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.hppvoid 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;
}