YUV格式学习:Y转换成RGB24

除了各种YUV格式转换成RGB外,还有一种是只转Y到RGB,如果YUV只有Y分量,也就就是YUV400这个格式了。如果成RGB后,显示出来的图像就是灰度图(因为Y是亮度),也可以理解为黑白图吧。下面给出转换函数:

/**
只支持平面、半平面的格式
交织的不支持,因为不知道如何获取Y
*/
void y_to_rgb24(unsigned char *yuv, unsigned char *rgb, int width, int height)
{
    int y, cb, cr;
    int r, g, b;
    int i = 0;
    unsigned char* p_y;
    unsigned char* p_rgb;

    p_y = yuv;

    p_rgb = rgb;

    // 只转换Y的,U、V也需要,其值固定为128
    cb = 128;
    cr = 128;
    init_yuv422p_table();

    for (i = 0; i < width * height; i++)
    {
        y  = p_y[0];
        r = MAX (0, MIN (255, (V[cr] + Y1[y])/10000));   //R value
        b = MAX (0, MIN (255, (U[cb] + Y1[y])/10000));   //B value
        g = MAX (0, MIN (255, (Y2[y] - 5094*(r) - 1942*(b))/10000)); //G value
        p_rgb[0] = r;
        p_rgb[1] = g;
        p_rgb[2] = b;

        p_rgb += 3;
        p_y++;
    }
}

注意,这个函数只支持平面的格式,因为平面格式的Y是在最前面的,并占用width*height大小。如果是YUYV这类的打包格式,图像显示是错乱的。


PS:至此,除了YUV411这个很少用的格式,其它我所接触的格式转换就完成了。可以为我准备写的播放器做下强有力的技术支撑。

李迟 2015.8.7 中午

发布了483 篇原创文章 · 获赞 252 · 访问量 111万+
展开阅读全文

这个bmp的RGB转YUV,再用Y值输出灰度图为什么运行不出来?

01-23

# 谢谢诸位大佬,我觉得没什么毛病了啊…… ``` #include<stdio.h> #include<stdlib.h> #include<malloc.h> typedef unsigned char BYTE; typedef unsigned short WORD; typedef unsigned long DWORD; /* bmp文件头 */ #pragma pack(1) typedef struct BMPFILEHEADER { BYTE bfType; //文件类型,必须是0x424D,即字符“BM” DWORD bSize; // 文件的大小 WORD bReserved1; // 保留值,必须设置为0 WORD bReserved2; // 保留值,必须设置为0 DWORD bOffset; // 文件头的最后到图像数据位开始的偏移量 }BMPHeader; #pragma pack() /* 位图数据信息结构*/ #pragma pack(1) typedef struct BMP_INFO { DWORD bInfoSize; // 结构的大小 long bWidth; // 图像的宽度 long bHeight; // 图像的高度 WORD bPlanes; // 图像的平面数 WORD bBitCount; // 颜色/像素的位数 DWORD bCompression; // 压缩类型 DWORD bmpImageSize; // DIB数据区的大小,以字节为单位 long bXPelsPerMeter; // 水平分辨率 long bYPelsPerMeter; // 垂直分辨率 DWORD bClrUsed; // 使用的色彩数 DWORD bClrImportant; // 重要的颜色数 }BMPInfo; #pragma pack() /* 彩色表:调色板 */ #pragma pack(1) typedef struct RGB_QUAD { BYTE rgbBlue; // 蓝色强度 BYTE rgbGreen; // 绿色强度 BYTE rgbRed; // 红色强度 BYTE rgbReversed; // 保留值 }RGB; #pragma pack() int main() { FILE *fp,*fg; BMPHeader *fh; BMPInfo *fi; RGB *fq; BYTE data[2000][2000][3]; //存储RGB图像的像素点 BYTE yuv[2000][2000][3]; //yuv BYTE data_gray[2000]; //存储灰度图像的像素点 int i,j,k; printf("%d",0); fp=fopen("test.bmp","rb"); //打开bmp文件 if (fp==NULL){ printf("Can't open the file!\n"); return 0; } fh=(BMPHeader*)malloc(sizeof(BMPHeader)); fi=(BMPInfo*)malloc(sizeof(BMPInfo)); //读取位图头结构和信息头 fread(fh,sizeof(BMPHeader),1,fp); fread(fi,sizeof(BMPInfo),1,fp); //修改头信息 fi->bBitCount=8; fi->bmpImageSize=((fi->bWidth*3+3)/4)*4*fi->bHeight; //fi->biClrUsed=256; fh->bOffset=sizeof(BMPHeader)+sizeof(BMPInfo)+256*sizeof(RGB); fh->bSize=fh->bOffset+fi->bmpImageSize; printf("%d",123); for(i=0;i<fi->bHeight;i++) //读取RGB图像像素 { for(j=0;j<(fi->bWidth+3)/4*4;j++) { for(k=0;k<3;k++){ fread(&data[i][j][k],1,1,fp); } } } /*rgb2yuv*/ for(i=0;i<fi->bHeight;i++) { for(j=0;j<(fi->bWidth+3)/4*4;j++) { yuv[i][j][0]=0.299*data[i][j][2]+0.587*data[i][j][1]+0.114*data[i][j][0];//Y yuv[i][j][1]=0.493*(data[i][j][2]-yuv[i][j][0]);//U yuv[i][j][2]=0.877*(data[i][j][2]-yuv[i][j][0]);//V } } /*创建灰色图像*/ fg=fopen("gray.bmp","wb"); if(fg==NULL) printf("Wrong!(write a gray bmp)\n"); //创建调色板 fq=(RGB*)malloc(256*sizeof(RGB)); for(i=0;i<256;i++) { fq[i].rgbBlue=fq[i].rgbGreen=fq[i].rgbRed=i; //fq[i].rgbReversed=0; } fwrite(fh,sizeof(BMPHeader),1,fg); //将头信息写入 fwrite(fi,sizeof(BMPInfo),1,fg); fwrite(fq,sizeof(RGB),256,fg); for(i=0;i<fi->bHeight;i++){ //读取yuv中的Y值并写入灰度图 for(j=0;j<(fi->bWidth+3)/4*4;j++){ data_gray[j]=(int)yuv[i][j][0]; } fwrite(data_gray,j,1,fg); } free(fh); free(fi); free(fq); fclose(fp); fclose(fg); return 0; } ``` 问答

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 技术工厂 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览