首页 技术 正文
技术 2022年11月9日
0 收藏 934 点赞 2,181 浏览 9506 个字

1 YCbCr简介
YCbCr颜色空间是将RGB颜色空间进行坐标转换后得到的,常用于数字电视系统。
Y取值范围:16~235
Cb、Cr的取值范围:16~240
YCbCr经常和YUV混淆。两者的主要差别在于YUV是模拟信号,YCbCr是数字信号。
2YCbCr与RGB的转换公式
因为SDTV(标清视频)和HDTV(高清视频)应用具有不同的色度特征,所以对于RGB和YCbCr之间的转换的公式,分两种情况进行说明:
对于SDTV(包括480i 576i),对应的标准是ITU-R BT.601:

对于HDTV(包括720P 1080i 1080P),对应的标准是ITU BT.709:

3YCbCr转RGB的verilog源码
/*
计算公式:R = 1.164(Y – 16) + 1.793(CR – 128) = 1.164Y + 1.793CR – 248.128;
G = 1.164(Y – 16) – 0.534(CR – 128) – 0.213(CB – 128) = 1.164Y – 0.213CB – 0.534CR + 76.992;
B = 1.164(Y – 16) + 2.115(CB – 128) = 1.164Y + 2.115CB – 289.344;
其中,时序在计算过程中完全没有用到
输入到输出有三个clock的时延。
第一级流水线计算所有乘法;
第二级流水线计算所有加法,把正的和负的分开进行加法;
第三级流水线计算最终的和,若为负数取0;
仿真通过
*/
`timescale 1ns/1ps
moduleycbcr_to_rgb(
inputclk,
inputwire[7 : 0]i_y_8b,
inputwire[7 : 0]i_cb_8b,
inputwire[7 : 0]i_cr_8b,

inputi_h_sync,
inputi_v_sync,
inputi_data_en,

outputwire[7 : 0]o_r_8b,
outputwire[7 : 0]o_g_8b,
outputwire[7 : 0]o_b_8b,

outputrego_h_sync,
outputrego_v_sync,
outputrego_data_en
);

/***************************************parameters*******************************************/
//multiply 256
parameterpara_1164_10b = 10’d297;//1.160
parameterpara_1793_10b = 10’d459;//1.793
parameterpara_0534_10b = 10’d137;//0.535
parameterpara_0213_10b = 10’d54;//0.211
parameterpara_2115_10b = 10’d541;//2.113
parameterpara_248128_18b = 18’d63521;//248.128
parameterpara_76992_18b = 18’d19710; //76.992
parameterpara_289344_18b = 18’d74072;//289.344
/********************************************************************************************/

/***************************************signals**********************************************/
wiresign_r;
wiresign_g;
wiresign_b;
reg[17 : 0]mult_y_for_r_18b;
reg[17 : 0]mult_y_for_g_18b;
reg[17 : 0]mult_y_for_b_18b;

reg[17 : 0]mult_cb_for_g_18b;
reg[17 : 0]mult_cb_for_b_18b;

reg[17 : 0]mult_cr_for_r_18b;
reg[17 : 0]mult_cr_for_g_18b;

reg[17 : 0]add_r_0_18b;
reg[17 : 0]add_g_0_18b;
reg[17 : 0]add_b_0_18b;

reg[17 : 0]add_r_1_18b;
reg[17 : 0]add_g_1_18b;
reg[17 : 0]add_b_1_18b;

reg[17 : 0] result_r_18b;
reg[17 : 0]result_g_18b;
reg[17 : 0]result_b_18b;

regi_h_sync_delay_1;
regi_v_sync_delay_1;
regi_data_en_delay_1;

regi_h_sync_delay_2;
regi_v_sync_delay_2;
regi_data_en_delay_2;

/********************************************************************************************/

/***************************************initial**********************************************/
initial
begin
mult_y_for_r_18b <= 18’d0;
mult_y_for_g_18b <= 18’d0;
mult_y_for_b_18b <= 18’d0;

mult_cb_for_g_18b <= 18’d0;
mult_cb_for_b_18b <= 18’d0;

mult_cr_for_r_18b <= 18’d0;
mult_cr_for_g_18b <= 18’d0;

add_r_0_18b <= 18’d0;
add_g_0_18b <= 18’d0;
add_b_0_18b <= 18’d0;

add_r_1_18b <= 18’d0;
add_g_1_18b <= 18’d0;
add_b_1_18b <= 18’d0;

result_r_18b <= 18’d0;
result_g_18b <= 18’d0;
result_b_18b <= 18’d0;

i_h_sync_delay_1 <= 1’d0;
i_v_sync_delay_1 <= 1’d0;
i_data_en_delay_1 <= 1’d0;

i_h_sync_delay_2 <= 1’d0;
i_v_sync_delay_2 <= 1’d0;
i_data_en_delay_2 <= 1’d0;

o_h_sync <= 1’d0;
o_v_sync <= 1’d0;
o_data_en <= 1’d0;
end
/********************************************************************************************/

/***************************************arithmetic*******************************************/
//LV1 pipeline : mult
always @ (posedgeclk)
begin
mult_y_for_r_18b <= i_y_8b * para_1164_10b;
mult_y_for_g_18b <= i_y_8b * para_1164_10b;
mult_y_for_b_18b <= i_y_8b * para_1164_10b;
end

always @ (posedgeclk)
begin
mult_cb_for_g_18b <= i_cb_8b * para_0213_10b;
mult_cb_for_b_18b <= i_cb_8b * para_2115_10b;
end

always @ (posedgeclk)
begin
mult_cr_for_r_18b <= i_cr_8b * para_1793_10b;
mult_cr_for_g_18b <= i_cr_8b * para_0534_10b;
end
//LV2 pipeline : add
always @ (posedgeclk)
begin
add_r_0_18b <= mult_y_for_r_18b + mult_cr_for_r_18b;
add_r_1_18b <= para_248128_18b;
add_g_0_18b <= mult_y_for_g_18b + para_76992_18b;
add_g_1_18b <= mult_cb_for_g_18b + mult_cr_for_g_18b;
add_b_0_18b <= mult_y_for_b_18b + mult_cb_for_b_18b;
add_b_1_18b <= para_289344_18b;
end
//LV3 pipeline : y + cb + cr
assignsign_r = (add_r_0_18b >= add_r_1_18b);
assignsign_g = (add_g_0_18b >= add_g_1_18b);
assignsign_b = (add_b_0_18b >= add_b_1_18b);
always @ (posedgeclk)
begin
result_r_18b = sign_r ? (add_r_0_18b – add_r_1_18b) : 18’d0;
result_g_18b = sign_g ? (add_g_0_18b – add_g_1_18b) : 18’d0;
result_b_18b = sign_b ? (add_b_0_18b – add_b_1_18b) : 18’d0;
end

//output
assigno_r_8b = (result_r_18b[17:16] == 2’b00) ? result_r_18b[15 : 8] : 8’hff;
assigno_g_8b = (result_g_18b[17:16] == 2’b00) ? result_g_18b[15 : 8] : 8’hff;
assigno_b_8b = (result_b_18b[17:16] == 2’b00) ? result_b_18b[15 : 8] : 8’hff;
/********************************************************************************************/

/***************************************timing***********************************************/
always @ (posedgeclk)
begin
i_h_sync_delay_1 <= i_h_sync;
i_v_sync_delay_1 <= i_v_sync;
i_data_en_delay_1 <= i_data_en;

i_h_sync_delay_2 <= i_h_sync_delay_1;
i_v_sync_delay_2 <= i_v_sync_delay_1;
i_data_en_delay_2 <= i_data_en_delay_1;

o_h_sync <= i_h_sync_delay_2;
o_v_sync <= i_v_sync_delay_2;
o_data_en <= i_data_en_delay_2;
end
/********************************************************************************************/
endmodule
4RGB转YCbCr的verilog源码
/*
计算公式:Y = 0.183R + 0.614G + 0.062B + 16;
CB = -0.101R – 0.338G + 0.439B + 128;
CR = 0.439R – 0.399G – 0.040B + 128;
其中,时序在计算过程中完全没有用到
输入到输出有三个clock的时延。
第一级流水线计算所有乘法;
第二级流水线计算所有加法,把正的和负的分开进行加法;
第三级流水线计算最终的和,若为负数取0;
仿真通过
*/
`timescale 1ns/1ps
modulergb_to_ycbcr(
inputclk,
inputwire[7 : 0]i_r_8b,
inputwire[7 : 0]i_g_8b,
inputwire[7 : 0]i_b_8b,

inputwirei_h_sync,
inputwirei_v_sync,
inputwirei_data_en,
input i_de_vld,

outputwire[7 : 0]o_y_8b,
outputwire[7 : 0]o_cb_8b,
outputwire[7 : 0]o_cr_8b,

outputrego_h_sync,
outputrego_v_sync,
outputrego_data_en,
output reg o_de_vld
);

/***************************************parameters*******************************************/
//multiply 256
parameterpara_0183_10b = 10’d47;
parameterpara_0614_10b = 10’d157;
parameterpara_0062_10b = 10’d16;
parameterpara_0101_10b = 10’d26;
parameterpara_0338_10b = 10’d86;
parameterpara_0439_10b = 10’d112;
parameterpara_0399_10b = 10’d102;
parameterpara_0040_10b = 10’d10;
parameterpara_16_18b = 18’d4096;
parameterpara_128_18b = 18’d32768;
/********************************************************************************************/

/***************************************signals**********************************************/
wiresign_cb;
wiresign_cr;
reg[17: 0]mult_r_for_y_18b;
reg[17: 0]mult_r_for_cb_18b;
reg[17: 0]mult_r_for_cr_18b;

reg[17: 0]mult_g_for_y_18b;
reg[17: 0]mult_g_for_cb_18b;
reg[17: 0]mult_g_for_cr_18b;

reg[17: 0]mult_b_for_y_18b;
reg[17: 0]mult_b_for_cb_18b;
reg[17: 0]mult_b_for_cr_18b;

reg[17: 0]add_y_0_18b;
reg[17: 0]add_cb_0_18b;
reg[17: 0]add_cr_0_18b;

reg[17: 0]add_y_1_18b;
reg[17: 0]add_cb_1_18b;
reg[17: 0]add_cr_1_18b;

reg[17: 0] result_y_18b;
reg[17: 0]result_cb_18b;
reg[17: 0]result_cr_18b;

regi_h_sync_delay_1;
regi_v_sync_delay_1;
regi_data_en_delay_1;
reg i_de_vld_delay_1;

regi_h_sync_delay_2;
regi_v_sync_delay_2;
regi_data_en_delay_2;
reg i_de_vld_delay_2;

/********************************************************************************************/

/***************************************initial**********************************************/
initial
begin
mult_r_for_y_18b <= 18’d0;
mult_r_for_cb_18b <= 18’d0;
mult_r_for_cr_18b <= 18’d0;

mult_g_for_y_18b <= 18’d0;
mult_g_for_cb_18b <= 18’d0;
mult_g_for_cr_18b <= 18’d0;

mult_b_for_y_18b <= 18’d0;
mult_g_for_cb_18b <= 18’d0;
mult_b_for_cr_18b <= 18’d0;

add_y_0_18b <= 18’d0;
add_cb_0_18b <= 18’d0;
add_cr_0_18b <= 18’d0;

add_y_1_18b <= 18’d0;
add_cb_1_18b <= 18’d0;
add_cr_1_18b <= 18’d0;

result_y_18b <= 18’d0;
result_cb_18b <= 18’d0;
result_cr_18b <= 18’d0;

i_h_sync_delay_1 <= 1’d0;
i_v_sync_delay_1 <= 1’d0;
i_data_en_delay_1 <= 1’d0;

i_h_sync_delay_2 <= 1’d0;
i_v_sync_delay_2 <= 1’d0;
i_data_en_delay_2 <= 1’d0;

o_h_sync <= 1’d0;
o_v_sync <= 1’d0;
o_data_en <= 1’d0;
end
/********************************************************************************************/

/***************************************arithmetic*******************************************/
//LV1 pipeline : mult
always @ (posedgeclk)
begin
mult_r_for_y_18b <= i_r_8b * para_0183_10b;
mult_r_for_cb_18b <= i_r_8b * para_0101_10b;
mult_r_for_cr_18b <= i_r_8b * para_0439_10b;
end

always @ (posedgeclk)
begin
mult_g_for_y_18b <= i_g_8b * para_0614_10b;
mult_g_for_cb_18b <= i_g_8b * para_0338_10b;
mult_g_for_cr_18b <= i_g_8b * para_0399_10b;
end

always @ (posedgeclk)
begin
mult_b_for_y_18b <= i_b_8b * para_0062_10b;
mult_b_for_cb_18b <= i_b_8b * para_0439_10b;
mult_b_for_cr_18b <= i_b_8b * para_0040_10b;
end
//LV2 pipeline : add
always @ (posedgeclk)
begin
add_y_0_18b <= mult_r_for_y_18b + mult_g_for_y_18b;
add_y_1_18b <= mult_b_for_y_18b + para_16_18b;

add_cb_0_18b <= mult_b_for_cb_18b + para_128_18b;
add_cb_1_18b <= mult_r_for_cb_18b + mult_g_for_cb_18b;

add_cr_0_18b <= mult_r_for_cr_18b + para_128_18b;
add_cr_1_18b <= mult_g_for_cr_18b + mult_b_for_cr_18b;
end
//LV3 pipeline : y + cb + cr

assignsign_cb = (add_cb_0_18b >= add_cb_1_18b);
assignsign_cr = (add_cr_0_18b >= add_cr_1_18b);
always @ (posedgeclk)
begin
result_y_18b = add_y_0_18b + add_y_1_18b;
result_cb_18b = sign_cb ? (add_cb_0_18b – add_cb_1_18b) : 18’d0;
result_cr_18b = sign_cr ? (add_cr_0_18b – add_cr_1_18b) : 18’d0;
end

//output
assigno_y_8b = (result_y_18b[17:16] == 2’b00) ? result_y_18b[15 : 8] : 8’hFF;
assigno_cb_8b = (result_cb_18b[17:16] == 2’b00) ? result_cb_18b[15 : 8] : 8’hFF;
assigno_cr_8b = (result_cr_18b[17:16] == 2’b00) ? result_cr_18b[15 : 8] : 8’hFF;
/********************************************************************************************/

/***************************************timing***********************************************/
always @ (posedgeclk)
begin
i_h_sync_delay_1 <= i_h_sync;
i_v_sync_delay_1 <= i_v_sync;
i_data_en_delay_1 <= i_data_en;
i_de_vld_delay_1 <=i_de_vld;

i_h_sync_delay_2 <= i_h_sync_delay_1;
i_v_sync_delay_2 <= i_v_sync_delay_1;
i_data_en_delay_2 <= i_data_en_delay_1;
i_de_vld_delay_2 <=i_de_vld_delay_1;

o_h_sync <= i_h_sync_delay_2;
o_v_sync <= i_v_sync_delay_2;
o_data_en <= i_data_en_delay_2;
o_de_vld <= i_de_vld_delay_2;
end
/********************************************************************************************/
endmodule

感谢阅读。转载请注明出处。如有错误之处,请联系donglooloo@163.com   多谢。

参考文档:
1、https://en.wikipedia.org/wiki/YCbCr
2、视频技术手册第五版

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,087
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,562
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,412
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,185
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,821
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,905