> 技术文档 > 【开发技术】.Net使用FFmpeg视频特定帧上绘制内容_ffmpeg roi

【开发技术】.Net使用FFmpeg视频特定帧上绘制内容_ffmpeg roi

目录

一、目的

二、解决方案

2.1 什么是FFmpeg

2.2 FFmpeg主要功能

2.3 使用Xabe.FFmpeg调用FFmpeg功能

2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI

三、总结


一、目的

        当前市场上有很多目标检测智能识别的相关算法,当前调用一个医疗行业的AI识别算法后返回了一堆对应帧上的ROI数据,因此为了展示算法识别效果,把返回的Roi画到对应帧上进行展示,这里使用FFmpeg对视频进行处理,基于FFmpeg 的 drawbox 滤镜来绘制 ROI。         展示:         处理前: 处理后:

二、解决方案

2.1 什么是FFmpeg

        FFmpeg 本身是一个多媒体处理工具,它可以对视频流进行各种处理(如裁剪、滤镜、编码等),以及 视频流推送到 RTMP 服务器或从 RTMP 服务器拉取流。

2.2 FFmpeg主要功能

        FFmpeg 主要用于以下几个方面:

  • 推流:将本地视频文件或实时视频流推送到 RTMP 服务器。
  • 拉流:从 RTMP 服务器拉取视频流并进行处理(如转码、转封装等)。
  • 处理流:对视频流进行各种处理(如裁剪、滤镜、编码等)。

2.3 使用Xabe.FFmpeg调用FFmpeg功能

        Xabe.FFmpeg 是一个基于 .NET Standard 的 FFmpeg 封装库,旨在简化媒体处理任务。它允许开发者在不了解 FFmpeg 工作原理的情况下,通过 .NET Core 应用程序调用 FFmpeg 功能,并传递自定义参数。Xabe.FFmpeg 提供了丰富的 API,支持视频和音频的转换、剪辑、合并等操作,适用于各种媒体处理需求。          本项目中使用版本为:5.2.6

dotnet add package Xabe.FFmpeg

        简单使用示例:简单展示了获取视频第一帧保存为图像存储在本地(这里也可以获取任何特定帧)。

using AI.Demo.Models;using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using Xabe.FFmpeg;namespace AI.Demo.Common{ public class FFmpegutil { static FFmpegutil() { //获取存放本地ffmpg.exe路径的文件夹路径 //如果是使用Nuget包安装的FFmpeg,默认路径是当前应用程序的根目录 //如果是手动下载的FFmpeg,需要将ffmpeg.exe放在应用程序的根目录下 var ffmpegPath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, \"ffmpeg.exe\"); if(File.Exists(ffmpegPath)) { //如果ffmpeg.exe存在,则设置FFmpeg的可执行文件路径 FFmpeg.SetExecutablesPath(System.IO.Path.GetDirectoryName(ffmpegPath)); //设置FFmpeg的可执行文件路径 } else { throw new Exception(\"ffmpeg.exe not found in the application directory.\"); } } ///  /// 获取视频第一帧 ///  /// 输入文件路径 /// 输出文件路径 /// FFmpeg命令行参数 public static async Task GetVideoFrame(string inputFile) { //根据传入的视频文件地址,获取该视频的第一帧图片,并保存到指定的输出文件路径  if (string.IsNullOrEmpty(inputFile)) { throw new ArgumentException(\"Input and output file paths must be provided.\"); } if (!File.Exists(inputFile)) { throw new ArgumentException(\"file Not Exist\"); } //输出文件路径  string outputFile = System.IO.Path.ChangeExtension(inputFile, \".jpg\"); // 替换为使用 FFmpeg 的截图功能  await FFmpeg.Conversions.New() .AddParameter($\"-i \\\"{inputFile}\\\" -frames:v 1 \\\"{outputFile}\\\"\") .Start(); return outputFile; } }}

2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI

        基于drawbox的enable参数来控制在特定帧上绘制,drawbox格式: “drawbox=enable=\'eq(n,frameIndex)\':x:y:w:h:color:thickness”

 ///  /// 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI ///  ///  ///  ///  ///  ///  public static async Task DrawRoiByLocation(string inputFile,ref string analyseVdeofile, List locations) { if (string.IsNullOrEmpty(inputFile)) { throw new ArgumentException(\"Input file paths must be provided.\"); } if (!File.Exists(inputFile)) { throw new ArgumentException(\"file Not Exist\"); } //改变输入文件的名字,增加后缀以区分输出文件 string outputFile = System.IO.Path.ChangeExtension(inputFile, \"_analyse.mp4\"); analyseVdeofile = outputFile; try { // 构建FFmpeg滤镜命令 StringBuilder filterBuilder = new StringBuilder(); // 对每个Location(帧)和ROI处理 foreach (var location in locations) { int frameIndex = location.Index; // 对该帧中的每个ROI进行处理 foreach (var roi in location.Rois) {  // 使用drawbox的enable参数来控制在特定帧上绘制  // 格式:drawbox=enable=\'eq(n,frameIndex)\':x:y:w:h:color:thickness  string boxFilter = $\"drawbox=enable=\'eq(n,{frameIndex})\':x={roi.X}:y={roi.Y}:w={roi.W}:h={roi.H}:color=red:thickness=2\";  if (filterBuilder.Length > 0)  filterBuilder.Append(\",\");  filterBuilder.Append(boxFilter); } } // 创建转换命令,直接使用输入文件路径而不是GetMediaInfo var conversion = FFmpeg.Conversions.New() .AddParameter($\"-i \\\"{inputFile}\\\"\") .SetOutput(outputFile); // 如果有滤镜,添加到命令中 if (filterBuilder.Length > 0) { conversion.AddParameter($\"-vf \\\"{filterBuilder}\\\"\").AddParameter(\"-c:v libx264\") // 使用H.264编码器.AddParameter(\"-preset medium\") // 编码速度和质量的平衡.AddParameter(\"-crf 23\") // 控制质量,值越低质量越高.AddParameter(\"-pix_fmt yuv420p\") // 设置像素格式,提高兼容性.AddParameter(\"-c:a aac\") // 使用AAC音频编码器.AddParameter(\"-movflags +faststart\"); // 优化网络播放 } else { // 即使没有滤镜,也确保使用正确的编解码器 conversion.AddParameter(\"-c:v libx264\").AddParameter(\"-preset medium\").AddParameter(\"-crf 23\").AddParameter(\"-pix_fmt yuv420p\").AddParameter(\"-c:a aac\").AddParameter(\"-movflags +faststart\"); } // 执行命令并等待完成 await conversion.Start();  return File.Exists(outputFile); } catch (Exception ex) { Console.WriteLine($\"Error drawing ROI: {ex.Message}\"); return false; } }

三、总结

        FFmpeg是一个强大的 多媒体处理工具,以上的处理只是它整体功能中的一小部分。结合 Xabe.FFmpeg可以进行视频的格式转换、裁剪、增加滤镜多种功能。同时支持在桌面应用、Web应用、Api服务、云服务多种场景下的处理需求。                  把之所学以文载之,欢迎大家多多交流~
煤炭价格实时查询