颜色空间转换

#include "stdafx.h"


#include "utils.h"


void NV212RGB(unsigned char *inputImageSource,unsigned char *inputRGBimage, int width,int height, int channel,int widthEdge)
{
int i = 0, j = 0;
int widthStep = width * channel;
int edgeWidthStep = widthEdge * channel;
int grayImageSize = widthEdge * height;
unsigned char *pCurSrcY = NULL;
unsigned char *pCurSrcUV = NULL;
unsigned char *pCurSrcRowY = NULL;
unsigned char *pCurSrcRowUV = NULL;
unsigned char *pCurDst = NULL;
unsigned char *pRowDst = NULL;


unsigned char R = 0;
unsigned char G = 0;
unsigned char B = 0;
unsigned char Y = 0;
unsigned char U = 0;
unsigned char V = 0;
unsigned char cb = 0, cr = 0;


pCurSrcY = inputImageSource;
pCurSrcRowY = pCurSrcY;
pCurSrcUV = inputImageSource + grayImageSize;
pCurSrcRowUV = pCurSrcUV;


pCurDst = inputRGBimage;
pRowDst = pCurDst;
for(i = 0; i < height;pRowDst += widthStep, pCurSrcRowY += widthEdge, pCurSrcRowUV += (i%2) * widthEdge, ++i)
{
pCurDst = pRowDst;
pCurSrcY = pCurSrcRowY;
pCurSrcUV = pCurSrcRowUV;
for( j = 0; j < width;  pCurDst += channel,++pCurSrcY,pCurSrcUV+=(j%2) * 2, ++j)
{
Y = pCurSrcY[0];
cb = pCurSrcUV[0];
cr = pCurSrcUV[1];

int temp = (int)(1.164 * Y + 1.596 * cr - 222.912 + 0.5);
if(temp < 0)
temp = 0;
if(temp > 255)
temp = 255;
R = (unsigned char)temp;


temp = (int)(1.164 * Y - 0.391 * cb - 0.813 * cr + 135.488 + 0.5);
if(temp < 0)
temp = 0;
if(temp > 255)
temp = 255;
G = (unsigned char)temp;


temp = (int)(1.164 * Y + 2.018 * cb - 276.928 + 0.5);
if(temp < 0)
temp = 0;
if(temp > 255)
temp = 255;
B = (unsigned char)temp;


pCurDst[0] = B;
pCurDst[1] = G;
pCurDst[2] = R;
}
}
}

void RGB2NV21(unsigned char *YUV420Image,unsigned char *RGBimage, int width,int height, int channel)
{
int i = 0, j = 0;
int widthStep = width * channel;
int grayImageSize = width * height;
unsigned char *pCurDstY = NULL;
unsigned char *pCurDstUV = NULL;
unsigned char *pCurDstRowY = NULL;
unsigned char *pCurDstRowUV = NULL;


unsigned char *pCurSrcRGB = NULL;
unsigned char *pRowSrcRGB = NULL;


unsigned char R = 0;
unsigned char G = 0;
unsigned char B = 0;
unsigned char Y = 0;
unsigned char U = 0;
unsigned char V = 0;
unsigned char cb = 0, cr = 0;


pCurDstY = YUV420Image;
pCurDstRowY = pCurDstY;
pCurDstUV = YUV420Image + grayImageSize;
pCurDstRowUV = pCurDstUV;


pCurSrcRGB = RGBimage;
pRowSrcRGB = pCurSrcRGB;
for(i = 0; i < height;pRowSrcRGB += widthStep, pCurDstRowY += width, pCurDstRowUV += (i%2) * width, ++i)
{
pCurSrcRGB = pRowSrcRGB;
pCurDstY = pCurDstRowY;
pCurDstUV = pCurDstRowUV;
for( j = 0; j < width;  pCurSrcRGB += channel,++pCurDstY,pCurDstUV+=(j%2) * 2, ++j)
{
B = pCurSrcRGB[0];
G = pCurSrcRGB[1];
R = pCurSrcRGB[2];
//Y   = 0.257*R+0.564*G+0.098*B+16
//Cb = -0.148*R-0.291*G+0.439*B+128
//Cr  = 0.439*R-0.368*G-0.071*B+128

int temp = (int)(0.257 * R + 0.564 * G + 0.098 * B + 16);
pCurDstY[0] = (unsigned char)temp;


temp = (int)(-0.148 * R - 0.291 * G + 0.439 * B + 128);
pCurDstUV[0] = (unsigned char)temp;


temp = (int)(0.439 * R - 0.368 * G - 0.071 * B + 128);
pCurDstUV[1] = (unsigned char)temp;
}
}
#if 0
/**/
FILE *fp = fopen("YUVIMAGE.dat","w+");
unsigned int imageSize = width * height*3/2;
fwrite(YUV420Image,1,imageSize, fp);
fclose(fp);
#endif
}


/*
The coefficients are multiplied bu 2^14.
*/
#define GET_YC(r, g, b, sh) (((4209 * (int)r + 8264 * (int)g + 1605 * (int)b + 8192) >> 14) + (int)sh)
#define GET_CB(r, g, b, sh) (((-2425 * (int)r - 4767 * (int)g + 7143 * (int)b + 8192) >> 14) + (int)sh)
#define GET_CR(r, g, b, sh) (((7193 * (int)r - 6029 * (int)g - 1163 * (int)b + 8192) >> 14) + (int)sh)


