音视频 - YUV像素处理

Posted 一只小阿大:)

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了音视频 - YUV像素处理相关的知识,希望对你有一定的参考价值。

将一帧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;
}

遇到的问题

注意:因为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像素数据处理.

以上是关于音视频 - YUV像素处理的主要内容,如果未能解决你的问题,请参考以下文章

OpenCV 从 YUYV 像素格式视频帧创建 YUV420 或灰度 Mat 对象

编程操作YUV像素

编程操作YUV像素

编程操作YUV像素

YUV420P的像素数据编码为H.264的压缩编码数据

YUV420P的像素数据编码为H.264的压缩编码数据