【OpenCV】【YUV】OpenCV中YUV颜色空间变换到RGB颜色空间的转换公式

OpenCV中YUV颜色空间变换到RGB颜色空间采用的公式如下:

浮点
{ R = 1.164 ( Y − 16 ) + 1.596 ( V − 128 ) G = 1.164 ( Y − 16 ) − 0.813 ( V − 128 ) − 0.391 ( U − 128 ) B = 1.164 ( Y − 16 ) + 2.018 ( U − 128 ) \footnotesize \begin{cases} R=1.164(Y-16)+1.596(V-128) \\ G=1.164(Y-16) -0.813(V-128)-0.391(U-128) \\ B = 1.164(Y-16)+2.018(U-128) \end{cases} R=1.164(Y16)+1.596(V128)G=1.164(Y16)0.813(V128)0.391(U128)B=1.164(Y16)+2.018(U128) 整型:系数整体放大 2 20 2^{20} 220倍,并在变换到原始尺度时加入0.5用于四舍五入
{ R = ( 1220542 ( Y − 16 ) + 1673527 ( V − 128 ) + ( 1 &lt; &lt; 19 ) ) &gt; &gt; 20 G = ( 1220542 ( Y − 16 ) − 852492 ( V − 128 ) − 409993 ( U − 128 ) + ( 1 &lt; &lt; 19 ) ) &gt; &gt; 20 B = ( 1220542 ( Y − 16 ) + 2116026 ( U − 128 ) + ( 1 &lt; &lt; 19 ) ) &gt; &gt; 20 \footnotesize \begin{cases} R=(1220542(Y-16)+1673527(V-128)+(1&lt;&lt;19)) &gt;&gt; 20 \\ G=(1220542(Y-16) -852492(V-128)-409993(U-128)+(1&lt;&lt;19)) &gt;&gt; 20 \\ B =(1220542(Y-16)+2116026(U-128)+(1&lt;&lt;19))&gt;&gt;20 \end{cases} R=(1220542(Y16)+1673527(V128)+(1<<19))>>20G=(1220542(Y16)852492(V128)409993(U128)+(1<<19))>>20B=(1220542(Y16)+2116026(U128)+(1<<19))>>20
O p e n C V \footnotesize OpenCV OpenCV中关键代码如下:
截取自 O p e n C V 2.4.13   i m g p r o c \footnotesize OpenCV 2.4.13 \ imgproc OpenCV2.4.13 imgproc模块的 c o l o r . c p p \footnotesize color.cpp color.cpp文件 Y U V 420 → R G B \footnotesize YUV420 \rightarrow RGB YUV420RGB部分代码,大约为 3042 \footnotesize 3042 3042行左右。

/************************************代码开始********************************************/
const int ITUR_BT_601_CY   = 1220542;
const int ITUR_BT_601_CUB  = 2116026;
const int ITUR_BT_601_CUG  = -409993;
const int ITUR_BT_601_CVG  = -852492;
const int ITUR_BT_601_CVR  = 1673527;
const int ITUR_BT_601_SHIFT = 20;

// u、v值分别先减去128
int u = int(uv[i + 0 + uIdx]) - 128;
int v = int(uv[i + 1 - uIdx]) - 128;

// int ruv=(1<<(20-1))+1673527*v
int ruv = (1 << (ITUR_BT_601_SHIFT - 1)) + ITUR_BT_601_CVR * v;
// int guv=(1<<(20-1))-852492*v-409993*u
int guv = (1 << (ITUR_BT_601_SHIFT - 1)) + ITUR_BT_601_CVG * v + ITUR_BT_601_CUG * u;
// int buv = (1<<(20-1))+2116026*u
int buv = (1 << (ITUR_BT_601_SHIFT - 1)) + ITUR_BT_601_CUB * u;

// 使用(同一组uv、共用同一uv分量的y)根据公式做计算得到 RGB 
int y00 = std::max(0, int(y1[i]) - 16) * ITUR_BT_601_CY;
row1[2-bIdx] = saturate_cast<uchar>((y00 + ruv) >> ITUR_BT_601_SHIFT);  // R
row1[1]      = saturate_cast<uchar>((y00 + guv) >> ITUR_BT_601_SHIFT); // G
row1[bIdx]   = saturate_cast<uchar>((y00 + buv) >> ITUR_BT_601_SHIFT); // B

int y01 = std::max(0, int(y1[i + 1]) - 16) * ITUR_BT_601_CY;
row1[5-bIdx] = saturate_cast<uchar>((y01 + ruv) >> ITUR_BT_601_SHIFT); // R
row1[4]      = saturate_cast<uchar>((y01 + guv) >> ITUR_BT_601_SHIFT); // G
row1[3+bIdx] = saturate_cast<uchar>((y01 + buv) >> ITUR_BT_601_SHIFT); // B

int y10 = std::max(0, int(y2[i]) - 16) * ITUR_BT_601_CY;
row2[2-bIdx] = saturate_cast<uchar>((y10 + ruv) >> ITUR_BT_601_SHIFT);  // R
row2[1]      = saturate_cast<uchar>((y10 + guv) >> ITUR_BT_601_SHIFT); // G
row2[bIdx]   = saturate_cast<uchar>((y10 + buv) >> ITUR_BT_601_SHIFT); // B

int y11 = std::max(0, int(y2[i + 1]) - 16) * ITUR_BT_601_CY;
row2[5-bIdx] = saturate_cast<uchar>((y11 + ruv) >> ITUR_BT_601_SHIFT);  // R
row2[4]      = saturate_cast<uchar>((y11 + guv) >> ITUR_BT_601_SHIFT); // G
row2[3+bIdx] = saturate_cast<uchar>((y11 + buv) >> ITUR_BT_601_SHIFT); // B
/************************************代码结束********************************************/

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值