当前位置: 首页 > news >正文

在Linux中从视频流截取图片帧(ffmpeg )

Linux依赖说明:

说明: 使用到的 依赖包  1. ffmpegsudo apt update 
sudo apt-get install ffmpeg2. imagemagick (选装)
(检测图像边缘信息推断清晰度,如果是简单截取但个图像帧=>用不到<=)sudo apt-get install imagemagick备注: 
指令及相关参数说明

核心指令: (作用: 执行 ffmpeg 命令提取帧,每10帧选择一帧, 一共提取5张)

示例:

ffmpeg -i “https://cdn.pixabay.com/video/2023/10/22/186115-877653483_large.mp4” -vf “select=‘not(mod(n,10))’” -frames:v 5 -q:v 1 output_%03d.jpg

指令说明:

这条 ffmpeg 命令从视频流中提取帧并保存为图片,具体的参数含义如下:

1. ffmpeg -i "https://cdn.pixabay.com/video/2023/10/22/186115-877653483_large.mp4"

  • ffmpeg:调用 ffmpeg 命令。
  • -i "https://cdn.pixabay.com/video/2023/10/22/186115-877653483_large.mp4":指定输入文件,视频源为给定的网络视频 URL。

2. -vf "select='not(mod(n,10))'"

  • -vf:表示使用视频滤镜。

  • "select='not(mod(n,10))'"
    

    :视频帧选择器,这里

    mod(n,10)
    

    表示每 10 帧提取一次帧。

    n
    

    是当前帧的编号,

    mod(n,10)
    

    计算帧编号除以 10 的余数,

    not(mod(n,10))
    

    选择那些编号是 10 的倍数的帧。

    • 换句话说,这条命令每 10 帧提取一个帧。

3. -frames:v 5

  • 只提取 5 帧图片。

4. -q:v 1

  • -q:v 设置视频帧的质量,范围为 1 到 31,值越小质量越高,1 是最高质量。

5. output_%03d.jpg

  • 输出文件名模板。%03d 是一个占位符,表示文件名中包含 3 位数字(例如 output_001.jpgoutput_002.jpg),这样可以保存多个帧。

整体含义:

从视频中每隔 10 帧提取一个帧,总共提取 5 帧,保存为高质量的 JPEG 图片文件,文件名为 output_001.jpg, output_002.jpg, 以此类推。

指令执行完可见当前文件夹中文件:

在这里插入图片描述

具体的命令可根据需求情况进行修改, 到这里文章的标题功能就已经实现了.

下面是加餐环节


需求: 提取视频中的图片帧, 并从多张中选取最清晰的一张照片

注: 其中的文件路径需要改为自己所存在的路径

这里准备了三个脚本文件如下:

  • extract_frames.sh 提取视频帧输出指定张数据照片并存到指定位置 并执行 detect_sharpness.sh 脚本(已注释掉, 需要的话自行打开)
  • detect_sharpness.sh 从多张照片中选择最清晰的一张 并将其余的照片删除, 且保留最清晰一张并重命名
  • create_directory.sh 判断文件夹是否存在, 不存在则创建, 存在则不处理

extract_frames.sh

提取视频帧输出指定张数据照片并存到指定位置 并执行 detect_sharpness.sh 脚本

注: 执行该脚本需要指定—视频路径

示例:

/data/hikuser/handler_video_to_picture/extract_frames.sh  https://cdn.pixabay.com/video/2023/10/22/186115-877653483_large.mp4
#!/bin/bash# 删除指定目录下已有的图片
rm -f /data/hikuser/handler_video_to_picture/output*.jpg# 检查是否提供了视频流 URL 参数
if [ "$#" -ne 1 ]; thenecho "Usage: ${0##*/} <video_stream_url>"exit 1
fi# 视频流 URL
VIDEO_URL="$1"# 检查输出目录是否存在
if [ ! -d "/data/hikuser/handler_video_to_picture" ]; thenecho "Directory /data/hikuser/handler_video_to_picture does not exist."exit 1
fi# 执行 ffmpeg 命令提取帧,每10帧选择一帧, 一共提取5张
if ! ffmpeg -i "$VIDEO_URL" -vf "select='not(mod(n,10))'" -frames:v 5 -q:v 1 /data/hikuser/handler_video_to_picture/output_%03d.jpg; thenecho "ffmpeg command failed."exit 1
fi# 执行检测图片清晰度的脚本
# if [ -f /data/hikuser/handler_video_to_picture/detect_sharpness.sh ]; then
#    /bin/bash /data/hikuser/handler_video_to_picture/detect_sharpness.sh
# else
#    echo "detect_sharpness.sh script not found!"
#    exit 1
# fi

detect_sharpness.sh

从多张照片中选择像素最高的一张 并将其余的照片删除, 并将最新的一张重命名

