C实现YUV420序列定区域裁剪
目的
实现对视频序列的某一区域定区域裁剪。示意图如下:
目的是将一个视频序列中某个固定位置的方形区域给抠出来。
代码实现
#include<iostream>
int main() {
int w = 1920;//帧宽
int h = 1080;//帧高
int f_num = 64;//处理帧数
const char* in_path = "E:/sequence/BasketballDrive65Frames_1920x1080_50_21.yuv";//待裁剪序列存储路径
const char* out_path = "E:/sequence/BasketballDrive65Frames_256x256_50_21.yuv";//输出路径
int block_size = 256;//裁剪块尺寸
int offset_x = 1024;//水平偏移坐标
int offset_y = 256;//垂直偏移坐标
uint8_t* ybuffer = (uint8_t*)malloc(block_size*block_size);
uint8_t* ubuffer = (uint8_t*)malloc((block_size * block_size)>>2);
uint8_t* vbuffer = (uint8_t*)malloc((block_size * block_size) >> 2);
FILE* fp;
fopen_s(&fp, in_path, "rb");
FILE* fp1;
fopen_s(&fp1, out_path, "wb");
for (int i = 1; i <= f_num; i++) {
fseek(fp, (i - 1) * w * h * 1.5, SEEK_SET);
//读取y分量
fseek(fp, offset_y * w + offset_x, SEEK_CUR);
for (int y = 0; y < block_size; y++) {
for (int x = 0; x < block_size; x++) {
fread(&ybuffer[y * block_size + x],1,1,fp);
}
fseek(fp, w-block_size, SEEK_CUR);
}
//读取u分量
fseek(fp, (i - 1) * w * h * 1.5, SEEK_SET);
fseek(fp, w * h, SEEK_CUR);
fseek(fp, (offset_y>>1) * (w>>1) + (offset_x>>1), SEEK_CUR);
for (int y = 0; y < block_size >> 1; y++) {
for (int x = 0; x < block_size >> 1; x++) {
fread(&ubuffer[y * (block_size>>1) + x], 1, 1, fp);
}
fseek(fp, (w >> 1)-(block_size>>1), SEEK_CUR);
}
//读取v分量
fseek(fp, (i - 1) * w * h * 1.5, SEEK_SET);
fseek(fp, w * h * 1.25, SEEK_CUR);
fseek(fp, (offset_y >> 1) * (w >> 1) + (offset_x >> 1), SEEK_CUR);
for (int y = 0; y < block_size >> 1; y++) {
for (int x = 0; x < block_size >> 1; x++) {
fread(&vbuffer[y * (block_size >> 1) + x], 1, 1, fp);
}
fseek(fp, (w >> 1) - (block_size >> 1), SEEK_CUR);
}
fwrite(ybuffer, 1, block_size * block_size, fp1);
fwrite(ubuffer, 1, (block_size >> 1) * (block_size >> 1), fp1);
fwrite(vbuffer, 1, (block_size >> 1) * (block_size >> 1), fp1);
}
free(ybuffer);
free(ubuffer);
free(vbuffer);
fclose(fp);
fclose(fp1);
return 0;
}