小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

linux 平臺camera失去YUV數(shù)據(jù)轉(zhuǎn)RGB888及加BMP頭文件

 dwlinux 2014-03-24
linux 平臺camera得到Y(jié)UV數(shù)據(jù)轉(zhuǎn)RGB888及加BMP頭文件

需要在Android平臺上通過UVC得到純YUV數(shù)據(jù),需要驗證數(shù)據(jù)的正確性。因此需要將每一幀的YUV數(shù)據(jù)轉(zhuǎn)為RGB888,但純的RGB888數(shù)據(jù)也無法在windows或者ubuntu上打開,需要加BMP頭。此文章介紹其實現(xiàn)方法。

第一步:YUY2轉(zhuǎn)為RGB888.

參考文章:

http://blog.csdn.net/jtujtujtu/article/details/3874621

//////////////////////////////////////////////////////////////////////////
// YUV2RGB
// pYUV			point to the YUV data
// pRGB			point to the RGB data
// width		width of the picture
// height		height of the picture
// alphaYUV		is there an alpha channel in YUV
// alphaRGB		is there an alpha channel in RGB
//////////////////////////////////////////////////////////////////////////
int YUV2RGB(void* pYUV, void* pRGB, int width, int height, bool alphaYUV, bool alphaRGB)
{
	if (NULL == pYUV)
	{
		return -1;
	}
	unsigned char* pYUVData = (unsigned char *)pYUV;
	unsigned char* pRGBData = (unsigned char *)pRGB;
	if (NULL == pRGBData)
	{
		if (alphaRGB)
		{
			pRGBData = new unsigned char[width*height*4];
		}
		else
			pRGBData = new unsigned char[width*height*3];
	}
	int Y1, U1, V1, Y2, alpha1, alpha2, R1, G1, B1, R2, G2, B2;
	int C1, D1, E1, C2;
	if (alphaRGB)
	{
		if (alphaYUV)
		{
			for (int i=0; i>8>255 ? 255 : (298*C1 + 409*E1 + 128)>>8);
					G1 = ((298*C1 - 100*D1 - 208*E1 + 128)>>8>255 ? 255 : (298*C1 - 100*D1 - 208*E1 + 128)>>8);	
					B1 = ((298*C1+516*D1 +128)>>8>255 ? 255 : (298*C1+516*D1 +128)>>8);	
					R2 = ((298*C2 + 409*E1 + 128)>>8>255 ? 255 : (298*C2 + 409*E1 + 128)>>8);
					G2 = ((298*C2 - 100*D1 - 208*E1 + 128)>>8>255 ? 255 : (298*C2 - 100*D1 - 208*E1 + 128)>>8);
					B2 = ((298*C2 + 516*D1 +128)>>8>255 ? 255 : (298*C2 + 516*D1 +128)>>8);	
					*(pRGBData+(height-i-1)*width*4+j*8+2) = R1<0 ? 0 : R1;
					*(pRGBData+(height-i-1)*width*4+j*8+1) = G1<0 ? 0 : G1;
					*(pRGBData+(height-i-1)*width*4+j*8) = B1<0 ? 0 : B1;
					*(pRGBData+(height-i-1)*width*4+j*8+3) = alpha1;	
					*(pRGBData+(height-i-1)*width*4+j*8+6) = R2<0 ? 0 : R2;
					*(pRGBData+(height-i-1)*width*4+j*8+5) = G2<0 ? 0 : G2;
					*(pRGBData+(height-i-1)*width*4+j*8+4) = B2<0 ? 0 : B2;
					*(pRGBData+(height-i-1)*width*4+j*8+7) = alpha2;	
				}
			}	
		}
		else
		{
			int alpha = 255;
			for (int i=0; i>8>255 ? 255 : (298*C1 + 409*E1 + 128)>>8);
					G1 = ((298*C1 - 100*D1 - 208*E1 + 128)>>8>255 ? 255 : (298*C1 - 100*D1 - 208*E1 + 128)>>8);	
					B1 = ((298*C1+516*D1 +128)>>8>255 ? 255 : (298*C1+516*D1 +128)>>8);	
					R2 = ((298*C2 + 409*E1 + 128)>>8>255 ? 255 : (298*C2 + 409*E1 + 128)>>8);
					G2 = ((298*C2 - 100*D1 - 208*E1 + 128)>>8>255 ? 255 : (298*C2 - 100*D1 - 208*E1 + 128)>>8);
					B2 = ((298*C2 + 516*D1 +128)>>8>255 ? 255 : (298*C2 + 516*D1 +128)>>8);	
					*(pRGBData+(height-i-1)*width*4+j*8+2) = R1<0 ? 0 : R1;
					*(pRGBData+(height-i-1)*width*4+j*8+1) = G1<0 ? 0 : G1;
					*(pRGBData+(height-i-1)*width*4+j*8) = B1<0 ? 0 : B1;
					*(pRGBData+(height-i-1)*width*4+j*8+3) = alpha;	
					*(pRGBData+(height-i-1)*width*4+j*8+6) = R2<0 ? 0 : R2;
					*(pRGBData+(height-i-1)*width*4+j*8+5) = G2<0 ? 0 : G2;
					*(pRGBData+(height-i-1)*width*4+j*8+4) = B2<0 ? 0 : B2;
					*(pRGBData+(height-i-1)*width*4+j*8+7) = alpha;	
				}
			}	
		}
	}
	else
	{
		if (alphaYUV)
		{
			for (int i=0; i>8>255 ? 255 : (298*C1 + 409*E1 + 128)>>8);
					G1 = ((298*C1 - 100*D1 - 208*E1 + 128)>>8>255 ? 255 : (298*C1 - 100*D1 - 208*E1 + 128)>>8);	
					B1 = ((298*C1+516*D1 +128)>>8>255 ? 255 : (298*C1+516*D1 +128)>>8);	
					R2 = ((298*C2 + 409*E1 + 128)>>8>255 ? 255 : (298*C2 + 409*E1 + 128)>>8);
					G2 = ((298*C2 - 100*D1 - 208*E1 + 128)>>8>255 ? 255 : (298*C2 - 100*D1 - 208*E1 + 128)>>8);
					B2 = ((298*C2 + 516*D1 +128)>>8>255 ? 255 : (298*C2 + 516*D1 +128)>>8);	
					*(pRGBData+(height-i-1)*width*3+j*6+2) = R1<0 ? 0 : R1;
					*(pRGBData+(height-i-1)*width*3+j*6+1) = G1<0 ? 0 : G1;
					*(pRGBData+(height-i-1)*width*3+j*6) = B1<0 ? 0 : B1;
					*(pRGBData+(height-i-1)*width*3+j*6+5) = R2<0 ? 0 : R2;
					*(pRGBData+(height-i-1)*width*3+j*6+4) = G2<0 ? 0 : G2;
					*(pRGBData+(height-i-1)*width*3+j*6+3) = B2<0 ? 0 : B2;
				}
			}
		}
		else
		{
			for (int i=0; i>8>255 ? 255 : (298*C1 + 409*E1 + 128)>>8);
					G1 = ((298*C1 - 100*D1 - 208*E1 + 128)>>8>255 ? 255 : (298*C1 - 100*D1 - 208*E1 + 128)>>8);	
					B1 = ((298*C1+516*D1 +128)>>8>255 ? 255 : (298*C1+516*D1 +128)>>8);	
					R2 = ((298*C2 + 409*E1 + 128)>>8>255 ? 255 : (298*C2 + 409*E1 + 128)>>8);
					G2 = ((298*C2 - 100*D1 - 208*E1 + 128)>>8>255 ? 255 : (298*C2 - 100*D1 - 208*E1 + 128)>>8);
					B2 = ((298*C2 + 516*D1 +128)>>8>255 ? 255 : (298*C2 + 516*D1 +128)>>8);	
					*(pRGBData+(height-i-1)*width*3+j*6+2) = R1<0 ? 0 : R1;
					*(pRGBData+(height-i-1)*width*3+j*6+1) = G1<0 ? 0 : G1;
					*(pRGBData+(height-i-1)*width*3+j*6) = B1<0 ? 0 : B1;
					*(pRGBData+(height-i-1)*width*3+j*6+5) = R2<0 ? 0 : R2;
					*(pRGBData+(height-i-1)*width*3+j*6+4) = G2<0 ? 0 : G2;
					*(pRGBData+(height-i-1)*width*3+j*6+3) = B2<0 ? 0 : B2;
				}
			}	
		}
	}
	return 0;
}

