FFmpeg提取一个yuv中的部分帧

本文介绍了如何使用C++库和ffmpeg工具实现YUV文件的隔帧分割,以及如何从大型YUV文件中提取指定帧数的片段。内容包括切分函数的源码和ffmpeg命令实例,适用于帧率扩展和视频编辑需求。

from:link

YUV处理实用小工具

1、隔帧分割:

功能说明:cutYUV.cpp 实现YUV文件分割为两个子YUV,隔帧写入YUV,实现帧率扩倍功能。

#include "stdio.h"
#include "stdlib.h"
#include "string"

int main(int argc, char** argv)
{
	unsigned char* y;
	FILE* fp_input, *fp_out1, *fp_out2;
	int width, height, picturesize, framenum = 0;

	printf("Usage: splitYUV.exe  srcyuv dstyuv1 dstyuv2 width height\n\n");

	if (argc < 5)
	{
		return -1;
	} width = atoi(argv[4]);
	height = atoi(argv[5]);

	fp_input = fopen(argv[1], "rb");
	if (NULL == fp_input)
	{
		printf("open %s fail!\n", argv[1]);
		return -1;
	}

	fp_out1 = fopen(argv[2], "wb");
	if (NULL == fp_out1)
	{
		printf("open %s fail!\n", argv[2]);
		return -1;
	}

	fp_out2 = fopen(argv[3], "wb");
	if (NULL == fp_out2)
	{
		printf("open %s fail!\n", argv[3]);
		return -1;
	}

	picturesize = width*height * 3 / 2;//++YUV420

	y = (unsigned char*)malloc(picturesize*sizeof(unsigned char*));

	while (fread(y, 1, picturesize, fp_input) == picturesize)
	{
		if (framenum % 2 == 0)
		{ fwrite(y, 1, picturesize, fp_out1);
		}
		else
		{ fwrite(y, 1, picturesize, fp_out2);
		}
		framenum++;
	}

	printf("[SplitYUV] split %s to %s and %s successfully!!!\n", argv[1], argv[2], argv[3]);

	free(y);
	y = NULL;
	fclose(fp_input);
	fclose(fp_out1);
	fclose(fp_out2);

	return 0;
}

另外,还可以通过ffmpeg实现隔帧分割的功能:

ffmpeg -r 2 -s WxH -i rawbitstream.yuv -filter:v select="mod(n-1\,2)" \
-c:v rawvideo -r 1 -format rawvideo -pix_fmt yuv420p -an odd.yuv

ffmpeg -r 2 -s WxH -i rawbitstream.yuv -filter:v select="not(mod(n-1\,2))" \
-c:v rawvideo -r 1 -format rawvideo -pix_fmt yuv420p -an even.yuv

更多可以参考:
https://superuser.com/questions/573747/drop-every-even-or-odd-frames-using-ffmpeg

2、分段分割:

Extract some YUV frames from large yuv File
从第0帧开始截取30帧:

ffmpeg -s widthxheight -i input.yuv -c:v rawvideo -filter:v select="gt(n\, -1)" -vframes 30 out30.yuv
或者
ffmpeg -s widthxheight -i input.yuv -c:v rawvideo -filter:v select="between(n\, 0\, 29)" out30.yuv
或者
ffmpeg -r 1 -ss 0 -i input.yuv -vcodec copy -vframes 30 output.yuv

更多命令使用参考:

http://processors.wiki.ti.com/index.php/Open_Source_Video_Processing_Tools_-_MPlayer,_FFMpeg,_AviSynth,_MKVToolnix,_MP4Box#Downloads
http://ffmpeg.org/ffmpeg-filters.html#aselect_002c-select
https://lists.ffmpeg.org/pipermail/ffmpeg-user/2017-February/035335.html
https://www.bookstack.cn/read/other-doc-cn-ffmpeg/ffmpeg-doc-cn-40.md

### 提取前100并保存为YUV格式的FFmpeg命令 从一个包含300YUV文件中提取前100并保存为YUV格式,可以使用以下FFmpeg命令: ```bash ffmpeg -s 720x1280 -pix_fmt yuv420p -i input.yuv -vframes 100 -pix_fmt yuv420p output.yuv ``` - `-s 720x1280` 指定输入视频的分辨率[^1]。 - `-pix_fmt yuv420p` 指定像素格式为 YUV420P。 - `-i input.yuv` 指定输入文件为 `input.yuv`。 - `-vframes 100` 指定只提取前100[^2]。 - `-pix_fmt yuv420p` 再次指定输出文件的像素格式为 YUV420P[^1]。 - `output.yuv` 是输出文件名。 此命令会从 `input.yuv` 中提取前100,并将结果保存到 `output.yuv` 文件中。 ### 示例代码 如果需要进一步验证或处理提取,可以结合其他工具进行操作。以下是使用 Python 脚本读取提取YUV 文件并显示第一的示例: ```python import numpy as np import cv2 # 定义分辨率和数 width, height = 720, 1280 frame_count = 100 # 读取 YUV 文件 with open("output.yuv", "rb") as f: yuv_data = f.read(width * height * 3 // 2) # 将 YUV 数据转换为 NumPy 数组 yuv_array = np.frombuffer(yuv_data, dtype=np.uint8).reshape((frame_count, height * 3 // 2, width)) # 提取第一并转换为 BGR 格式 yuv_frame = yuv_array[0] bgr_frame = cv2.cvtColor(yuv_frame, cv2.COLOR_YUV2BGR_I420) # 显示第一 cv2.imshow("First Frame", bgr_frame) cv2.waitKey(0) cv2.destroyAllWindows() ``` 此代码片段展示了如何加载提取YUV 文件并显示第一图像。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值