使用OpenCV(C++)
代码
// 引用的头文件
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
// 代码重点部分
cv::Mat yuv(height, width, CV_8UC2, p);
cv::Mat img;
cv::cvtColor(yuv, img, cv::COLOR_YUV2BGR_UYVY);
要点讲解
- 关键参数注意替换
- 网上大多数对于YUV格式图片的读取设置为:
(height*3/2, width, CV_8UC1)
, 但YUV格式的图片对三个通道有不同的存储模式。对于UYVY
形式的图片应如上设置。 - 此处
p
为一个int类型的指针,指向图片数据。
Python代码(不使用OpenCV)
代码
import numpy as np
def uyvy2rgb(path, width, height, channels=3):
# 读取文件
img = np.fromfile(file_path, dtype=np.uint8)
# Y, U, V 管道
Y = np.zeros(height * width)
U = np.zeros(height * width)
V = np.zeros(height * width)
index = 0
# 按规律将数据填充进管道中
while 8 * index < len(img):
Y[4*index] = img[8*index+1]
Y[4*index+1] = img[8*index+3]
Y[4*index+2] = img[8*index+5]
Y[4*index+3] = img[8*index+7]
U[4*index] = img[8*index]
U[4*index+1] = img[8*index]
U[4*index+2] = img[8*index+4]
U[4*index+3] = img[8*index+4]
V[4*index] = img[8*index+2]
V[4*index+1] = img[8*index+2]
V[4*index+2] = img[8*index+6]
V[4*index+3] = img[8*index+6]
index += 1
# 转为RGB
R = 1.164 * ( Y - 16 ) + 2.018 * ( U - 128 )
G = 1.164 * ( Y - 16 ) - 0.813 * ( V - 128 ) - 0.391 * ( U - 128 )
B = 1.164 * ( Y - 16 ) + 1.596 * ( V - 128 )
rgb = np.zeros((height, width, channels))
rgb[:, :, 0] = R.reshape((height, width))
rgb[:, :, 1] = G.reshape((height, width))
rgb[:, :, 2] = B.reshape((height, width))
return rgb
if __name__ == '__main__':
file_path = './file.raw'
RGB = uyvy2rgb(file_path, 1280, 720, 3)
要点讲解
-
UYVY的存储规律为
U0 Y0 V0 Y1 U2 Y2 V2 Y3
两个像素共用一组U和V, 即这8个像素值一共构成4组YUV:(Y0, U0, V0), (Y1, U0, V0), (Y2, U2, V2), (Y3, U2, V2). -
YUV转RGB格式有不同的算法,此处用的是:
R = 1.164 ∗ ( Y − 16 ) + 2.018 ∗ ( U − 128 ) G = 1.164 ∗ ( Y − 16 ) − 0.813 ∗ ( V − 128 ) − 0.391 ∗ ( U − 128 ) B = 1.164 ∗ ( Y − 16 ) + 1.596 ∗ ( V − 128 ) \begin{aligned} &R = 1.164 * ( Y - 16 ) + 2.018 * ( U - 128 ) \\ &G = 1.164 * ( Y - 16 ) - 0.813 * ( V - 128 ) - 0.391 * ( U - 128 ) \\ &B = 1.164 * ( Y - 16 ) + 1.596 * ( V - 128 ) \end{aligned} R=1.164∗(Y−16)+2.018∗(U−128)G=1.164∗(Y−16)−0.813∗(V−128)−0.391∗(U−128)B=1.164∗(Y−16)+1.596∗(V−128)