#!/bin/bash# 初始化最大边缘值和最清晰的图片变量
max_edge_value=0
sharpest_image=""# 进入图片所在目录
cd /data/hikuser/handler_video_to_picture || exit 1# 遍历每张图片并计算边缘值
for img in output_*.jpg; do# 计算图片的边缘检测值edge_value=$(convert "$img" -edge 1 -format "%[mean]" info:)echo "$img 边缘检测值: $edge_value"# 比较边缘值,保留最大值对应的图片if (( $(echo "$edge_value > $max_edge_value" | bc -l) )); thenmax_edge_value=$edge_valuesharpest_image=$imgfi
done# 输出最清晰的图片
echo "最清晰的图片是: $sharpest_image"# 删除其他图片
for img in output_*.jpg; doif [ "$img" != "$sharpest_image" ]; thenrm "$img"fi
done# 将最清晰的图片重命名为 output.jpg
mv "$sharpest_image" /data/hikuser/handler_video_to_picture/output.jpgecho "已删除其他图片,保留最清晰的图片: $sharpest_image"

脚本执行效果示例:

所以截取的图片大小因为数据源是一个静态视频, 当然如果采集帧率过快时也会出现这样的情况, 注意空值

create_directory.sh

判断文件夹是否存在存在则创建不存在则不处理

#!/bin/bash# 检查是否提供了文件夹名称参数
if [ "$#" -ne 1 ]; thenecho "Usage: ${0##*/} <directory_name>"exit 1
fi# 文件夹名称
DIR_NAME="$1"# 检查文件夹是否存在
if [ -d "$DIR_NAME" ]; thenecho "Directory '$DIR_NAME' already exists."
else# 创建文件夹mkdir -p "$DIR_NAME"if [ $? -eq 0 ]; thenecho "Directory '$DIR_NAME' has been created."elseecho "Failed to create directory '$DIR_NAME'."exit 1fi
fi

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 去除恢复出厂设置中UI文字显示
  • 3.无人机介绍
  • 《人工智能安全治理框架》1.0版
  • 【算法】模拟退火
  • [linux 驱动]i2c总线设备驱动详解与实战
  • 揭开Facebook AI的神秘面纱:如何利用人工智能提升社交体验
  • C++ | Leetcode C++题解之第395题至少有K个重复字符的最长子串
  • 还能买燃油车吗
  • Pygame中Sprite类实现多帧动画3-1
  • 一个例子彻底搞懂对线程模型的理解 !
  • 【Puppeteer】‘left‘ is already pressed, ‘${button}‘ is already pressed 的解决办法
  • Qt常用控件——QRadioButton和QCheckBox
  • 【VSCode v1.93.0】手动配置远程remote-ssh
  • 开源可视化大屏superset Docker环境部署
  • 计算机网络练级第一级————认识网络
  • #Java异常处理
  • CSS 提示工具(Tooltip)
  • ECS应用管理最佳实践
  • ES2017异步函数现已正式可用
  • JavaScript 基础知识 - 入门篇(一)
  • javascript面向对象之创建对象
  • seaborn 安装成功 + ImportError: DLL load failed: 找不到指定的模块 问题解决
  • Vim Clutch | 面向脚踏板编程……
  • 闭包,sync使用细节
  • 七牛云假注销小指南
  • 微服务核心架构梳理
  • 我从编程教室毕业
  • 以太坊客户端Geth命令参数详解
  • 最简单的无缝轮播
  • 京东物流联手山西图灵打造智能供应链,让阅读更有趣 ...
  • 完善智慧办公建设,小熊U租获京东数千万元A+轮融资 ...
  • #AngularJS#$sce.trustAsResourceUrl
  • #pragma once
  • #pragma pack(1)
  • #我与Java虚拟机的故事#连载09:面试大厂逃不过的JVM
  • (0)Nginx 功能特性
  • (003)SlickEdit Unity的补全
  • (C语言)共用体union的用法举例
  • (独孤九剑)--文件系统
  • (二) 初入MySQL 【数据库管理】
  • (二十九)STL map容器(映射)与STL pair容器(值对)
  • (附源码)apringboot计算机专业大学生就业指南 毕业设计061355
  • (转)http-server应用
  • ***监测系统的构建(chkrootkit )
  • .NET “底层”异步编程模式——异步编程模型(Asynchronous Programming Model,APM)...
  • .Net Core 微服务之Consul(三)-KV存储分布式锁
  • .NET Framework .NET Core与 .NET 的区别
  • .NET 动态调用WebService + WSE + UsernameToken
  • .Net多线程Threading相关详解
  • .NET关于 跳过SSL中遇到的问题
  • .NET框架
  • .NET企业级应用架构设计系列之开场白
  • .net知识和学习方法系列(二十一)CLR-枚举
  • .Net中的集合
  • .NET中使用Protobuffer 实现序列化和反序列化