xfopencv提供了一些常用的算法函数,用于简化程序的编写。
所有的参数配置需要的枚举常量,都定义在 common/xf_params.h中。
+++++++++++++++++++++++++++++++++++++++ imgproc/xf_channel_combine.hpp 实现mono图像合并成为color图像。 有两个可用的模板函数。
template<int SRC_T, int DST_T, int ROWS, int COLS, int NPC=1>
void merge(
xf::Mat<SRC_T, ROWS, COLS, NPC> &_src1,
xf::Mat<SRC_T, ROWS, COLS, NPC> &_src2,
xf::Mat<SRC_T, ROWS, COLS, NPC> &_src3,
xf::Mat<DST_T, ROWS, COLS, NPC> &_dst)
将xfmat对象控制的mono图像,合并成xfmat对象控制的color图像。
template<int ROWS, int COLS, int SRC_T, int DST_T, int NPC>
void xfChannelCombine(
hls::stream< XF_TNAME(SRC_T,NPC) >& _in1,
hls::stream< XF_TNAME(SRC_T,NPC) >& _in2,
hls::stream< XF_TNAME(SRC_T,NPC) >& _in3,
hls::stream< XF_TNAME(DST_T,NPC) >& _out,
uint16_t height,uint16_t width)
将hlstream对象存放的mono图像,合并成hlsstream对象存放的color图像。
注意: src1位于最低位段,src3位于最高位段。
++++++++++++++++++++++++++++++++++++++++++++++++++ imgproc/xf_channel_extract.hpp 实现color图像,抽取出独立的mono图像。
template<int SRC_T, int DST_T, int ROWS, int COLS, int NPC=1>
void extractChannel(
xf::Mat<SRC_T, ROWS, COLS, NPC> & _src_mat,
xf::Mat<DST_T, ROWS, COLS, NPC> & _dst_mat,
uint16_t _channel)
从xfmat对象控制的color图像中,抽取出对应通道的mono图像,用xfmat对象控制。
注意: 通道0对应最低位段,通道2对应最高位段。 如果是四通道图像,通道3对应最高位段。
enum _channel_extract
{
XF_EXTRACT_CH_0, //Used by formats with unknown channel types
XF_EXTRACT_CH_1, //Used by formats with unknown channel types
XF_EXTRACT_CH_2, //Used by formats with unknown channel types
XF_EXTRACT_CH_3, //Used by formats with unknown channel types
XF_EXTRACT_CH_R, //Used to extract the RED channel
XF_EXTRACT_CH_G, //Used to extract the GREEN channel
XF_EXTRACT_CH_B, //Used to extract the BLUE channel
XF_EXTRACT_CH_A, //Used to extract the ALPHA channel
XF_EXTRACT_CH_Y, //Used to extract the LUMA channel
XF_EXTRACT_CH_U, //Used to extract the Cb/U channel
XF_EXTRACT_CH_V //Used to extract the Cr/V/Value channel
};
例如: 我们要把一个color图像分离成3个独立的mono图像,需要duplicate的配合使用。
xf::Mat<TYPE, HEIGHT, WIDTH, NPC> _src1(_src.rows,_src.cols);
xf::Mat<TYPE, HEIGHT, WIDTH, NPC> _src2(_src.rows,_src.cols);
xf::Mat<TYPE, HEIGHT, WIDTH, NPC> _src3(_src.rows,_src.cols);
xf::Mat<TYPE, HEIGHT, WIDTH, NPC> _src4(_src.rows,_src.cols);
#pragma HLS dataflow
xf::duplicateMat<TYPE, HEIGHT, WIDTH, NPC>(_src,_src1,_src2);
xf::duplicateMat<TYPE, HEIGHT, WIDTH, NPC>(_src1,_src3,_src4);
xf::extractChannel<TYPE, HEIGHT, WIDTH,MEMORYMAPPED_ARCH, NPC>(_src2, _dst0,XF_EXTRACT_CH_0);
xf::extractChannel<TYPE, HEIGHT, WIDTH,MEMORYMAPPED_ARCH, NPC>(_src3, _dst1,XF_EXTRACT_CH_1);
xf::extractChannel<TYPE, HEIGHT, WIDTH,MEMORYMAPPED_ARCH, NPC>(_src4, _dst2,XF_EXTRACT_CH_2);
++++++++++++++++++++++++++++++++++++++++++++++++++ imgproc/xf_duplicateimage.hpp 复制一个图像。一进两出。
template<int ROWS, int COLS,int SRC_T, int DEPTH, int NPC, int WORDWIDTH>
void xFDuplicate(
hls::stream< XF_TNAME(SRC_T,NPC) > &_src_mat,
hls::stream< XF_TNAME(SRC_T,NPC) > &_dst1_mat,
hls::stream< XF_TNAME(SRC_T,NPC) > &_dst2_mat,
uint16_t img_height, uint16_t img_width)
将一个hlsstream对象存放的图像,复制为两个hlsstream对象存放的图像。
template<int SRC_T, int ROWS, int COLS,int NPC>
void duplicateMat(
xf::Mat<SRC_T, ROWS, COLS, NPC> & _src,
xf::Mat<SRC_T, ROWS, COLS, NPC> & _dst1,
xf::Mat<SRC_T, ROWS, COLS, NPC> & _dst2)
将一个xfmat对象控制的图像,复制为两个xfmat对象控制的图像。
++++++++++++++++++++++++++++++++++++++++++++++++++ imgproc/xf_crop.hpp 从图像中提取ROI。
template<int SRC_T, int ROWS, int COLS,int ARCH_TYPE=0,int NPC=1>
void crop(
xf::Mat<SRC_T, ROWS, COLS, NPC> & _src_mat,
xf::Mat<SRC_T, ROWS, COLS, NPC> &_dst_mat,
xf::Rect_<unsigned int> &roi)
将ROI几何位置信息,存放在xfrect对象中。 从xfmat对象控制的图像中,抽取出ROI区域的图像,存放到xfmat对象控制的图像中。
enum _ARCH_type
{
XF_STREAM = 0,
XF_MEMORYMAPPED = 1
};
默认是stream模式,如果需要MM模式,需要显式定义。
template<int SRC_T, int ROWS, int COLS,int DEPTH, int NPC, int WORDWIDTH_SRC, int WORDWIDTH_DST, int COLS_TRIP>
void xFcropkernel_stream(
xf::Mat<SRC_T, ROWS, COLS, NPC> & _src_mat,
xf::Mat<SRC_T, ROWS, COLS, NPC> & _dst_mat,
xf::Rect_<unsigned int> &roi,
unsigned short height, unsigned short width)
将ROI几何位置信息,存放在xfrect对象中。 从xfmat对象控制的图像中,抽取出ROI区域的图像,存放到xfmat对象控制的图像中。 按照stream方式获取xfmat,需要指定height,width。 传递给函数的xfmat,需要在定义的位置,施加stream约束给xfmat的data成员数组。
template<int SRC_T, int ROWS, int COLS,int DEPTH, int NPC, int WORDWIDTH_SRC, int WORDWIDTH_DST, int COLS_TRIP>
void xFcropkernel_memorymapped(
xf::Mat<SRC_T, ROWS, COLS, NPC> & _src_mat,
xf::Mat<SRC_T, ROWS, COLS, NPC> & _dst_mat,
xf::Rect_<unsigned int> &roi,
unsigned short height, unsigned short width)
将ROI几何位置信息,存放在xfrect对象中。 从xfmat对象控制的图像中,抽取出ROI区域的图像,存放到xfmat对象控制的图像中。 按照MM方式获取xfmat,需要指定height,width。 传递给函数的xfmat,不能施加stream约束给xfmat的data成员数组。因为是随机寻址访问的。
来看一个抽取3个ROI的例子。
void crop_accel(
xf::Mat<TYPE, HEIGHT, WIDTH, NPC> &_src,
xf::Mat<TYPE, HEIGHT, WIDTH, NPC> _dst[3],
xf::Rect_<unsigned int> roi[3])
{
#if MEMORYMAPPED_ARCH
for(int i=0; i<3; i++)
{
xf::crop<TYPE, HEIGHT, WIDTH,MEMORYMAPPED_ARCH, NPC>(_src, _dst[i],roi[i]);
}
#else
xf::Mat<TYPE, HEIGHT, WIDTH, NPC> _src1(_src.rows,_src.cols);
xf::Mat<TYPE, HEIGHT, WIDTH, NPC> _src2(_src.rows,_src.cols);
xf::Mat<TYPE, HEIGHT, WIDTH, NPC> _src3(_src.rows,_src.cols);
xf::Mat<TYPE, HEIGHT, WIDTH, NPC> _src4(_src.rows,_src.cols);
#pragma HLS dataflow
xf::duplicateMat<TYPE, HEIGHT, WIDTH, NPC>(_src,_src1,_src2);
xf::duplicateMat<TYPE, HEIGHT, WIDTH, NPC>(_src1,_src3,_src4);
xf::crop<TYPE, HEIGHT, WIDTH,MEMORYMAPPED_ARCH, NPC>(_src2, _dst[0],roi[0]);
xf::crop<TYPE, HEIGHT, WIDTH,MEMORYMAPPED_ARCH, NPC>(_src3, _dst[1],roi[1]);
xf::crop<TYPE, HEIGHT, WIDTH,MEMORYMAPPED_ARCH, NPC>(_src4, _dst[2],roi[2]);
#endif
}
如果是MM方式,那么在一个for循环中,反复读取src,从中抽取出ROI即可。 如果是stream方式,则不能反复读取src。所以需要复制src, 第一级,将src复制成src1和src2, 第二级,将src1复制成src3和src4,src1被使用了,不能再被使用。 最后可以使用的,是src2,src3,src4。
+++++++++++++++++++++++++++++++++++++++++++++++ imgproc/xf_demosaicing.hpp 将bayer图像进行CFA处理,生成RGB图像。
template<int BFORMAT, int SRC_T, int DST_T, int ROWS, int COLS, int NPC, bool USE_URAM>
void demosaicing(
xf::Mat<SRC_T, ROWS, COLS, NPC> &src_mat,
xf::Mat<DST_T, ROWS, COLS, NPC> &dst_mat)
将一个xfmat控制的图像,CFA处理后,输出为xfmat控制的对象。 BFORMAT需要设置为如下枚举常量定义的格式。
enum XF_demosaicing
{
XF_BAYER_BG,
XF_BAYER_GB,
XF_BAYER_GR,
XF_BAYER_RG,
};
bayer pattern主要是对于滤镜排布的定义不同,且首像素的颜色不同。 R G R G B G R G R
例如, RG,就是RG/GB, GR,就是GR/BG, GB,就是GB/RG, BG,就是BG/GR. ++++++++++++++++++++++++++++++++++++++++++++++++++ imgproc/xf_paintmask.hpp
template< int SRC_T,int MASK_T, int ROWS, int COLS,int NPC=1>
void paintmask(
xf::Mat<SRC_T, ROWS, COLS, NPC> & _src_mat,
xf::Mat<MASK_T, ROWS, COLS, NPC> & in_mask,
xf::Mat<SRC_T, ROWS, COLS, NPC> & _dst_mat,
unsigned char _color[XF_CHANNELS(SRC_T,NPC)])
用指定的颜色和指定的mask,覆盖源图像的对应像素位置。 +++++++++++++++++++++++++++++++++++++++++++++++ imgproc/xf_reduce.hpp
矩阵降维函数。
template< int REDUCE_OP, int SRC_T,int DST_T, int ROWS, int COLS,int ONE_D_HEIGHT, int ONE_D_WIDTH, int NPC=1>
void reduce(
xf::Mat<SRC_T, ROWS, COLS, NPC> & _src_mat,
xf::Mat<DST_T, ONE_D_HEIGHT, ONE_D_WIDTH, 1> & _dst_mat,
unsigned char dim)
将输入的xfmat对象,降维后,输出为另一个降维的xfmat对象。 REDUCE_OP要是如下枚举常量中的一种。
enum _reduction_op
{
REDUCE_SUM = 0,
REDUCE_AVG = 1,
REDUCE_MAX = 2,
REDUCE_MIN = 3
};
dim为0时,坍缩为行,输出的xfmat将被降维为一行。(最后的xfmat只有默认行号为0的元素),源矩阵中,不同的行中对应相同列号的元素,用来参与坍缩运算,最后只剩下一个对应列号的元素。 dim为1时,坍缩为列,输出的xfmat将被降维为一列。(最后的xfmat只有默认列号为0的元素),源矩阵中,不同的列中对应相同行号的元素,用来参与坍缩运算,最后只剩下一个对应行号的元素。
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ imgproc/xf_resize.hpp 对源图像进行插值后,输出到结果图像。
template<int INTERPOLATION_TYPE, int TYPE, int SRC_ROWS, int SRC_COLS, int DST_ROWS, int DST_COLS, int NPC, int MAX_DOWN_SCALE>
void resize (
xf::Mat<TYPE, SRC_ROWS, SRC_COLS, NPC> & _src,
xf::Mat<TYPE, DST_ROWS, DST_COLS, NPC> & _dst)
INTERPOLATION_TYPE需要是如下枚举常量。 最近邻域双线性插值,双线性插值,或者区域插值。
enum _interpolation_types
{
XF_INTERPOLATION_NN = 0,
XF_INTERPOLATION_BILINEAR = 1,
XF_INTERPOLATION_AREA = 2
};
TYPE是图像类型,可以是XF_8UC1或者XF_8UC3。 MAX_DOWN_SCALE,支持的最大缩尺寸的倍数。
++++++++++++++++++++++++++++++++++++++++++++ imgproc/xf_histogram.hpp
template<int SRC_T,int ROWS, int COLS,int NPC=1>
void calcHist(
xf::Mat<SRC_T, ROWS, COLS, NPC> & _src,
uint32_t *histogram)
对一个图像进行直方统计,将结果输出到一个数组中。 在HLS中,HLS倾向于将指针理解为数组。 在xfopencv中,hist_array是一个二维数组。
uint32_t hist_array[XF_CHANNELS(SRC_T,NPC)][256]={0};
最高维,代表通道号,最低维,代表值对应编号。 所以,如果是XF_8UC1,那么定义hist_array[1][256], 如果是XF_8UC3,那么定义hist_array[3][256],
所以,histogram数组,应该定义为hist_array展平后的等价数组的尺寸。
histogram[(i*256)+j]=hist_array[i][j];
+++++++++++++++++++++++++++++++++++++++++++++++ imgproc/xf_hist_equalize.hpp
template<int SRC_T, int ROWS, int COLS, int NPC = 1>
void equalizeHist(
xf::Mat<SRC_T, ROWS, COLS, NPC> & _src,
xf::Mat<SRC_T, ROWS, COLS, NPC> & _src1,
xf::Mat<SRC_T, ROWS, COLS, NPC> & _dst)
src1是src的duplicate的图像。 函数中,用src作为输入的图像,计算出histogram数组,这个数组,可以施加stream约束, 用src1作为输入的图像,以及输入的histogram这个streamlized array,计算出直方均衡的图像。 所以,这个函数,使用的上一帧的histogram来均衡下一帧。 +++++++++++++++++++++++++++++++++++++++++++++++++++ imgproc/xf_threshold.hpp
template<int THRESHOLD_TYPE, int SRC_T, int ROWS, int COLS,int NPC=1>
void Threshold(
xf::Mat<SRC_T, ROWS, COLS, NPC> & _src_mat,
xf::Mat<SRC_T, ROWS, COLS, NPC> & _dst_mat,
short int thresh,
short int maxval )
THRESHOLD_TYPE需要是如下枚举常量中的一种。
enum _threshold_type
{
XF_THRESHOLD_TYPE_BINARY = 0,
XF_THRESHOLD_TYPE_BINARY_INV = 1,
XF_THRESHOLD_TYPE_TRUNC = 2,
XF_THRESHOLD_TYPE_TOZERO = 3,
XF_THRESHOLD_TYPE_TOZERO_INV = 4,
};
XF_THRESHOLD_TYPE_BINARY---- 如果大于thres,则输出结果为指定的maxval,否则输出为0。 XF_THRESHOLD_TYPE_BINARY_INV---- 如果大于thres,则输出结果为0,否则为指定的maxval。 XF_THRESHOLD_TYPE_TRUNC---- 如果大于thres,则输出结果限幅为thres,否则保持不变。 XF_THRESHOLD_TYPE_TOZERO---- 如果大于thres,则输出结果保持不变,否则输出为0。 XF_THRESHOLD_TYPE_TOZERO_INV---- 如果大于thres,则输出结果为0,否则输出保持不变。
+++++++++++++++++++++++++++++++++++++++++++ imgproc/xf_otsuthreshold.hpp
template<int SRC_T, int ROWS, int COLS,int NPC=1>
void OtsuThreshold(
xf::Mat<SRC_T, ROWS, COLS, NPC> & _src_mat,
uint8_t &_thresh)
计算出otsu阈值。写入thresh句柄所指向的变量中。 该函数配合前面的threshold函数一起使用,进行阈值分割。 所以,还需要配合duplicate函数一起使用。如果图像尺寸很大,则不适合使用stream方式。 所以,otsu分割,适合于MM方式。
+++++++++++++++++++++++++++++++++++++++++++++ imgproc/xf_canny.hpp
template<int FILTER_TYPE,int NORM_TYPE,int SRC_T,int DST_T, int ROWS, int COLS,int NPC,int NPC1,bool USE_URAM=false>
void Canny(
xf::Mat<SRC_T, ROWS, COLS, NPC> & _src_mat,
xf::Mat<DST_T, ROWS, COLS, NPC1> & _dst_mat,
unsigned char _lowthreshold,unsigned char _highthreshold)
FILTER_TYPE需要是如下枚举常量中的一种,
enum _filter_size
{
XF_FILTER_3X3 = 3,
XF_FILTER_5X5 = 5,
XF_FILTER_7X7 = 7
};
NORM_TYPE需要是如下枚举常量中的一种,
enum _normalisation_params
{
XF_L1NORM = 0,
XF_L2NORM = 1
};
使用低阈值和高阈值进行边缘检测。 +++++++++++++++++++++++++++++++++++++++++++++
|