1. 程式人生 > >HLS實現bayer to RGB 轉換

HLS實現bayer to RGB 轉換

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);
}