您的位置:首页 > 其它

色彩空间转换

2016-07-27 14:49 429 查看
1. http://blog.csdn.net/yyingwei/article/details/22649575
//以下是yv12到RGB24的转换算法,如果是yuv420到RGB24转换,秩序u,v反过来就可以了。
//即:
// unsigned char* uData = &yData[nYLen];
// unsigned char* vData = &vData[nYLen>>2];
<pre name="code" class="cpp">bool YV12_to_RGB24(unsigned char* pYV12, unsigned char* pRGB24, int iWidth, int iHeight)
{
if(!pYV12 || !pRGB24)
return false;

const long nYLen = long(iHeight * iWidth);
const int nHfWidth = (iWidth>>1);

if(nYLen < 1 || nHfWidth < 1)
return false;

unsigned char* yData = pYV12;
unsigned char* vData = &yData[nYLen];
unsigned char* uData = &vData[nYLen>>2];
if(!uData || !vData)
return false;

int rgb[3];
int i, j, m, n, x, y;
m = -iWidth;
n = -nHfWidth;
for(y = 0; y < iHeight; y++)
{
m += iWidth;

if(!(y % 2))
n += nHfWidth;

for(x=0; x < iWidth; x++)
{
i = m + x;
j = n + (x>>1);
rgb[2] = int(yData[i] + 1.370705 * (vData[j] - 128)); // r分量值
rgb[1] = int(yData[i] - 0.698001 * (uData[j] - 128)  - 0.703125 * (vData[j] - 128)); // g分量值
rgb[0] = int(yData[i] + 1.732446 * (uData[j] - 128)); // b分量值
j = nYLen - iWidth - m + x;
i = (j<<1) + j;
for(j=0; j<3; j++)
{
if(rgb[j]>=0 && rgb[j]<=255)
pRGB24[i + j] = rgb[j];
else
pRGB24[i + j] = (rgb[j] < 0) ? 0 : 255;
}
}
}

return true;
}


2

#include "stdio.h"

#define  ALIGNMENTTO16(size) (((size) + 15) / 16 * 16)
void UYVYtoYV12(unsigned char* UYVYBuffer,
int ImageWidth,
int ImageHeight,
unsigned char* YBuffer,
unsigned char* UBuffer,
unsigned char* VBuffer,
int SrcPitch,
int DstPitch)
{
unsigned char* pDestY = YBuffer;
unsigned char* pDestU = UBuffer;
unsigned char* pDestV = VBuffer;
int i;
int j;

//  For each destination U and V pixel
for (i = 0; i < ImageHeight / 2; ++i)
{
for (j = 0; j < ImageWidth / 2; ++j)
{
int u;
int v;

//  Subsample U
u = UYVYBuffer[j * 4];
u += UYVYBuffer[j * 4 + SrcPitch];
u /= 2;
pDestU[j] = u;

//  Subsample V
v = UYVYBuffer[j * 4 + 2];
v += UYVYBuffer[j * 4 + 2 + SrcPitch];
v /= 2;
pDestV[j] = v;

//  Copy Y
pDestY[j * 2] = UYVYBuffer[j * 4 + 1];
pDestY[j * 2 + 1] = UYVYBuffer[j * 4 + 3];
pDestY[DstPitch + j * 2] = UYVYBuffer[j * 4 + SrcPitch + 1];
pDestY[DstPitch + j * 2 + 1] = UYVYBuffer[j * 4 + SrcPitch + 3];
}

pDestY += DstPitch * 2;  //  Step 2 Y rows
pDestU += DstPitch / 2;  //  Step 1 U row
pDestV += DstPitch / 2;  //  Step 1 V row
UYVYBuffer += SrcPitch * 2;  //  Step 2 source rows
}

return;
}

void YUY2toYV12(unsigned char* YUY2Buffer,
int ImageWidth,
int ImageHeight,
unsigned char* YBuffer,
unsigned char* UBuffer,
unsigned char* VBuffer,
int SrcPitch,
int DstPitch)
{
unsigned char* pDestY = YBuffer;
unsigned char* pDestU = UBuffer;
unsigned char* pDestV = VBuffer;
int i;
int j;

//  For each destination U and V pixel
for (i = 0; i < ImageHeight / 2; ++i)
{
for (j = 0; j < ImageWidth / 2; ++j)
{
int u;
int v;

//  Subsample U
u = YUY2Buffer[j * 4 + 1];
u += YUY2Buffer[j * 4 + 1 + SrcPitch];
u /= 2;
pDestU[j] = u;

//  Subsample V
v = YUY2Buffer[j * 4 + 3];
v += YUY2Buffer[j * 4 + 3 + SrcPitch];
v /= 2;
pDestV[j] = v;

//  Copy Y
pDestY[j * 2] = YUY2Buffer[j * 4];
pDestY[j * 2 + 1] = YUY2Buffer[j * 4 + 2];
pDestY[DstPitch + j * 2] = YUY2Buffer[j * 4 + SrcPitch];
pDestY[DstPitch + j * 2 + 1] = YUY2Buffer[j * 4 + SrcPitch + 2];
}

pDestY += DstPitch * 2;  //  Step 2 Y rows
pDestU += DstPitch / 2;  //  Step 1 U row
pDestV += DstPitch / 2;  //  Step 1 V row
YUY2Buffer += SrcPitch * 2;  //  Step 2 source rows
}

return;
}

