C语言学习笔记(8)——第一次个人实战(YUV图像分割)
来源:互联网 发布:淘宝数据分析工作 编辑:程序博客网 时间:2024/06/04 00:30
很遗憾第一次实战并没有达到我想要的效果,想要达到的目的是把一个n帧的3840*1920的YUV420p的图像均分成64份。
首先来看一下YUV4:2:0格式的存储格式,首先可以参照大神写的http://blog.csdn.net/lin453701006/article/details/53053185这篇博文了解一下YUV格式。
简单来讲,假设有个4*4的像素点,对于420P而言,不妨假设这四个像素点Y值都为1,U值为2,V值为3
那么YUV的实际存储方式为
1111
1111
1111
1111
22
22
33
33
也就是一个4*4的矩阵加两个长宽为这个矩阵一半的矩阵。
下面就是实际的代码:
首先是主函数,其中while(1)和readsize控制按帧读取,读取到3840*1920的一帧后,要把它们分成64个小文件输出,因此设置了ij表示第i行第j列的第几个小块。其中filename函数可以根据ij设置输出的文件名。YUVslice函数的功能是将图像的64分之一放到output_buff中。
#include "YUV.h"#define _CRT_SECURE_NO_WARNINGS #define IMAGEWIDTH 3840 //图像的宽 #define IMAGEHEIGHT 1920 //高 #define NUM 64//#define Y_SIZE (IMAGEWIDTH*IMAGEHEIGHT) #define YUV420_SIZE (Y_SIZE*3/2) //4:2:0格式 int main(){ FILE * input_yuvfile; //输入YUV420文件的指针 if (NULL == (input_yuvfile = fopen("Driving_in_Country_3840x1920_388p.yuv", "rb"))) { printf("File input is can't open!\n"); return -1; } int readsize; unsigned char *input_buff; input_buff = (unsigned char *)malloc(YUV420_SIZE * sizeof(unsigned char)); while (1) { readsize = fread(input_buff, 1, YUV420_SIZE , input_yuvfile); if (readsize<YUV420_SIZE) //读取的数据量少于YUV420_SIZE时跳出 break; FILE *fq = NULL; for (int i = 0; i <= 7; i++)//i代表分成8*8之后的第几行 { for (int j = 0; j <= 7; j++)//j代表分成8*8之后的 { unsigned char *output_buff; output_buff = (unsigned char *)malloc(YUV420_SIZE * sizeof(unsigned char)/64); char output_yuvfile[15] = { 0 }; filename(i, j, output_yuvfile);//设置输出文件名 YUVslice(i, j, input_buff, output_buff, IMAGEWIDTH, IMAGEHEIGHT);//将原图的64分之一输入到output_buff中 fq = fopen(output_yuvfile, "a+");// 这里打开写入文件,注意使用的是a模式 fwrite(output_buff, 1, YUV420_SIZE/64, fq); free(output_buff); output_buff = NULL; fclose(fq); } } } free(input_buff); input_buff = NULL; fclose(input_yuvfile); return 0;}
下面是函数的具体形式:
#include<stdio.h>#include<stdlib.h>#include<iostream>#include<string.h>#include<vector>#include<malloc.h> #include<memory.h> #include <math.h>#define _CRT_SECURE_NO_WARNINGS #define IMAGEWIDTH 3840 //图像的宽 #define IMAGEHEIGHT 1920 //高 #define NUM 64#define Y_SIZE ( IMAGEWIDTH*IMAGEHEIGHT) #define YUV420_SIZE (Y_SIZE*3/2) //4:2:0格式 char filename(int i, int j, char *output_yuvfile){ //unsigned char frame_num[3];//标示输出的是第几帧 char output_yuvfile_i[3];//表示第几行的块 char output_yuvfile_j[3];//表示第几列的块 memset(output_yuvfile_i, 0, sizeof(output_yuvfile_i)); memset(output_yuvfile_j, 0, sizeof(output_yuvfile_j)); _itoa(i, output_yuvfile_i, 10); _itoa(j, output_yuvfile_j, 10); char outputfile_tail[5] = ".YUV"; strcat(output_yuvfile, output_yuvfile_i); strcat(output_yuvfile, output_yuvfile_j); strcat(output_yuvfile, outputfile_tail);//得到要输出的文件名 return 0;}int YUVslice(int i,int j,unsigned char* input_buff,unsigned char* output_buff,int PIC_W,int PIC_H){ unsigned char *y_buf = NULL; y_buf = (unsigned char *)malloc(YUV420_SIZE * sizeof(unsigned char) / NUM);//y_buff是个大小为原图64分之一的数组 if (y_buf == NULL) { printf("Error: malloc buf.\n"); exit(1); } int h, v; //Y分量切割; for (v = 0 + i*PIC_H / 8; v<PIC_H / 8 + i*PIC_H / 8; v++) { for (h = 0 + j*PIC_W / 8; h<PIC_W / 8 + j*PIC_W / 8; h++) { y_buf[(v - i*PIC_H / 8)*(PIC_W / 8) + h-j*PIC_W / 8] = input_buff[(v*PIC_W + h)];//每次调用YUVslice函数就将原图第v行第第h列的Y值拷贝到y_buff数组的前PIC_H / sqrt(NUM)*PIC_W / sqrt(NUM)个值中。 } } for (v = 0 + i*PIC_H / 16; v<PIC_H / 16 + i*PIC_H / 16; v++) { for (h = 0 + j*PIC_W / 16; h<PIC_W / 16 + j*PIC_W / 16; h++)//这里原理和Y相同,但是其长宽减半,且将uv的值拷贝到y_buff的(v - i*PIC_H / 16)*(PIC_W / 16) + h+偏移的位置 { y_buf[Y_SIZE / 64 + (v - i*PIC_H / 16)*(PIC_W / 16) + h- i*PIC_H / 16] = input_buff[Y_SIZE + (v*PIC_W / 2 + h)];//U y_buf[Y_SIZE * 5 / 256 + (v - i*PIC_H / 16)*(PIC_W / 16) + h- i*PIC_H / 16] = input_buff[Y_SIZE * 5 / 4 + (v*PIC_W / 2 + h)];//V } } memcpy(output_buff, y_buf, YUV420_SIZE / 64); free(y_buf); return 1;}
为什么说是一个失败的实战呢,是因为它可以输出第一帧的左上角的64分之一图像,但是无法输出左上角第二个64分之一的图像。使用断点调试,发现在运行到i=0,j=1时,在YUVslice函数中input_buff的值没有复制到y_buff中,而且,在运行到free (y_buff)时会弹出捕捉到一个break= =。暂时无法解决这个问题,不过分割的思想已经有了 == 希望有用
额,刚刚修改了一下,可以使用了,不要问我修改了哪里,都是微不足道的地方,太不认真了,需要的可以直接用啦
- C语言学习笔记(8)——第一次个人实战(YUV图像分割)
- halcon学习笔记——(12)图像分割
- halcon学习笔记——(12)图像分割
- halcon学习笔记——(12)图像分割
- C 语言学习笔记 (个人)
- halcon学习笔记——图像分割
- MATLAB学习笔记 图像分割(一)
- MATLAB学习笔记 图像分割(二)
- C语言个人学习笔记
- C语言学习个人笔记
- C语言从零学习第一次笔记
- opencv学习笔记 split(图像分割为3通道)
- opencv学习笔记(十七)利用cvPyrSegmentation()做图像分割
- 学习OpenCV范例(二十二)—GrabCut图像分割
- c语言 第一次笔记
- 机器学习实战——个人学习笔记
- 个人R语言学习笔记(1)
- C语言总结-个人学习笔记
- 使用java语言与c++语言通信
- pluck
- 初识SpringBoot,Mavern之环境搭建
- The Elements of Computing Systems阅读笔记(2)
- 笔记
- C语言学习笔记(8)——第一次个人实战(YUV图像分割)
- iOS 视图的模糊效果
- 配置虚拟主机(apache)之后,localhost(127.0.0.1)服务打不开方案
- ubuntu16.04安装php5出现Package php5 have no installation candidate,解决方法
- Xen虚拟化基本原理详解
- Callable和Future
- 飞塔官网账号注册步骤
- 网络编程技术
- Python爬虫基础