目录
将一帧YUV图像变成黑白照,只保留Y数据(灰度图)
我们把UV数据去掉,只写入Y数据,那么只剩下Y数据,打开图片的时候选择一定要选择以“Y”格式打开,而不是“YUV420”格式打开。
#include <stdio.h>
#include <stdlib.h>
#define startImage "lena_256x256_yuv420p.yuv"
int main()
{
FILE *fp = NULL;
FILE *fp1 = NULL;
unsigned char *readBuf;
readBuf = (unsigned char *)malloc(256*256*3/2);
fp = fopen(startImage,"rb+");
fp1 = fopen("new_256x256_yuv420p.y","wb+");
fread(readBuf,1,256*256,fp);
fwrite(readBuf,1,256*256,fp1);
free(readBuf);
fclose(fp);
fclose(fp1);
return 0;
}
用yuv420格式打开的样子
用y格式打开的样子
将一帧YUV图像变成黑白照,将UV置0(灰度图)
上面只保存了Y数据,准确来说不算是YUV图像,我们不把UV拿掉,将U和V的数据修改为0就代表无色,让他置0也可以让他呈现黑白照。
U、V是图像中的经过偏置处理的色度分量。在偏置处理前,它的取值范围是-128-127,这时,把U和V数据修改为0代表无色。在偏置处理后,它的取值范围变成了0-255,所以这时候需要取中间值,即128。所以我们下面要将U和V数据修改为128
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define outPutFileName "testGrey.yuv"
int testYuv420Grey(char *fileName, int width, int height)
{
FILE *fp;
FILE *fp1;
unsigned char *readBuf;
readBuf = (unsigned char *)malloc(width*height*3/2);
fp = fopen(fileName, "rb+");
fp1 = fopen(outPutFileName, "wb+");
/* read yuv file */
fread(readBuf, 1, width*height, fp);
/* memset U and V*/
memset(readBuf+width*height, 128, width*height/2);
/* create new file */
fwrite(readBuf, 1, width*height*3/2, fp1);
free(readBuf);
fclose(fp);
fclose(fp1);
return 0;
}
int main()
{
testYuv420Grey("lena_256x256_yuv420p.yuv", 256, 256);
return 0;
}
将一帧YUV图像U值置0,其他不动
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define outPutFileName "test0u.yuv"
int testYuv420Grey(char *fileName, int width, int height)
{
FILE *fp;
FILE *fp1;
unsigned char *readBuf;
readBuf = (unsigned char *)malloc(width*height*3/2);
fp = fopen(fileName, "rb+");
fp1 = fopen(outPutFileName, "wb+");
/* read yuv file */
fread(readBuf, 1, width*height, fp);
/* memset U*/
memset(readBuf+width*height, 128, width*height/4);
/* create new file */
fwrite(readBuf, 1, width*height*3/2, fp1);
free(readBuf);
fclose(fp);
fclose(fp1);
return 0;
}
int main()
{
testYuv420Grey("lena_256x256_yuv420p.yuv", 256, 256);
return 0;
}
将一帧YUV图像V值置0,其他不动
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define outPutFileName "test0v.yuv"
int testYuv420Grey(char *fileName, int width, int height)
{
FILE *fp;
FILE *fp1;
unsigned char *readBuf;
readBuf = (unsigned char *)malloc(width*height*3/2);
fp = fopen(fileName, "rb+");
fp1 = fopen(outPutFileName, "wb+");
/* read yuv file */
fread(readBuf, 1, width*height, fp);
/* memset V */
memset(readBuf+width*height*5/4, 128, width*height/4);
/* create new file */
fwrite(readBuf, 1, width*height*3/2, fp1);
free(readBuf);
fclose(fp);
fclose(fp1);
return 0;
}
int main()
{
testYuv420Grey("lena_256x256_yuv420p.yuv", 256, 256);
return 0;
}
将Y(亮度)值减半
#include <stdio.h>
#include <stdlib.h>
#define startImage "lena_256x256_yuv420p.yuv"
int main()
{
FILE *fp = NULL;
FILE *fp1 = NULL;
int nIdx = 0;
unsigned char *readBuf;
readBuf = (unsigned char *)malloc(256*256*3/2);
fp = fopen(startImage,"rb+");
fp1 = fopen("halfbrightness.yuv","wb+");
fread(readBuf,1,256*256*3/2,fp);
for(nIdx=0;nIdx<256*256;nIdx++)
{
readBuf[nIdx] = readBuf[nIdx]/2;
}
fwrite(readBuf,1,256*256*3/2,fp1);
free(readBuf);
fclose(fp);
fclose(fp1);
return 0;
}
自己制作一帧YUV420灰阶测试图
U和V数据置为128,将Y数据递增即可。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define OP_File "GreyTest.yuv"
#define yMAX 255
/**
* Get gray scale test diagram
* @param width : 输出图片的宽
* @param height: 输出图片的高
* @param num : 输出灰阶测试图条数
*
*/
int getGreyTest(int width,int height,int num)
{
FILE *fp = NULL;
int y_data[32];
int new_ydata = 0;
int yMAX_distance = yMAX/num;
int width_distance = width/num;
long FILE_Size = width*height*3/2;
unsigned char *buf;
buf = (unsigned char *)malloc(FILE_Size);
fp = fopen(OP_File,"wb+");
if(fp == NULL)
{
printf("fopen error!\n");
return -1;
}
for(int i = 0;i<num;i++)
{
y_data[i] = new_ydata;
new_ydata += yMAX_distance;
printf("Y = %d U = %d V = %d\n",y_data[i],128,128);
}
memset(buf,0,FILE_Size);
for(int h=0;h<height;h++)
{
for(int cnt = 0;cnt<num;cnt++)
{
memset(buf + cnt*width_distance + h*width,y_data[cnt]
,width_distance);
}
}
memset(buf+height*width,128,height*width/2);
fwrite(buf,1,FILE_Size,fp);
printf("Generate success\n");
free(buf);
fclose(fp);
}
int main()
{
int num = 0;
printf("please input num:\n");
scanf("%d",&num);
getGreyTest(352,288,num);
return 0;
}
下图中有四列,每列还会分为行(h * width)和列(cnt * width_distance)
遇到的问题
注意:因为CSDN编辑格式我给 * 旁边各加了个空格
刚开始学习的时候,看半天fwritefwrite(pic+w * h,1,w * h/4,fp2)没看懂是啥意思,pic+w * h就是pic从w*h开始操作数据
其中前w * h Byte存储Y,接着的w * h * 1/4 Byte存储U,最后w * h * 1/4 Byte存储V
参考文档:
音视频入门(一) - YUV像素处理
yuv rgb 像素格式1
视音频数据处理入门:RGB、YUV像素数据处理.