\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
.
1
6
4
(
Y
−
1
6
)
+
1
.
5
9
6
(
V
−
1
2
8
)
G
=
1
.
1
6
4
(
Y
−
1
6
)
−
0
.
8
1
3
(
V
−
1
2
8
)
−
0
.
3
9
1
(
U
−
1
2
8
)
B
=
1
.
1
6
4
(
Y
−
1
6
)
+
2
.
0
1
8
(
U
−
1
2
8
)
整型
:系数整体放大
\footnotesize \begin{cases} R=(1220542(Y-16)+1673527(V-128)+(1<<19)) >> 20 \\ G=(1220542(Y-16) -852492(V-128)-409993(U-128)+(1<<19)) >> 20 \\ B =(1220542(Y-16)+2116026(U-128)+(1<<19))>>20 \end{cases}
⎩
⎨
⎧
R
=
(
1
2
2
0
5
4
2
(
Y
−
1
6
)
+
1
6
7
3
5
2
7
(
V
−
1
2
8
)
+
(
1
<
<
1
9
)
)
>
>
2
0
G
=
(
1
2
2
0
5
4
2
(
Y
−
1
6
)
−
8
5
2
4
9
2
(
V
−
1
2
8
)
−
4
0
9
9
9
3
(
U
−
1
2
8
)
+
(
1
<
<
1
9
)
)
>
>
2
0
B
=
(
1
2
2
0
5
4
2
(
Y
−
1
6
)
+
2
1
1
6
0
2
6
(
U
−
1
2
8
)
+
(
1
<
<
1
9
)
)
>
>
2
0
3
0
4
2
行左右。
/************************************代码开始********************************************/
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
/************************************代码结束********************************************/
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.64(Y−16)+2.018(U−128)\footnotesize \begin{cases}R=1.164(Y-16)+1.596(V-128) \\G=1.164(Y-16) ...
cv::Mat rgbImg(cy, cx,CV_8UC3);
yuvImg.create(cy, cx, CV_8UC4);
memcpy(argbImg.data, data, len);
cv::cvtColor(argbImg, rgbImg, C...
Mat rgb2;
cvtColor(rgb, nv12, COLOR_RGB2YUV_I420);
//imwrite("/home/ubuntu/nv12.yuv",nv12,0);
FILE* f = fopen(".
YUV2RGB格式转换
最近在arm板子上做一个项目,arm板上采集的图像是YUV格式的,在后续的图像处理中需要用到RGB格式的图像。在网上查了很多YUV转RGB的资料,由于每个人得到的YUV的数据排列格式不一样,所以要找到适合自己工程的代码很不容易。其中有两篇博客里的资料对我有很大启发,这里向大家介绍一下。网址如下:
http://blog.csdn.net/drea
一.知识点
1.RGB模式
RGB模式是基于自然界中3种基色光的混合原理,将红(Red)、绿(Green)和蓝(Blue)3中基色按照从0(黑)到255(白色)的亮度值在每个色阶中分配,从而指定其色彩。
3个字节 每个字节8位 表示0-255
黑色(0,0,0);白色(255,255,255);第一个字节B蓝色通道,蓝色为(255,0,0),第...
应用:模拟领域
Y'= 0.299*R' + 0.587*G' + 0.114*B'
U'= -0.147*R' - 0.289*G' + 0.436*B' = 0.492*(B'- Y')
V'= 0.615*R' - 0.
计算机领域,RGB被称为基色分量,组合后能显示的颜色叫做颜色空间,一般取值范围从0-255(2^8,可以显示1600万多种颜色;现在有的显示器为10位位深,即2^10,约可以显示10亿种颜色)
还有一种显示方法即YUV显示法:
只黑白显示时,则只需要拿到Y值就可以了,彩色显示时则需要拿到YUV三个值。
关于写这篇文章的原因:
本人也是摸索了很长时间才弄懂其中的原理,里面涉及的知识点太多了,比如色彩空间,比如Gamma,里面还会涉及到很多的协议,比如BT601 BT709,BT2020,RP177等,一不小心就会写错,然后色彩可能就不准确了,可能偏白偏黑或者偏色
自己也踩过很多坑,然后把这些经验写出来,防止大家踩重复的坑,如果文章有不够严谨的地方,请及时...
因为在作品图像相关的东西,过程中,不可避免会涉及到RGB与YUV的相互转化,同时在模型训练的过程中,有时候,只是训练的Y channel,所以还涉及到提取出channel 最后再合并成 RGB图像的一个问题。
但是呢,在模型训练的时候,用的都是tensor,所以还涉及到从image
到tensor 的过程。
这里只介绍两种方法,一种是 基于BT.601
另一种是使用PIL transforms的那个Image.open().convert(‘YCbCr’)
先看第一种方法:BT601
def rgb2y
在OpenCV中,可以使用cv2.cvtColor()函数来进行YUV422和RGB之间的转换。
假设有一张YUV422格式的图像,可以通过以下代码将其转换为RGB格式:
```python
import cv2
# 加载YUV422格式的图像
yuv_image = cv2.imread('yuv_image.jpg', cv2.IMREAD_UNCHANGED)
# 将YUV422图像转换为RGB图像
rgb_image = cv2.cvtColor(yuv_image, cv2.COLOR_YUV2RGB_Y422)
# 显示RGB图像
cv2.imshow('RGB Image', rgb_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
相反地,如果想将一张RGB格式的图像转换为YUV422格式,可以使用以下代码:
```python
import cv2
# 加载RGB格式的图像
rgb_image = cv2.imread('rgb_image.jpg')
# 将RGB图像转换为YUV422图像
yuv_image = cv2.cvtColor(rgb_image, cv2.COLOR_RGB2YUV_Y422)
# 显示YUV422图像
cv2.imshow('YUV422 Image', yuv_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
在进行YUV422和RGB之间的转换时,需要注意图像的颜色空间和通道顺序。YUV422图像通常具有4:2:2采样率,即每两个像素共享一个U和一个V分量,而RGB图像则没有这种采样率。因此,在进行转换时,需要确保正确的颜色空间和通道顺序,以避免图像质量的损失。