HLS第四十课(xfopencv,常用的imgproc函数)

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

使用低阈值和高阈值进行边缘检测。
+++++++++++++++++++++++++++++++++++++++++++++

猜你喜欢

转载自blog.csdn.net/weixin_42418557/article/details/121245687
今日推荐