当前位置: 代码网 > 服务器>服务器>Linux > 教你在Linux中从视频流截取图片帧(ffmpeg)

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

2024年11月03日 Linux 我要评论
linux依赖说明:说明: 使用到的 依赖包 1. ffmpegsudo apt update sudo apt-get install ffmpeg2. imagemagick (选装)(检测图像

linux依赖说明:

说明: 使用到的 依赖包  

1. ffmpeg

sudo apt update 
sudo apt-get install ffmpeg

2. 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.jpgoutput_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 ]; then
    echo "usage: ${0##*/} <video_stream_url>"
    exit 1
fi

# 视频流 url
video_url="$1"

# 检查输出目录是否存在
if [ ! -d "/data/hikuser/handler_video_to_picture" ]; then
    echo "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; then
    echo "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) )); then
        max_edge_value=$edge_value
        sharpest_image=$img
    fi
done

# 输出最清晰的图片
echo "最清晰的图片是: $sharpest_image"

# 删除其他图片
for img in output_*.jpg; do
    if [ "$img" != "$sharpest_image" ]; then
        rm "$img"
    fi
done

# 将最清晰的图片重命名为 output.jpg
mv "$sharpest_image" /data/hikuser/handler_video_to_picture/output.jpg

echo "已删除其他图片,保留最清晰的图片: $sharpest_image"

脚本执行效果示例:

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

create_directory.sh

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

#!/bin/bash

# 检查是否提供了文件夹名称参数
if [ "$#" -ne 1 ]; then
    echo "usage: ${0##*/} <directory_name>"
    exit 1
fi

# 文件夹名称
dir_name="$1"

# 检查文件夹是否存在
if [ -d "$dir_name" ]; then
    echo "directory '$dir_name' already exists."
else
    # 创建文件夹
    mkdir -p "$dir_name"
    if [ $? -eq 0 ]; then
        echo "directory '$dir_name' has been created."
    else
        echo "failed to create directory '$dir_name'."
        exit 1
    fi
fi

总结 

到此这篇关于在linux中从视频流截取图片帧(ffmpeg)的文章就介绍到这了,更多相关linux从视频流截取图片帧内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

  • Linux系统中的软连接管理详解

    Linux系统中的软连接管理详解

    软连接的基本概念软连接是一种特殊类型的文件,它包含指向另一个文件或目录的路径。与硬链接不同,软连接可以跨文件系统,也可以指向不存在的目标文件。软连接的优势在于其... [阅读全文]
  • 在Linux上搭建Minecraft服务器的方法步骤

    在Linux上搭建Minecraft服务器的方法步骤

    在选择服务器时,请确保它至少有 1gb 的 ram,最好至少有 2gb。首先,您需要通过ssh 连接到服务器。如果您使用的是 mac,可以打开终端;如果您使用的... [阅读全文]
  • 一文带你搞懂Nginx如何处理请求

    一文带你搞懂Nginx如何处理请求

    nginx(engine x)是一个高性能的http和反向代理服务器,它以其高并发、高性能和低资源消耗著称。这篇文章,我们将从原理、代码以及示例来深入分析 ng... [阅读全文]
  • Linux切换root用户的几种实现方式

    Linux切换root用户的几种实现方式

    概述在linux操作系统中,root用户是系统的超级用户,拥有的权限。无论是系统配置还是文件操作,都需要root权限才能进行。一般情况下,我们使用普通用户账号进... [阅读全文]
  • Linux如何使用HTTP进行远程系统监控

    简介http协议概述http协议是 超文本传输协议 ,基于tcp/ip通信协议,用于从万维网服务器传输数据到本地浏览器。它的工作原理基于 客户端-服务器架构 ,浏览器作为客户端通过…

    2024年11月04日 服务器
  • Linux下如何安装与设置Vim编辑器

    本文以centos7.4为例,讲解安装与设置vim编辑器我们安装完centos7.4后,它默认是安装了vi编辑器的,但vim编辑器是没安装或者未完全安装的。第一步:安装vim编辑器…

    2024年11月04日 服务器

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com