void YVYUtoYV12( unsigned char *src,
int ImageWidth,
int ImageHeight,
unsigned char *YBuffer,
unsigned char *UBuffer,
unsigned char *VBuffer,
int SrcPitch,
int DstPitch )
{
int i,j;

unsigned char *YDst=YBuffer;
unsigned char *UDst=UBuffer;
unsigned char *VDst=VBuffer;

// for each destination u and v pixel
for(i=0;i<ImageHeight/2;i++)
{
for(j=0;j<ImageWidth/2;j++)
{
int u,v;

// subsample u
u = src[j*4+3];
u +=src[j*4+3+SrcPitch];
u /= 2;
UDst[j] = u ;

// subsample v
v = src[j*4+1];
v += src[j*4+1+SrcPitch];
v /= 2;
VDst[j] = v;

// calculate the 4 y's
YDst[j*2] = src[j*4];
YDst[j*2+1] = src[j*4+2];
YDst[DstPitch + j*2] = src[j*4+SrcPitch];
YDst[DstPitch + j*2 + 1] = src[j*4+SrcPitch + 2];

}
YDst+=DstPitch*2;   // step 2 y rows
UDst+=DstPitch/2;   // step 1 u row
VDst+=DstPitch/2;   // step 1 v row
src+=SrcPitch*2; // step 2 source rows
}
}

void main()
{
//待转换数据和宽高
LPBYTE SrcBuffer = ?;
int width = ?;
int height = ?;

int YV12BufferSize = ALIGNMENTTO16(width * 3 / 2) * height;
LPBYTE YV12Buffer = new BYTE[YV12BufferSize]();

LPBYTE pY = YV12Buffer;
LPBYTE pV = pY + width * height;
LPBYTE pU = pV + width * height / 4;

int SrcPitch = ALIGNMENTTO16(width) * 2;
int DstPitch = ALIGNMENTTO16(width);

// UYYV to YV12
UYVYtoYV12(SrcBuffer,
width,
height,
pY,
pU,
pV,
SrcPitch,
DstPitch);

// YUV2 to YV12
YUY2toYV12(SrcBuffer,
width,
height,
pY,
pU,
pV,
SrcPitch,
DstPitch);

// YVYU to YV12
YVYUtoYV12(SrcBuffer,
width,
height,
pY,
pU,
pV,
SrcPitch,
DstPitch);

delete YV12Buffer;
}


3

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<height; ++i)
{
for (int j=0; j<width/2; ++j)
{
Y1 = *(pYUVData+i*width*3+j*6);
U1 = *(pYUVData+i*width*3+j*6+1);
Y2 = *(pYUVData+i*width*3+j*6+2);
V1 = *(pYUVData+i*width*3+j*6+3);
alpha1 = *(pYUVData+i*width*3+j*6+4);
alpha2 = *(pYUVData+i*width*3+j*6+5);
C1 = Y1-16;
C2 = Y2-16;
D1 = U1-128;
E1 = V1-128;
R1 = ((298*C1 + 409*E1 + 128)>>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<height; ++i)
{
for (int j=0; j<width/2; ++j)
{
Y1 = *(pYUVData+i*width*2+j*4);
U1 = *(pYUVData+i*width*2+j*4+1);
Y2 = *(pYUVData+i*width*2+j*4+2);
V1 = *(pYUVData+i*width*2+j*4+3);
C1 = Y1-16;
C2 = Y2-16;
D1 = U1-128;
E1 = V1-128;
R1 = ((298*C1 + 409*E1 + 128)>>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<height; ++i)
{
for (int j=0; j<width/2; ++j)
{
Y1 = *(pYUVData+i*width*3+j*4);
U1 = *(pYUVData+i*width*3+j*4+1);
Y2 = *(pYUVData+i*width*3+j*4+2);
V1 = *(pYUVData+i*width*3+j*4+3);
C1 = Y1-16;
C2 = Y2-16;
D1 = U1-128;
E1 = V1-128;
R1 = ((298*C1 + 409*E1 + 128)>>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<height; ++i)
{
for (int j=0; j<width/2; ++j)
{
Y1 = *(pYUVData+i*width*2+j*4);
U1 = *(pYUVData+i*width*2+j*4+1);
Y2 = *(pYUVData+i*width*2+j*4+2);
V1 = *(pYUVData+i*width*2+j*4+3);
C1 = Y1-16;
C2 = Y2-16;
D1 = U1-128;
E1 = V1-128;
R1 = ((298*C1 + 409*E1 + 128)>>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;
}

bool YV12_to_RGB24(unsigned char* pYV12, unsigned char* pRGB24, int iWidth, int iHeight)
{
if(!pYV12 || !pRGB24)
return false;

const long nYLen = long(iHeight * iWidth);
const int nHfWidth = (iWidth>>1);

if(nYLen < 1 || nHfWidth < 1)
return false;

unsigned char* yData = pYV12;
unsigned char* vData = &yData[nYLen];
unsigned char* uData = &vData[nYLen>>2];
if(!uData || !vData)
return false;

int rgb[3];
int i, j, m, n, x, y;
m = -iWidth;
n = -nHfWidth;
for(y = 0; y < iHeight; y++)
{
m += iWidth;

if(!(y % 2))
n += nHfWidth;

for(x=0; x < iWidth; x++)
{
i = m + x;
j = n + (x>>1);
rgb[2] = int(yData[i] + 1.370705 * (vData[j] - 128)); // r分量值
rgb[1] = int(yData[i] - 0.698001 * (uData[j] - 128)  - 0.703125 * (vData[j] - 128)); // g分量值
rgb[0] = int(yData[i] + 1.732446 * (uData[j] - 128)); // b分量值
j = nYLen - iWidth - m + x;
i = (j<<1) + j;
for(j=0; j<3; j++)
{
if(rgb[j]>=0 && rgb[j]<=255)
pRGB24[i + j] = rgb[j];
else
pRGB24[i + j] = (rgb[j] < 0) ? 0 : 255;
}
}
}

return true;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: