OpenCV -- ffmpeg 视频输入输出VideoCapture和VideoWriter的使用
opencv依赖了ffmpeg,所以可以轻松对avi视频文件进行操作。
打开视频文件或摄像头视频需要使用Opencv中的VideoCapture类,保存视频或摄像头视频到本地磁盘,需要使用Opencv中的VideoWriter类。
代码:
bool isInit= false; VideoCapture *inputVideo=NULL; VideoWriter *outputVideo=NULL; JNIEXPORT void JNICALL Java_org_opencv_samples_tutorial2_Tutorial2Activity_FindFeatures(JNIEnv *, jobject, jlong addrGray, jlong addrRgba) { Mat &mGr = *(Mat *) addrGray; Mat &mRgb = *(Mat *) addrRgba; vector<KeyPoint> v; looperAddNum++; if (looperAddNum > 15) { looperAddNum = 0; if (looperIndexNum < 100) looperIndexNum += 1; } // code start----------------------------------------------------------------------------- if (!isInit){ LOGI("index start"); const string source = "/data/data/org.opencv.samples.tutorial2/cache/Megamind.avi"; // the source file name inputVideo=new VideoCapture(source.c_str()); if (!inputVideo->isOpened()){ LOGI("open video error"); return; } Mat lsFrame; *inputVideo>> lsFrame; if (lsFrame.empty()) return; string::size_type pAt = source.find_last_of('.'); // Find extension point const string NAME = source.substr(0, pAt) + "R" + ".avi"; // Form the new name with container LOGI("index looper %d %d", lsFrame.cols, lsFrame.rows); outputVideo=new VideoWriter(); outputVideo->open(NAME, VideoWriter::fourcc('M', 'J', 'P', 'G'), 25, Size(lsFrame.cols, lsFrame.rows), true); if (!outputVideo->isOpened()) { LOGI("index open video error %s", NAME.c_str()); return; } isInit= true; } if (isInit){ Mat videoFrame; *inputVideo >> videoFrame; if (videoFrame.empty()) return; // show video Mat dstW = mRgb(Rect(0,0, videoFrame.cols, videoFrame.rows)); cvtColor(videoFrame, dstW, COLOR_RGB2BGRA); int channel = 2; // Select the channel to save Mat res; vector<Mat> spl; split(videoFrame, spl); // process - extract only the correct channel for (int i =0; i < 3; ++i) if (i != channel) spl[i] = Mat::zeros(Size(videoFrame.cols, videoFrame.rows), spl[0].type()); merge(spl, res); *outputVideo << res; } // code end----------------------------------------------------------------------------- }
代码说明:
1、使用VideoCapture读内容文件获取视频信息。
2、初始化输出视频VideoWriter。
3、开始读取mat 写入 VideoWriter。
4、同时将其中两个通道数据设置为0(黑色)。
编解码器标识说明:
CV_FOURCC(‘P’, ‘I’, ‘M’, ‘1’) = MPEG-1 codec
CV_FOURCC(‘M’, ‘J’, ‘P’, ‘G’) = motion-jpeg codec
CV_FOURCC(‘M’, ‘P’, ‘4’, ‘2’) = MPEG-4.2 codec
CV_FOURCC(‘D’, ‘I’, ‘V’, ‘3’) = MPEG-4.3 codec
CV_FOURCC(‘D’, ‘I’, ‘V’, ‘X’) = MPEG-4 codec
CV_FOURCC(‘U’, ‘2’, ‘6’, ‘3’) = H263 codec
CV_FOURCC(‘I’, ‘2’, ‘6’, ‘3’) = H263I codec
CV_FOURCC(‘F’, ‘L’, ‘V’, ‘1’) = FLV1 codec
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!