FFmpeg源码分析:视频滤镜介绍(下)

FFmpeg在libavfilter模块提供音视频滤镜。所有的视频滤镜都注册在libavfilter/allfilters.c。我们也可以使用ffmpeg -filters命令行来查看当前支持的所有滤镜,前面-v代表视频。本篇文章主要介绍视频滤镜,包括:绘制文字、边缘检测、淡入淡出、高斯模糊、左右镜像、图层叠加、视频旋转。

关于视频滤镜的详细介绍,可查看官方文档:视频滤镜。视频滤镜介绍的上半部分,可以查看上一篇文章:视频滤镜介绍(上)。

1、drawtext

绘制文字,在视频画面上绘制文本文字。需要开启freetype第三方库--enable-freetype,详细介绍可查看:freetype官网。如果要设置字体大小、颜色,需要开启fontconfig第三方库--enable-fontconfig,详情可查看:fontconfig官网。如果要设置字体形状,需要开启libfribidi第三方库--enable-libfribidi,详情可查看:fribidi的GitHub网站。

参数选项如下:

box:是否使用背景颜色绘制矩形框, 1 (开启) 或0 (关闭),默认为关闭 boxborderw:绘制矩形边框的宽度,默认为0 boxcolor:绘制矩形边框的颜色,默认为白色 line_spacing:行距,默认为0 basetime:开始计时时间,单位微秒 fontcolor:字体颜色,默认为黑色 font:字体,默认为Sans fontfile:字体文件,需要文件的绝对路径 alpha:文字的混合透明通道alpha值,范围为[0.0, 1.0],默认为1.0 fontsize:字体大小,默认为16 shadowcolor:阴影颜色,默认为黑色 shadowx、shadowy:文本阴影相对于文本的x、y偏移量 timecode:时间码,默认格式为 "hh:mm:ss[:;.]ff" text:字符串文本,必须为UTF-8编码格式 textfile:文本文件,必须为UTF-8编码格式 main_h, h, H:输入高度 main_w, w, W:输入宽度 n:从哪一帧开始绘制文本,默认为0 t:时间戳表达式,单位为秒, NAN为未知值 text_h, th:文字高度 text_w, tw:文字宽度 x、y:文本在视频画面的xy坐标点,作为渲染文本的起始位置 绘制文本参考命令,指定文本、xy坐标点、字体大小、字体颜色:

ffmpeg -i in.mp4 -vf drawtext="text='Hello world:x=10:y=20:fontcolor=red" watermark.mp4

添加文字水印的效果如下图所示:

2、edgedetect

边缘检测,用于检测与绘制边缘,使用Canny边缘检测算法。关于Canny边缘检测算法原理,详情可查看:Canny边缘检测的维基百科。边缘检测步骤如下:

(1) 应用高斯滤波器平滑图像以去除噪声 (2) 计算图像的梯度与方向 (3) 应用梯度幅度阈值或下限截止抑制来消除对边缘检测的虚假响应 (4) 应用双阈值来确定潜在边缘 (5) 滞后跟踪边缘:抑制所有其他弱且未连接到强边缘的边缘 参数选项如下:

low、high:Canny边缘检测阈值,范围 [0,1],默认最小值为20/255, 默认最大值为50/255 mode:绘制模式,默认为wire,所有模式如下所示: ‘wires’:黑色背景中绘制白灰连线 ‘colormix’:混合颜色,类似绘画卡通效果 ‘canny’:每个平面都进行Canny检测 planes:是否开启平面过滤,默认开启

2.1 边缘检测算法

边缘检测的代码位于libavfilter/vf_edgedetect.c,操作步骤包括高斯滤波、sobel算子、消除响应、双阈值寻找潜在边缘、滞后跟踪边缘,核心代码如下:

static int filter_frame(AVFilterLink *inlink, AVFrame *in)
{
    ......
    // 从缓冲区获取视频帧数据
    out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
    
    for (p = 0; p < edgedetect->nb_planes; p++) {
        ......
        // 高斯滤波,图像降噪处理
        gaussian_blur(ctx, width, height,
                      tmpbuf,      width,
                      in->data[p], in->linesize[p]);
 
        // sobel算子: 计算图像梯度和方向
        sobel(width, height,
              gradients, width,
              directions,width,
              tmpbuf,    width);
 
        memset(tmpbuf, 0, width * height);
        // 应用梯度阈值消除虚假响应
        non_maximum_suppression(width, height,
                                tmpbuf,    width,
                                directions,width,
                                gradients, width);
 
        // 应用高低位双阈值来确定潜在边缘
        double_threshold(edgedetect->low_u8, edgedetect->high_u8,
                         width, height,
                         out->data[p], out->linesize[p],
                         tmpbuf,       width);
        // 颜色混合,滞后跟踪边缘
        if (edgedetect->mode == MODE_COLORMIX) {
            color_mix(width, height,
                      out->data[p], out->linesize[p],
           
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值