MULTISENSOR_API void rgb2YCbCr(unsigned char * pRGB, unsigned char * pYCbCr, const int iWidth, const int iHeight, const int iChannel, const int iWidthStep)
{
unsigned char * pSrc, * pDest;
register int r, g, b;


int i, j;


for(i = iHeight; i > 0; i--, pRGB += iWidthStep, pYCbCr += iWidthStep)
{
pSrc = pRGB;
pDest = pYCbCr;
for(j = iWidth; j > 0; j--, pSrc += iChannel, pDest += iChannel)
{
r = (int)pSrc[2];
g = (int)pSrc[1];
b = (int)pSrc[0];
pDest[0] = (unsigned char)GET_YC(r, g, b, 16);
pDest[1] = (unsigned char)GET_CB(r, g, b, 128);
pDest[2] = (unsigned char)GET_CR(r, g, b, 128);
}
}
}


#define GET_YC_CONT(yc) (19071 * (int)(yc))
#define GET_R(yc_cont, cr) ((yc_cont + 26149 * (int)(cr) + 8192) >> 14)
#define GET_G(yc_cont, cb, cr) ((yc_cont - 6423 * (int)(cb) - 13320 * (int)(cr) + 8192) >> 14)
#define GET_B(yc_cont, cb) ((yc_cont + 33047 * (int)(cb) + 8192) >> 14)
MULTISENSOR_API void yCbCr2Rgb(unsigned char * pYCbCr, unsigned char * pRGB, const int iWidth, const int iHeight, const int iChannel, const int iWidthStep)
{
int ycCont, cb, cr;
unsigned char * pSrc, * pDest;


int i, j;


for(i = iHeight; i > 0; i--, pRGB += iWidthStep, pYCbCr += iWidthStep)
{
pSrc = pYCbCr;
pDest = pRGB;
for(j = iWidth; j > 0; j--, pSrc += iChannel, pDest += iChannel)
{
ycCont = (int)GET_YC_CONT(pSrc[0] - 16);
cb = (int)pSrc[1] - 128;
cr = (int)pSrc[2] - 128;
pDest[2] = clip256(GET_R(ycCont, cr));
pDest[1] = clip256(GET_G(ycCont, cb, cr));
pDest[0] = clip256(GET_B(ycCont, cb));
}
}
}


#define GET_Y(r, g, b) ((4899 * (int)(r) + 9617 * (int)(g) + 1868 * (int)(b)) >> 14)


MULTISENSOR_API void getImageGrey(unsigned char * pRGB, unsigned char * pGrey, const int iWidth, const int iHeight, const int iChannel, const int iWidthStep, const int iOutWidthStep)
{
unsigned char * pSrc, * pDest;


int i, j;


for(i = iHeight; i > 0; i--, pRGB += iWidthStep, pGrey += iOutWidthStep)
{
pSrc = pRGB;
pDest = pGrey;
for(j = iWidth; j > 0; j--, pSrc += iChannel, pDest++)
{
pDest[0] = (unsigned char)GET_Y(pSrc[2], pSrc[1], pSrc[0]);
}
}
}


inline short clipValue(const int iValue, const short iUpLimit)
{
if(iValue < 0)
return 0;
else if(iValue > (int)iUpLimit)
return iUpLimit;
else
return (short)iValue;
}


MULTISENSOR_API void rgb2YCbCr16(short * pRGB, short * pYCbCr, const int iBitPerSample, const int iWidth, const int iHeight, const int iChannel, const int iWidthStep)
{
short * pSrc, * pDest;
int iYcSh, iCSh;
register int r, g, b;


int i, j;


if(iBitPerSample < 8)
return ;
iYcSh = 16 << (iBitPerSample - 8);
iCSh = 128 << (iBitPerSample - 8);


for(i = iHeight; i > 0; i--, pRGB += iWidthStep, pYCbCr += iWidthStep)
{
pSrc = pRGB;
pDest = pYCbCr;
for(j = iWidth; j > 0; j--, pSrc += iChannel, pDest += iChannel)
{
r = (int)pSrc[2];
g = (int)pSrc[1];
b = (int)pSrc[0];
pDest[0] = (short)GET_YC(r, g, b, iYcSh);
pDest[1] = (short)GET_CB(r, g, b, iCSh);
pDest[2] = (short)GET_CR(r, g, b, iCSh);
}
}
}


MULTISENSOR_API void yCbCr2Rgb16(short * pYCbCr, short * pRGB, const int iBitPerSample, const int iWidth, const int iHeight, const int iChannel, const int iWidthStep)
{
int ycCont, cb, cr;
short * pSrc, * pDest;
int iYcSh, iCSh, iUpLimit;


int i, j;


if(iBitPerSample < 8)
return ;
iYcSh = 16 << (iBitPerSample - 8);
iCSh = 128 << (iBitPerSample - 8);
iUpLimit = (1 << iBitPerSample) - 1;


for(i = iHeight; i > 0; i--, pRGB += iWidthStep, pYCbCr += iWidthStep)
{
pSrc = pYCbCr;
pDest = pRGB;
for(j = iWidth; j > 0; j--, pSrc += iChannel, pDest += iChannel)
{
ycCont = (int)GET_YC_CONT(pSrc[0] - iYcSh);
cb = (int)pSrc[1] - iCSh;
cr = (int)pSrc[2] - iCSh;
pDest[2] = clipValue(GET_R(ycCont, cr), iUpLimit);
pDest[1] = clipValue(GET_G(ycCont, cb, cr), iUpLimit);
pDest[0] = clipValue(GET_B(ycCont, cb), iUpLimit);
}
}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值