//////////////////////////////////////////////////////////////////////////
// RGB2YUV
// pRGB			point to the RGB data
// pYUV			point to the YUV data
// width		width of the picture
// height		height of the picture
// alphaYUV		is there an alpha channel in YUV
// alphaRGB		is there an alpha channel in RGB
//////////////////////////////////////////////////////////////////////////
int RGB2YUV(void* pRGB, void* pYUV, int width, int height, bool alphaYUV, bool alphaRGB)
{
	if (NULL == pRGB)
	{
		return -1;
	}
	unsigned char* pRGBData = (unsigned char *)pRGB;
	unsigned char* pYUVData = (unsigned char *)pYUV;
	if (NULL == pYUVData)
	{
		if (alphaYUV)
		{
			pYUVData = new unsigned char[width*height*3];
		}
		else
			pYUVData = new unsigned char[width*height*2];
	}
	int R1, G1, B1, R2, G2, B2, Y1, U1, Y2, V1;
	int alpha1, alpha2;
	if (alphaYUV)
	{
		if (alphaRGB)
		{
			for (int i=0; i>8) + 16) > 255 ? 255 : (((66*R1+129*G1+25*B1+128)>>8) + 16);
					U1 = ((((-38*R1-74*G1+112*B1+128)>>8)+((-38*R2-74*G2+112*B2+128)>>8))/2 + 128)>255 ? 255 : ((((-38*R1-74*G1+112*B1+128)>>8)+((-38*R2-74*G2+112*B2+128)>>8))/2 + 128);
					Y2 = (((66*R2+129*G2+25*B2+128)>>8) + 16)>255 ? 255 : ((66*R2+129*G2+25*B2+128)>>8) + 16;
					V1 = ((((112*R1-94*G1-18*B1+128)>>8) + ((112*R2-94*G2-18*B2+128)>>8))/2 + 128)>255 ? 255 : ((((112*R1-94*G1-18*B1+128)>>8) + ((112*R2-94*G2-18*B2+128)>>8))/2 + 128);
					*(pYUVData+i*width*3+j*6) = Y1;
					*(pYUVData+i*width*3+j*6+1) = U1;
					*(pYUVData+i*width*3+j*6+2) = Y2;
					*(pYUVData+i*width*3+j*6+3) = V1;
					*(pYUVData+i*width*3+j*6+4) = alpha1;
					*(pYUVData+i*width*3+j*6+5) = alpha2;
				}
			}	
		}
		else
		{
			unsigned char alpha = 255;
			for (int i=0; i>8) + 16;
					U1 = ((-38*R1-74*G1+112*B1+128)>>8+(-38*R2-74*G2+112*B2+128)>>8)/2 + 128;
					Y2 = ((66*R2+129*G2+25*B2+128)>>8) + 16;
					V1 = ((112*R1-94*G1-18*B1+128)>>8 + (112*R2-94*G2-18*B2+128)>>8)/2 + 128;
					Y1 = (((66*R1+129*G1+25*B1+128)>>8) + 16) > 255 ? 255 : (((66*R1+129*G1+25*B1+128)>>8) + 16);
					U1 = ((((-38*R1-74*G1+112*B1+128)>>8)+((-38*R2-74*G2+112*B2+128)>>8))/2 + 128)>255 ? 255 : ((((-38*R1-74*G1+112*B1+128)>>8)+((-38*R2-74*G2+112*B2+128)>>8))/2 + 128);
					Y2 = (((66*R2+129*G2+25*B2+128)>>8) + 16)>255 ? 255 : ((66*R2+129*G2+25*B2+128)>>8) + 16;
					V1 = ((((112*R1-94*G1-18*B1+128)>>8) + ((112*R2-94*G2-18*B2+128)>>8))/2 + 128)>255 ? 255 : ((((112*R1-94*G1-18*B1+128)>>8) + ((112*R2-94*G2-18*B2+128)>>8))/2 + 128);
					*(pYUVData+i*width*3+j*6) = Y1;
					*(pYUVData+i*width*3+j*6+1) = U1;
					*(pYUVData+i*width*3+j*6+2) = Y2;
					*(pYUVData+i*width*3+j*6+3) = V1;
					*(pYUVData+i*width*3+j*6+4) = alpha;
					*(pYUVData+i*width*3+j*6+5) = alpha;
				}
			}	
		}
	}
	else
	{
		if (alphaRGB)
		{
			for (int i=0; i>8) + 16) > 255 ? 255 : (((66*R1+129*G1+25*B1+128)>>8) + 16);
					U1 = ((((-38*R1-74*G1+112*B1+128)>>8)+((-38*R2-74*G2+112*B2+128)>>8))/2 + 128)>255 ? 255 : ((((-38*R1-74*G1+112*B1+128)>>8)+((-38*R2-74*G2+112*B2+128)>>8))/2 + 128);
					Y2 = (((66*R2+129*G2+25*B2+128)>>8) + 16)>255 ? 255 : ((66*R2+129*G2+25*B2+128)>>8) + 16;
					V1 = ((((112*R1-94*G1-18*B1+128)>>8) + ((112*R2-94*G2-18*B2+128)>>8))/2 + 128)>255 ? 255 : ((((112*R1-94*G1-18*B1+128)>>8) + ((112*R2-94*G2-18*B2+128)>>8))/2 + 128);
					*(pYUVData+i*width*2+j*4) = Y1;
					*(pYUVData+i*width*2+j*4+1) = U1;
					*(pYUVData+i*width*2+j*4+2) = Y2;
					*(pYUVData+i*width*2+j*4+3) = V1;
				}
			}	
		}
		else
		{
			for (int i=0; i>8) + 16) > 255 ? 255 : (((66*R1+129*G1+25*B1+128)>>8) + 16);
					U1 = ((((-38*R1-74*G1+112*B1+128)>>8)+((-38*R2-74*G2+112*B2+128)>>8))/2 + 128)>255 ? 255 : ((((-38*R1-74*G1+112*B1+128)>>8)+((-38*R2-74*G2+112*B2+128)>>8))/2 + 128);
					Y2 = (((66*R2+129*G2+25*B2+128)>>8) + 16)>255 ? 255 : ((66*R2+129*G2+25*B2+128)>>8) + 16;
					V1 = ((((112*R1-94*G1-18*B1+128)>>8) + ((112*R2-94*G2-18*B2+128)>>8))/2 + 128)>255 ? 255 : ((((112*R1-94*G1-18*B1+128)>>8) + ((112*R2-94*G2-18*B2+128)>>8))/2 + 128);
					*(pYUVData+i*width*2+j*4) = Y1;
					*(pYUVData+i*width*2+j*4+1) = U1;
					*(pYUVData+i*width*2+j*4+2) = Y2;
					*(pYUVData+i*width*2+j*4+3) = V1;
				}
			}	
		}
	}
	return 0;
}

