数字图像处理(11):RGB转YUV
(1)RGB颜色空间
RGB颜色空间,是一种基于红色、绿色、蓝色三种基本颜色进行混合的颜色空间,通过这三种颜色的叠加,可以产生丰富而广泛的颜色。RGB颜色空间在计算机图像处理、显示器显示、摄影和影视制作等领域具有广泛应用。R、G、B取值通常8bit表示,因此代表三基色的红、绿、蓝通道分别用0~255的整数表示强度,0亮度最低;255亮度最高。(0,0,0)表示黑色,(255,255,255)表示白色。
(2)YUV颜色空间
YUV颜色空间,又常称为YCbCr颜色空间,是用于数字电视的颜色空间,Y表示亮度、U表示蓝色色差(蓝色与绿色的差异),V表示红色色差(红色与蓝白色的差异)。
(3)RGB与YUV的转换公式
(4)matlab实现
% 1. 读取图像
rgb_image = imread('3_1280x720.bmp'); % 或其他图像名称
% 获取屏幕分辨率
screen_size = get(0, 'ScreenSize');
screen_width = screen_size(3);
screen_height = screen_size(4);
% 计算合适的显示尺寸
max_single_width = (screen_width - 200) / 3;
scale = max_single_width / size(rgb_image, 2);
display_width = round(size(rgb_image, 2) * scale);
display_height = round(size(rgb_image, 1) * scale);
% 2. 将RGB图像转换为YUV图像
yuv_image = zeros(size(rgb_image));
R = double(rgb_image(:,:,1));
G = double(rgb_image(:,:,2));
B = double(rgb_image(:,:,3));
% RGB to YUV转换
Y = 0.299*R + 0.587*G + 0.114*B;
U = 0.5*B - 0.169*R - 0.331*G + 128;
V = 0.5*R - 0.419*G - 0.081*B + 128;
yuv_image(:,:,1) = Y;
yuv_image(:,:,2) = U;
yuv_image(:,:,3) = V;
% 3. 将YUV图像转换回RGB图像
Y = double(yuv_image(:,:,1));
U = double(yuv_image(:,:,2));
V = double(yuv_image(:,:,3));
% YUV to RGB转换
R2 = Y + 1.402*(V-128);
G2 = Y - 0.344*(U-128) - 0.714*(V-128);
B2 = Y + 1.772*(U-128);
% 确保RGB值在正确范围内
rgb_image_again = zeros(size(rgb_image), 'uint8');
rgb_image_again(:,:,1) = uint8(min(max(R2, 0), 255));
rgb_image_again(:,:,2) = uint8(min(max(G2, 0), 255));
rgb_image_again(:,:,3) = uint8(min(max(B2, 0), 255));
% 4. 显示图像
% 计算窗口位置
window_spacing = 50;
x_pos1 = round((screen_width - 3*display_width - 2*window_spacing)/2);
x_pos2 = x_pos1 + display_width + window_spacing;
x_pos3 = x_pos2 + display_width + window_spacing;
y_pos = round((screen_height - display_height)/2);
% 显示原始RGB图像
figure('Name', 'RGB Image', 'NumberTitle', 'off');
imshow(imresize(rgb_image, [display_height display_width]));
set(gcf, 'Position', [x_pos1 y_pos display_width display_height]);
% 显示YUV图像
figure('Name', 'YUV Image', 'NumberTitle', 'off');
imshow(uint8(imresize(yuv_image, [display_height display_width])));
set(gcf, 'Position', [x_pos2 y_pos display_width display_height]);
% 显示转换回的RGB图像
figure('Name', 'Converted RGB Image', 'NumberTitle', 'off');
imshow(imresize(rgb_image_again, [display_height display_width]));
set(gcf, 'Position', [x_pos3 y_pos display_width display_height]);
(5)FPGA RGB转YUV代码:
module RGB_YUV
(
input wire [7:0] red ,
input wire [7:0] green ,
input wire [7:0] blue ,
output wire [7:0] Y ,
output wire [7:0] U ,
output wire [7:0] V
);
wire [17:0] Y_w,U_w,V_w;
parameter Y_1 = 18'd306; //0.299*1024
parameter Y_2 = 18'd601; //0.587*1024
parameter Y_3 = 18'd117; //0.114*1024
parameter U_1 = 18'd512; //0.5*1024
parameter U_2 = 18'd173; //0.169*1024
parameter U_3 = 18'd339; //0.331*1024
parameter U_4 = 18'd131072; //128*1024
parameter V_1 = 18'd512; //0.5*1024
parameter V_2 = 18'd429; //0.419*1024
parameter V_3 = 18'd83; //0.081*1024
parameter V_4 = 18'd131072; //128*1024
assign Y_w = Y_1 * red + Y_2 * green + Y_3 * blue;
assign U_w = U_1 * blue - U_2 * red - U_3 * green + U_4;
assign V_w = V_1 * red - U_2 * green - U_3 * blue + U_4;
assign Y = Y_w[17:10];
assign U = U_w[17:10];
assign V = V_w[17:10];
endmodule
(6)仿真及实验现象
使用先前的读写BMP图片的仿真测试工程,添加RGB_YUV模块,观察仿真出来的波形。
module img_process
(
input wire clk ,
input wire reset_n ,
input wire [10:0] img_width ,
input wire [10:0] img_height ,
input wire valid_i ,
input wire [23:0] img_data_i ,
output reg valid_o ,
output reg [23:0] img_data_o
);
wire [7:0] Y_data ;
wire [7:0] U_data ;
wire [7:0] V_data ;
wire [23:0] yuv_data ;
RGB_YUV rgb_yuv_inst
(
.red (img_data_i[23:16]),
.green (img_data_i[15:8]),
.blue (img_data_i[7:0]),
.Y (Y_data),
.U (U_data),
.V (V_data)
);
assign yuv_data = {Y_data,U_data,V_data};
always@(posedge clk or negedge reset_n)
if(!reset_n)begin
valid_o <= 1'd0;
img_data_o <= 24'd0;
end
else begin
valid_o <= valid_i;
img_data_o <= yuv_data;
end
endmodule
上板验证后的波形:与matlab处理和仿真出来的差不多