当前位置:网站首页>C代码生产YUV420 planar格式文件
C代码生产YUV420 planar格式文件
2022-07-03 07:12:00 【HUI的技術筆記】
YUV420知识
对于所有YUV420图像,它们的Y值排列是完全相同的,因为只有Y的图像就是灰度图像。
YUV420根据存储形式,分为YUV420sp(semi-Planar 半平面
)与YUV420p(planar 平面
),它们的数据格式在UV排列上是不同的。420p它是先把U或者V存放完后,再存放V或者U,也就是说UV它们是连续的,而420sp是UV交替存放的。
I420(YU12)和YV12属于YUV420p格式,将Y、U、V分量分别打包,依次存储。NV12与NV21类似,U和V交错排列,属于YUV420sp。
YUV 4:2:0采样,每四个Y共用一组UV分量。所以,计算出一个YUV420在内存中存放的大小,就是下面Y,U,V分量的大小总和,即:Y+U+V => width * height * 3/2
Y = width * hight
U = Y / 4
V = Y / 4
图示:1个像素的YUV存储,每个字母代表一位,
I420: YYYYYYYY UUVV => YUV420P
YV12: YYYYYYYY VVUU => YUV420P
NV12: YYYYYYYY UVUV => UV420SP
NV21: YYYYYYYY VUVU => YUV420SP
在名称中,“YV”表示平面顺序:Y,然后V(然后U)。12
指像素深度:对于YV12,每像素12位。NV12中的12也表示每像素12位。
灰白色YUV
下面这段代码生产一个1080x720的YUV文件,格式是YUV420 planar,对于planar的YUV格式,先连续存储所有像素点的Y,紧接着存储所有像素点的U,随后是所有像素点的V。
所以,data的大小是width * height * 3 / 2
,先写width * height
大小的数据,颜色位0xb4,再写width * height / 2
的大小作为uv的数据,这里选择的UV颜色一样,所以一起写了。这样写出来的文件用过ubuntu上的YUVView工具查看就是灰白色。
int width = 1080;
int height = 720;
int size = width * height * 3 / 2;
uint8_t *data = (uint8_t *)malloc(size);
memset(data, 0xb4, size);
fwrite(data, width * height, 1, fp); // write y data
memset(data + width*height, 0x80, size);
fwrite(data, width*height/2, 1, fp); //write uv data
fclose(fp);
青色YUV
青色的这个文件定义的大小是8x8的文件,因为发现通过YUVView工具,放大8x8的YUV图像后,就可以很清楚的看到YUV分量在图片里面的分布。
下面代码中先申请data内存,然后分别设置不同的值,最后按大小写入。
int width = 8;
int height = 8;
int size = width * height * 3 / 2;
uint8_t *data = (uint8_t *)malloc(size);
// set Y to 131
memset(data, 0x83/* 131 */, width*height);
// set U to 156
memset(data + width*height, 0x9c/* 156 */, width*height/4);
// set V to 44
memset(data + width*height + width*height/4, 0x2c/* 44 */, width*height/4);
FILE* fp = nullptr;
fp = fopen("/sdcard/h264.yuv", "wb");
// write Y
fwrite(data, width * height, 1, fp);
// write UV
fwrite(data+ width*height, width*height/2, 1, fp);
fclose(fp);
通过ubuntu上YUView工具,放大到64倍,就可以看到YUV的分布情况,YUV420四个点有一个UV值:
换成数组的代码
width = 8;
height = 8;
int size = width * height * 3 / 2;
uint8_t *data = (uint8_t *)malloc(size);
memset(data, 0, size);
FILE* fp = nullptr;
fp = fopen("/sdcard/h264.yuv", "wb");
// set Y to 131
for(int i = 0; i < height; i++) {
for(int j = 0; j < width; j++) {
data[i*width + j] = 131;
}
}
// set U to 156
int offset = width * height;
for(int i = 0; i < height/4; i++) {
for(int j = 0; j < width; j++) {
data[offset + i*width + j] = 156;
}
}
// set V to 45
offset = width*height + width*height/4;
for(int i = 0; i < height/4; i++) {
for(int j = 0; j < width; j++) {
data[offset + i*width + j] = 45;
}
}
fwrite(data, width * height, 1, fp);
//write UV
fwrite(data+ width*height, width*height/2, 1, fp);
fclose(fp);
YUView查看,和前面的V值不一样:
前面代码中的颜色表参考
标称范围 | 白色 | 黄色 | 青色 | 绿色 | 红色 | 蓝色 | 黑色 | |
---|---|---|---|---|---|---|---|---|
Y | 16~235 | 180 | 162 | 131 | 112 | 65 | 35 | 16 |
Cb | 16~240 | 128 | 44 | 156 | 72 | 100 | 212 | 128 |
Cr | 16~240 | 128 | 142 | 44 | 58 | 212 | 114 | 128 |
边栏推荐
- 2022 East China Normal University postgraduate entrance examination machine test questions - detailed solution
- Deep learning parameter initialization (I) Xavier initialization with code
- [set theory] partition (partition | partition example | partition and equivalence relationship)
- Error c2017: illegal escape sequence
- 2022 - 06 - 23 vgmp - OSPF - Inter - Domain Security Policy - nat Policy (Update)
- php artisan
- EasyExcel
- MySQL mistakenly deleted the root account and failed to log in
- Pytest -- write and manage test cases
- How can I split a string at the first occurrence of “-” (minus sign) into two $vars with PHP?
猜你喜欢
PAT甲级真题1166
Sorting out the core ideas of the pyramid principle
[set theory] partition (partition | partition example | partition and equivalence relationship)
Pat grade a real problem 1166
Mise en place d'un environnement de développement de fonctions personnalisées
Gridome + strapi + vercel + PM2 deployment case of [static site (3)]
La loi des 10 000 heures ne fait pas de vous un maître de programmation, mais au moins un bon point de départ
MySQL installation
10000小时定律不会让你成为编程大师,但至少是个好的起点
My 2020 summary "don't love the past, indulge in moving forward"
随机推荐
Basic teaching of crawler code
JUC forkjoinpool branch merge framework - work theft
CentOS switches and installs mysql5.7 and mysql8.0
IC_ EDA_ All virtual machine (rich Edition): questasim, vivado, VCs, Verdi, DC, Pt, spyglass, icc2, synthesize, innovative, ic617, mmsim, process library
Centos切换安装mysql5.7和mysql8.0
Win 10 find the port and close the port
Advanced API (character stream & net for beginners)
Hands on redis master-slave replication, sentinel master-slave switching, cluster sharding
EasyExcel
Software testing learning - the next day
Search engine Bing Bing advanced search skills
Tool class static method calls @autowired injected service
[set theory] equivalence classes (concept of equivalence classes | examples of equivalence classes | properties of equivalence classes | quotient sets | examples of quotient sets)*
PHP install the spool extension
【已解决】Unknown error 1146
Shim and Polyfill in [concept collection]
【无标题】
Realize PDF to picture conversion with C #
高并发内存池
[Fiddler actual operation] how to use Fiddler to capture packets on Apple Mobile Phones