//////////////////////////////////////////////////////////////////////////
// pGBYUV			point to the background YUV data
// pFGYUV			point to the foreground YUV data
// width			width of the picture
// height			height of the picture
// alphaBG			is there an alpha channel in background YUV data
// alphaFG			is there an alpha channel in fourground YUV data
//////////////////////////////////////////////////////////////////////////
int YUVBlending(void* pBGYUV, void* pFGYUV, int width, int height, bool alphaBG, bool alphaFG)
{
	if (NULL == pBGYUV || NULL == pFGYUV)
	{
		return -1;
	}
	unsigned char* pBGData = (unsigned char*)pBGYUV;
	unsigned char* pFGData = (unsigned char*)pFGYUV;
	if (!alphaFG)
	{
		if (!alphaBG)
		{
			memcpy(pBGData, pFGData, width*height*2);
		}
		else
		{
			for (int i=0; i

將轉(zhuǎn)化后數(shù)據(jù)保存。

第二步,將純RGB888轉(zhuǎn)化為BMP文件,

參考http://my.csdn.net/meng_tianshi/code/detail/2092

保存為.c文件

/****************************
      RGB加上頭部信息轉(zhuǎn)換成BMP
    參數(shù)說明:
      rgb_buffer        :RGB數(shù)據(jù)文件中的信息
      nData             :RGB數(shù)據(jù)的長度
      nWidth            :圖像寬度的像素數(shù)
      nHeight           :圖像高度的像素數(shù)
      fp1               :所存放的文件
*****************************/
int RGB2BMP(char *rgb_buffer,int nWidth,int nHeight,FILE*fp1)
{
     BmpHead m_BMPHeader;       
     char bfType[2]={'B','M'};
     m_BMPHeader.imageSize=3*nWidth*nHeight+54;
     m_BMPHeader.blank=0;
     m_BMPHeader.startPosition=54;
 
     fwrite(bfType,1,sizeof(bfType),fp1);
     fwrite(&m_BMPHeader.imageSize,1,sizeof(m_BMPHeader.imageSize),fp1);
     fwrite(&m_BMPHeader.blank,1,sizeof(m_BMPHeader.blank),fp1);
     fwrite(&m_BMPHeader.startPosition,1,sizeof(m_BMPHeader.startPosition),fp1);
        
     InfoHead  m_BMPInfoHeader;
     m_BMPInfoHeader.Length=40;
     m_BMPInfoHeader.width=nWidth;
     m_BMPInfoHeader.height=nHeight;
     m_BMPInfoHeader.colorPlane=1;
     m_BMPInfoHeader.bitColor=24;
     m_BMPInfoHeader.zipFormat=0;
     m_BMPInfoHeader.realSize=3*nWidth*nHeight;
     m_BMPInfoHeader.xPels=0;
     m_BMPInfoHeader.yPels=0;
     m_BMPInfoHeader.colorUse=0;
     m_BMPInfoHeader.colorImportant=0;
 
     fwrite(&m_BMPInfoHeader.Length,1,sizeof(m_BMPInfoHeader.Length),fp1);
     fwrite(&m_BMPInfoHeader.width,1,sizeof(m_BMPInfoHeader.width),fp1);
     fwrite(&m_BMPInfoHeader.height,1,sizeof(m_BMPInfoHeader.height),fp1);
     fwrite(&m_BMPInfoHeader.colorPlane,1,sizeof(m_BMPInfoHeader.colorPlane),fp1);
     fwrite(&m_BMPInfoHeader.bitColor,1,sizeof(m_BMPInfoHeader.bitColor),fp1);
     fwrite(&m_BMPInfoHeader.zipFormat,1,sizeof(m_BMPInfoHeader.zipFormat),fp1);
     fwrite(&m_BMPInfoHeader.realSize,1,sizeof(m_BMPInfoHeader.realSize),fp1);
     fwrite(&m_BMPInfoHeader.xPels,1,sizeof(m_BMPInfoHeader.xPels),fp1);
     fwrite(&m_BMPInfoHeader.yPels,1,sizeof(m_BMPInfoHeader.yPels),fp1);
     fwrite(&m_BMPInfoHeader.colorUse,1,sizeof(m_BMPInfoHeader.colorUse),fp1);
     fwrite(&m_BMPInfoHeader.colorImportant,1,sizeof(m_BMPInfoHeader.colorImportant),fp1);
     fwrite(rgb_buffer,3*nWidth*nHeight,1,fp1);
     return 0;
}
//主函數(shù)
#include 
#include 
#include 
#include "rgb2bmp.h"
int  main()
{
    FILE* p;
/***************  input data  ***********
    filename      :RGB數(shù)據(jù)文件名稱
    nWidth        :所生成文件的水平像素
    nHeight       :所生成文件的垂直像素
    newFile       :最終生成文件的名稱
***********************************************/
        char* filename = "rgb888_800_480_woman";
    int nWidth = 800;
    int nHeight = 480;
    char* newFile = "bmp2s (copy).bmp";
    p = fopen(filename,"rb");
    if (p == NULL)
    {
        printf("!!!file %s open failed.n", filename);
        return 0;
    }
    printf("file %s open success.n",filename);
/***********  read Image Data  **************/
    long nData = nWidth*nHeight*3;
    char* rgb_buffer = malloc(nData*sizeof(char));
    char* pVisit = rgb_buffer;
    fread(rgb_buffer,1,nData,p);
    printf("read file over.nData%ldn",nData);
/***********  write file *******************/
 
    FILE *result = fopen(newFile,"wb");
    if (result == NULL)
    {
       printf("open new file failed.n");
       return -1;
    }
    RGB2BMP(rgb_buffer,nWidth,nHeight,result);
    fclose(result);
    return 0;
}
  

頭文件

//rgb2bmp.h頭文件
#include 
typedef unsigned char  BYTE;
typedef unsigned short WORD;
// BMP圖像各部分說明如下
/***********
    第一部分    位圖文件頭
該結(jié)構(gòu)的長度是固定的,為14個字節(jié),各個域的依次如下:
    2byte   :文件類型,必須是0x4d42,即字符串"BM"。
    4byte   :整個文件大小
    4byte   :保留字,為0
    4byte   :從文件頭到實際的位圖圖像數(shù)據(jù)的偏移字節(jié)數(shù)。
*************/
typedef struct
{    long imageSize;
    long blank;
    long startPosition;
}BmpHead;
/*********************
 
 /*********************
    第二部分    位圖信息頭
該結(jié)構(gòu)的長度也是固定的,為40個字節(jié),各個域的依次說明如下:
    4byte   :本結(jié)構(gòu)的長度,值為40
    4byte   :圖像的寬度是多少象素。
    4byte   :圖像的高度是多少象素。
    2Byte   :必須是1。
    2Byte   :表示顏色時用到的位數(shù),常用的值為1(黑白二色圖)、4(16色圖)、8(256色圖)、24(真彩色圖)。
    4byte   :指定位圖是否壓縮,有效值為BI_RGB,BI_RLE8,BI_RLE4,BI_BITFIELDS。Windows位圖可采用RLE4和RLE8的壓縮格式,BI_RGB表示不壓縮。
    4byte   :指定實際的位圖圖像數(shù)據(jù)占用的字節(jié)數(shù),可用以下的公式計算出來:
圖像數(shù)據(jù) = Width' * Height * 表示每個象素顏色占用的byte數(shù)(即顏色位數(shù)/8,24bit圖為3,256色為1)
  要注意的是:上述公式中的biWidth'必須是4的整數(shù)倍(不是biWidth,而是大于或等于biWidth的最小4的整數(shù)倍)。
   如果biCompression為BI_RGB,則該項可能為0。
    4byte   :目標設(shè)備的水平分辨率。
    4byte   :目標設(shè)備的垂直分辨率。
    4byte   :本圖像實際用到的顏色數(shù),如果該值為0,則用到的顏色數(shù)為2的(顏色位數(shù))次冪,如顏色位數(shù)為8,2^8=256,即256色的位圖
    4byte   :指定本圖像中重要的顏色數(shù),如果該值為0,則認為所有的顏色都是重要的。
***********************************/
 
typedef struct
{
    long    Length;
    long    width;
    long    height;
    WORD    colorPlane;
    WORD    bitColor;
    long    zipFormat;
    long    realSize;
    long    xPels;
    long    yPels;
    long    colorUse;
    long    colorImportant;
}InfoHead;
/***************************
/***************************
    第三部分    調(diào)色盤結(jié)構(gòu)  顏色表
    對于256色BMP位圖,顏色位數(shù)為8,需要2^8 = 256個調(diào)色盤;
    對于24bitBMP位圖,各象素RGB值直接保存在圖像數(shù)據(jù)區(qū),不需要調(diào)色盤,不存在調(diào)色盤區(qū)
    rgbBlue:   該顏色的藍色分量。
    rgbGreen:  該顏色的綠色分量。
    rgbRed:    該顏色的紅色分量。
    rgbReserved:保留值。
************************/
typedef struct
{
         BYTE   rgbBlue;
         BYTE   rgbGreen;
         BYTE   rgbRed;
         BYTE   rgbReserved;
}RGBMixPlate;

gcc編譯后生成可執(zhí)行文件,關(guān)于分辨率及文件名,可自行修改。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多