HLS實現bayer to RGB 轉換
阿新 • • 發佈:2019-01-28
unsigned int bayer2rgb(hls::Window<3,3,HLS_TNAME(HLS_8UC1)> &core_win, int i, int j) { unsigned int value,r,g,b; #pragma HLS INLINE if(i%2==1){ // odd row if(j%2==1){ // odd col g=(core_win(1,1)); value=(core_win(0,1)); value += (core_win(2,1)); b=value/2; value=(core_win(1,0)); value += (core_win(1,2)); r=value/2; }else{ // even col r=(core_win(1,1)); value=(core_win(0,1)); value += (core_win(2,1)); value += (core_win(1,0)); value += (core_win(1,2)); g=value/4; value=(core_win(0,0)); value += (core_win(0,2)); value += (core_win(2,0)); value += (core_win(2,2)); b=value/4; } }else{ // even row if(j%2==0){ // even col g=(core_win(1,1)); value=(core_win(0,1)); value += (core_win(2,1)); r=value/2; value=(core_win(1,0)); value += (core_win(1,2)); b=value/2; }else{ // odd col b=(core_win(1,1)); value=(core_win(0,1)); value += (core_win(2,1)); value += (core_win(1,0)); value += (core_win(1,2)); g=value/4; value=(core_win(0,0)); value += (core_win(0,2)); value += (core_win(2,0)); value += (core_win(2,2)); r=value/4; } } return ((b<<16)|(g<<8)|r); } template<int D_HEIGHT, int D_WIDTH, int ROWS, int COLS, int SRC_T,int DST_T> void _filter( hls::Mat<ROWS, COLS, SRC_T> &src, hls::Mat<ROWS, COLS, DST_T> &dst) { HLS_SIZE_T IMG_HEIGHT = src.rows; HLS_SIZE_T IMG_WIDTH = src.cols; hls::Window<D_HEIGHT, D_WIDTH,HLS_TNAME(HLS_8UC1)> src_kernel_win; hls::LineBuffer<D_HEIGHT,MAX_WIDTH,HLS_TNAME(HLS_8UC1)> main_buf; hls::LineBuffer<D_HEIGHT,1,HLS_TNAME(HLS_8UC1)> col_buf; HLS_SIZE_T fillvalue=255; HLS_SIZE_T loophight=IMG_HEIGHT+D_HEIGHT-1; HLS_SIZE_T loopwidth=IMG_WIDTH+D_WIDTH-1; HLS_SIZE_T buf_row=0; HLS_SIZE_T buf_rows,buf_cols; HLS_SIZE_T heightloop= IMG_HEIGHT+D_HEIGHT-1; HLS_SIZE_T widthloop = IMG_WIDTH+D_WIDTH-1;//one pixel overlap, so it should minus one loop_height: for(HLS_SIZE_T i= 0;i< heightloop;i++) { #pragma HLS LOOP_TRIPCOUNT MAX=ROWS loop_width: for (HLS_SIZE_T j= 0;j< widthloop;j++) { #pragma HLS DEPENDENCE array inter false #pragma HLS LOOP_TRIPCOUNT MAX=COLS #pragma HLS LOOP_FLATTEN OFF #pragma HLS PIPELINE II=1 if(j<IMG_WIDTH) { for(HLS_SIZE_T row=0; row<D_HEIGHT; row++){ for(HLS_SIZE_T col=D_WIDTH-1; col>=1; col--) { src_kernel_win(row,col) = src_kernel_win(row,col-1); //column left shift } } { HLS_TNAME(SRC_T) temp; if(i < IMG_HEIGHT) src.data_stream[0] >> temp; else temp=fillvalue; main_buf(0,j)=(temp&0xFF); } for(buf_row=0; buf_row<D_HEIGHT; buf_row++){ // Fetch the column from the line buffer to shift into the window. col_buf(buf_row,0)= main_buf(buf_row,j); } { HLS_TNAME(HLS_8UC1) toppixel=col_buf(D_HEIGHT-1,0); src_kernel_win(D_HEIGHT-1,0)=toppixel; } for(buf_row=D_HEIGHT-1; buf_row>=1; buf_row--){ HLS_TNAME(HLS_8UC1) temp=col_buf(buf_row-1,0); src_kernel_win(buf_row-1,0)=temp; main_buf(buf_row,j)=temp; } } else { for(HLS_SIZE_T row=0; row<D_HEIGHT; row++){ for(HLS_SIZE_T col=D_WIDTH-1; col>=1; col--) { src_kernel_win(row,col) = src_kernel_win(row,col-1); } } for(HLS_SIZE_T row=0; row<D_HEIGHT; row++){ src_kernel_win(row,0)=fillvalue; } } // figure out the output image pixel value if(i >= (D_HEIGHT-1) && j>=(D_WIDTH-1)) { unsigned int temp_out; temp_out = bayer2rgb(src_kernel_win, i, j); dst.data_stream[0] << (temp_out&0xFF); // red dst.data_stream[1] << ((temp_out>>8)&0xFF); // green dst.data_stream[2] << ((temp_out>>16)&0xFF); // blue } }//w }//h } void hls_bayer2rgb( AXI_STREAM &INPUT_STREAM, AXI_STREAM &OUTPUT_STREAM, int rows, int cols) { #pragma HLS INTERFACE axis port=INPUT_STREAM #pragma HLS INTERFACE axis port=OUTPUT_STREAM #pragma HLS INTERFACE s_axilite port=rows bundle=BUS_CTRL #pragma HLS INTERFACE s_axilite port=cols bundle=BUS_CTRL #pragma HLS INTERFACE s_axilite port=return bundle=BUS_CTRL hls::Mat<MAX_HEIGHT,MAX_WIDTH,HLS_8UC3> src(rows,cols); hls::Mat<MAX_HEIGHT,MAX_WIDTH,HLS_8UC3> dst(rows,cols); #pragma HLS dataflow hls::AXIvideo2Mat(INPUT_STREAM, src); _filter<3,3>(src, dst); hls::Mat2AXIvideo(dst, OUTPUT_STREAM); }