一、RGB转GRAY的常用方式
1.BT.601标准--标清模式
Gray = 0.299 × R + 0.587 × G + 0.114 × B
2.BT.709标准--高清模式
Gray = 0.2126 × R + 0.7152 × G + 0.0722 × B
3.粗略计算
Gray = (R + G + B) / 3
二、FPGA实现
为了节约资源,避免浮点运算,使用浮点数定点化设计
6位精度(推荐用于 FPGA/嵌入式)
Gray = (R × 19595 + G × 38469 + B × 7472) >> 16
精度高,误差小 。
7位精度(速度与精度平衡)
Gray = (R × 38 + G × 75 + B × 15) >> 7
适合资源受限环境 。
2位精度(仅用于实时预览或游戏)
Gray = (R + (G << 1) + B) >> 2
三、代码实现
1.直接使用浮点数来实现
void rgb2gray(hls::stream<ap_axiu<24,1,1,1> > &in_stream,
hls::stream<ap_axiu<8,1,1,1> > &out_stream) {
#pragma HLS INTERFACE axis port=in_stream
#pragma HLS INTERFACE axis port=out_stream
ap_axiu<8,1,1,1> pixel;
while(!in_stream.empty()) {
#pragma HLS PIPELINE II=1
auto rgb = in_stream.read();
uint8_t gray = (rgb.data >> 16) * 0.299 +
((rgb.data >> 8) & 0xFF) * 0.587 +
(rgb.data & 0xFF) * 0.114;
pixel.data = gray;
out_stream.write(pixel);
}
}
2.定点计算
定点化设计一
void rgb2gray(hls::stream<ap_axiu<24,1,1,1> > &in_stream,
hls::stream<ap_axiu<8,1,1,1> > &out_stream) {
#pragma HLS INTERFACE axis port=in_stream
#pragma HLS INTERFACE axis port=out_stream
ap_axiu<8,1,1,1> pixel;
while(!in_stream.empty()) {
#pragma HLS LOOP_TRIPCOUNT min=0 max=0 avg=0
#pragma HLS PIPELINE II=1
ap_axiu<24,1,1,1> rgb = in_stream.read();
ap_uint<8> gray = ap_fixed<32,16>(rgb.data(23,16)) * ap_fixed<32,16>(0.299f) +
ap_fixed<32,16>(rgb.data(15,8)) * ap_fixed<32,16>(0.587f) +
ap_fixed<32,16>(rgb.data(7,0)) * ap_fixed<32,16>(0.114f);
pixel.data = gray;
out_stream.write(pixel);
}
}
定点化设计二
void rgb2gray(hls::stream<ap_axiu<24,1,1,1> > &in_stream,
hls::stream<ap_axiu<8,1,1,1> > &out_stream) {
#pragma HLS INTERFACE axis port=in_stream
#pragma HLS INTERFACE axis port=out_stream
ap_axiu<8,1,1,1> pixel;
while(!in_stream.empty()) {
#pragma HLS LOOP_TRIPCOUNT min=0 max=0 avg=0
#pragma HLS PIPELINE II=1
ap_axiu<24,1,1,1> rgb = in_stream.read();
ap_uint<8> gray1 = ap_fixed<32,16>(rgb.data(23,16)) * ap_fixed<32,16>(0.299f);
ap_uint<8> gray2 = ap_fixed<32,16>(rgb.data(15,8)) * ap_fixed<32,16>(0.587f);
ap_uint<8> gray3 = ap_fixed<32,16>(rgb.data(7,0)) * ap_fixed<32,16>(0.114f);
ap_uint<8> gray = gray1 + gray2 + gray3;
pixel.data = gray;
out_stream.write(pixel);
}
}
定点化设计三:
void rgb2gray(hls::stream<ap_axiu<24,1,1,1> > &in_stream,
hls::stream<ap_axiu<8,1,1,1> > &out_stream) {
#pragma HLS INTERFACE axis port=in_stream
#pragma HLS INTERFACE axis port=out_stream
ap_axiu<8,1,1,1> pixel;
ap_uint<16> i = 0;
//while(i < 2000) {
while(!in_stream.empty()){
//#pragma HLS LATENCY min=5 max=5
#pragma HLS LOOP_TRIPCOUNT min=0 max=0 avg=0
#pragma HLS PIPELINE II=1
ap_axiu<24,1,1,1> rgb = in_stream.read();
ap_uint<8> gray1 = ap_fixed<24,8>(rgb.data(23,16)) * ap_fixed<24,8>(0.299f);
ap_uint<8> gray2 = ap_fixed<24,8>(rgb.data(15,8)) * ap_fixed<24,8>(0.587f);
ap_uint<8> gray3 = ap_fixed<24,8>(rgb.data(7,0)) * ap_fixed<24,8>(0.114f);
ap_uint<8> gray = gray1 + gray2 + gray3;
pixel.data = gray;
out_stream.write(pixel);
// i++;
}
}