LBP算法的原理不再介绍,下面只介绍一下使用vivado hls如何实现lbp算法。
首先,需要对输入图像做灰度变换,将rgb图像转为灰度图像。
调用hls中的 hls::AXIvideo2Mat(input1, img_1);函数即可实现,完成图像灰度的转换。
接下来针对灰度图像做lbp变换。
使用hls中的Window和LineBuffer,来对图像进行缓存和窗处理。
typedef hls::Window<X1, X2, unsigned char> X_WINDOW;
typedef hls::LineBuffer<X3 MAX_WIDTH, unsigned char> X_BUFFER;
简单介绍一下LineBuffer,LineBuffer是相当于一个缓存器,会缓X3行,MAX_WIDTH列的数据,
Window是一个窗口,可在LineBuffer中上下左右滑动,针对窗口数据做出处理。
我大概的理解就是这样。
使用LineBuffer缓存3行,MAX_WIDTH列的图像数据,再使用3*3的窗口对窗口数据进行处理。
接下来就是对窗口数据进行处理,3*3的窗口,大于窗口最中间的值为1,小于为0,再按照顺时针对处理后的数据进行编码。
最后返回编码值,存回图像中,一次窗口处理完成后滑动窗向右移动,一行完成后,向下移动。
等待数据处理完成后,再对图像做统计。做256维的统计。
统计函数参考原有hls中的函数hls::EqualizeHist,对其改进,完成统计功能。
相应代码如下:
namespace hls {
template<int SRC_T,int ROW, int COL>
void Equalize_1(
Mat<ROW, COL, SRC_T> &_src,int hist_out[256])
{
ap_uint<8> addr=0;
//int hist_out[256];
ap_uint<BitWidth<ROW*COL>::Value> data[2];
#pragma HLS ARRAY_PARTITION variable= data complete dim=0
for(int i=0;i<256;i++)
hist_out[i]=0;
int cols=_src.cols;
int rows=_src.rows;
assert(rows<=ROW);
assert(cols<=COL);
loop_height: for(int i=0;i<rows;i++)
{
loop_width: for(int j=0;j<cols;j++)
{
#pragma HLS PIPELINE
#pragma HLS LOOP_FLATTEN OFF
HLS_TNAME(SRC_T) tempsrc=0;
_src.data_stream[0].read(tempsrc);
if(!(i==0&&j==0))
{
data[1]=data[0];
data[0]=hist_out[tempsrc];
if(tempsrc==addr)
data[0]++;
hist_out[addr]=data[1]+1;
addr=tempsrc;
}
else
{
addr=tempsrc;
data[0]=hist_out[tempsrc];
}
}
}
hist_out[addr]=data[0]+1;
//array=hist_out;
}
template<int SRC_T,int ROW, int COL>
void EqualizeHist_1(
Mat<ROW, COL, SRC_T> &_src,int array[256])
{
#pragma HLS INLINE
Equalize_1(_src,array);
}
}
将返回值再存入到zynq的BRAM中,最后在ps端读取处理后的256维数据。再做相应识别和分类。