赞
踩
常用的几个xfopencv的H文件和HPP文件的分析与使用。
常用的可综合的通用H文件。
xf_common.h。
common/xf_infra.h
common/xf_structs.h
common/xf_video_core.h
common/xf_video_mem.h
常用的只用于仿真的文件。
common/xf_axi.h
common/xf_sw_utils.h
常用的特定图像处理算法的HPP文件
imgproc/xf_demosaicing.hpp
imgproc/xf_channel_combine.hpp
imgproc/xf_channel_extract.hpp
imgproc/xf_crop.hpp
imgproc/xf_duplicateimage.hpp
imgproc/xf_paintmask.hpp
imgproc/xf_reduce.hpp
imgproc/xf_resize.hpp
imgproc/xf_histogram.hpp
imgproc/xf_hist_equalize.hpp
++++++++++++++++++++++++++++++++++++++
common/xf_infra.h
#include "hls_stream.h"
#include "xf_types.h"
#include "xf_axi_sdata.h"
#include "common/xf_axi_io.h"
它里面包含了如上的多个头文件,所以,由了xf_infra,就不用再包含这些文件了。
hls_stream是用来做axivideo的。
xf_types包含了常用的各种type。
xf_axi_sdata包含了ap_axiu模板类。
common/xf_axi_io包含了各种位操作需要的模板函数。
template<int W,int T,int ROWS, int COLS,int NPC>
int AXIvideo2xfMat(hls::stream< ap_axiu<W,1,1,1> >& AXI_video_strm, xf::Mat<T,ROWS, COLS, NPC>& img)
template<int W, int T, int ROWS, int COLS,int NPC>
int xfMat2AXIvideo(xf::Mat<T,ROWS, COLS,NPC>& img,hls::stream<ap_axiu<W,1,1,1> >& AXI_video_strm)
实现axivideo和xfmat之间的转换。
++++++++++++++++++++++++++++++++++++++++++
common/xf_infra.h----xf_types.h
#include "ap_int.h"
#include "xf_params.h"
包含了ap_int,所以可以使用任意精度整数。
包含了xf_params,所以可以使用枚举常量,类似XF_8UC3,XF_8UP,XF_NPPC1等。
在HLSC++中,扩展了模板结构体的作用,除了可以定义成员变量,还可以定义成员类型。
结构体此时相当于是一个作用域的标识符。
结构体模板中,只能存在成员类型和静态成员常量。
结构体模板没有传入模板形参,而是指定了枚举常量,这是最严格的匹配,只有套用模板时,指定的枚举常量完全匹配,才能套用这个模板。
template<>
struct DataType <XF_8UC3, XF_NPPC1> {
typedef ap_uint<24> name;
typedef ap_uint<24> uname;
typedef ap_uint<8> cname;
typedef unsigned char sname;
typedef unsigned int wname;
static const int bitdepth = 8;
static const int pixelwidth = 24;
static const int pixeldepth = XF_24UP;
static const int wordwidth = XF_24UW;
static const int channel = 3;
};
如果要使用结构体的静态成员常量,则使用域限定操作符。
如果要使用结构体的成员类型,则使用域限定操作符。
#define XF_TNAME(flags,npc)\
typename DataType<flags,npc>::name
定义了一个宏拟类型声明语句,实现类型声明的转换。
#define XF_CHANNELS(flags,npc)\
DataType<flags,npc>::channel
定义了一个宏拟函数,获取静态成员常量的值。
template<>
struct PixelType<XF_8UP> {
typedef ap_uint<8> name;
typedef ap_uint<8> uname;
typedef unsigned char name2;
static const int bitdepth = 8; };
如果要使用结构体的静态成员常量,则使用域限定操作符。
如果要使用结构体的成员类型,则使用域限定操作符。
#define XF_PTNAME(flags)\
typename PixelType<flags>::name
定义了一个宏拟类型声明语句,实现类型声明的转换。
+++++++++++++++++++++++++++++++++++++
common/xf_infra.h----xf_axi_sdata.h
template<int D,int U,int TI,int TD>
struct ap_axiu{
ap_uint<D> data;
ap_uint<(D+7)/8> keep;
ap_uint<(D+7)/8> strb;
ap_uint<U> user;
ap_uint<1> last;
ap_uint<TI> id;
ap_uint<TD> dest;
};
定义了AXIS总线的一次bite,用一个结构体来描述总线的一次bite。
++++++++++++++++++++++++++++++++++++++++++
common/xf_infra.h----common/xf_axi_io.h
由于HLSC++扩展了()操作符,
所以,在HLSC++中,可以用()操作符,做截位操作,类似于verilog的截位。
截位操作符,实现的是一个for循环,在循环中逐位赋值。
template<int W, typename T>
void AXIGetBitFields(ap_uint<W> pix, int start, int w, T& val) {
#pragma HLS inline
assert(start >= 0 && start+w <= W);
val = (T)pix(start+w-1, start);
}
从一个ap_uint整数中,截取一个位向量,这个位向量,也是需要的宽度的ap_uint。
template<int W, typename T>
void AXISetBitFields(ap_uint<W>& pix, int start, int w, T val) {
#pragma HLS inline
assert(start >= 0 && start+w <= W);
pix(start+w-1, start) = val;
}
从一个ap_uint整数中,截取一个位向量并写入,这个位向量,也是需要的宽度的ap_uint。
template<int W, typename T>
void AXIGetBitFields(ap_axiu<W,1,1,1> axi, int start, int w, T& val) {
#pragma HLS inline
AXIGetBitFields(axi.data, start, w, val);
}
从一个AXIS总线的一次bite中,截取一个位向量,这个位向量,也是需要的宽度的ap_uint。
template<int W, typename T>
void AXISetBitFields(ap_axiu<W,1,1,1>& axi, int start, int w, T val) {
#pragma HLS inline
AXISetBitFields(axi.data, start, w, val);
}
从一个AXIS总线的一次bite中,截取一个位向量并写入,这个位向量,也是需要的宽度的ap_uint。
++++++++++++++++++++++++++++++++++++++++++++++++
xf_common.h----common/xf_structs.h
定义了常用的结构体。
template<typename T>
class Point_ {
public:
Point_();
Point_(T _x, T _y);
Point_(const Point_& pt);
~Point_();
T x, y;
};
typedef Point_<int> Point;
定义了Point类。它是模板类point_的具象类型。
如果我们需要定义任意精度,我们需要自己具象化point_,并typedef成我们需要的类型。
template<typename T>
class Size_ {
public:
Size_();
Size_(T _width, T _height);
Size_(const Size_<T>& sz);
Size_(const Point_<T>& pt);
T area();
~Size_();
T width, height;
};
typedef Size_<int> Size;
Size类似于Point的具象化。
template<typename T> class Rect_ { public: Rect_(); Rect_(T _x, T _y, T _width, T _height); Rect_(const Rect_& rect); Rect_(const Point_<T>& pt, const Size_<T>& sz); T area(); Size_<T> size(); Point_<T> tl(); // top-left point(inside); Point_<T> tr(); // top-right point(outside); Point_<T> bl(); // bottom-left point(outside); Point_<T> br(); // bottom-right point(outside); bool bContains(const Point_<T>& pt); ~Rect_(); T x, y, width, height; }; typedef Rect_<int> Rect;
Rect类似于Point的具象化。
template<int N, typename T> class Scalar { public: ... void operator =(T value); Scalar<N, T> operator +(T value); Scalar<N, T> operator +(Scalar<N, T> s); Scalar<N, T> operator -(T value); Scalar<N, T> operator -(Scalar<N, T> s); Scalar<N, T> operator *(T value); Scalar<N, T> operator *(Scalar<N, T> s); Scalar<N, T> operator /(T value); Scalar<N, T> operator /(Scalar<N, T> s); T val[N]; };
定义了模板类Scalar,它的成员是一个一维数组,支持重载的加减乘除运算。
template<int T, int ROWS, int COLS, int NPC> class Mat { public: int rows, cols, size; // actual image size DATATYPE *data ; Mat(int _rows, int _cols); Mat(const Mat&); // copy constructor Mat& operator= (const Mat&); // Assignment operator XF_TNAME(T,NPC) read(int index); void write(int index, XF_TNAME(T,NPC) val); const int channels() const; };
+++++++++++++++++++++++++++++++++++++++++++++
common/xf_video_core.h
typedef struct{ unsigned char R; unsigned char G; unsigned char B; }rgb_8; typedef struct{ unsigned char Y; char U; char V; }yuv444_8; typedef struct{ unsigned char Y; char UV; }yuv422_8; typedef struct{ unsigned char CMY; }bayer_8;
定义了各种视频格式下的一个像素的结构体。
template<typename T> yuv422_8 Scalar_to_yuv422_8(Scalar<2, T> scl) { #pragma HLS inline yuv422_8 pix; pix.Y = (unsigned char)scl.val[0]; pix.UV = (char)scl.val[1]; return pix; } template<typename T> Scalar<2, T> yuv422_8_to_Scalar(yuv422_8 pix) { #pragma HLS inline Scalar<2, T> scl; scl.val[0] = (T)pix.Y; scl.val[1] = (T)pix.UV; return scl; }
定义了YUV422和scalar之间的转换。
template<typename T> rgb_8 Scalar_to_rgb_8(Scalar<3, T> scl) { #pragma HLS inline rgb_8 pix; pix.R = (unsigned char)scl.val[0]; pix.G = (unsigned char)scl.val[1]; pix.B = (unsigned char)scl.val[2]; return pix; } template<typename T> Scalar<3, T> rgb_8_to_Scalar(rgb_8 pix) { #pragma HLS inline Scalar<3, T> scl; scl.val[0] = (T)pix.R; scl.val[1] = (T)pix.G; scl.val[2] = (T)pix.B; return scl; }
定义了RGB444和scalar之间的转换。
注意,这里使用了内联约束,该函数会被HLS在综合时内联处理。
++++++++++++++++++++++++++++++++++++++++++++
common/xf_video_mem.h
template<int ROWS, int COLS, typename T>
class Window {
public:
T& getval(int row, int col);
T& operator ()(int row, int col);
void shift_right();
void insert_right(T value[ROWS]);
T val[ROWS][COLS];
};
定义了window模板类。
template<int ROWS, int COLS, typename T, XF_ramtype_e MEM_TYPE=RAM_S2P_BRAM, int RESHAPE_FACTOR=1>
class LineBuffer {
public:
T& getval(int row, int col);
T& operator ()(int row, int col);
void shift_down(int col);
void insert_bottom(T value, int col);
T val[ROWS][COLS];
};
定义了linebuffer的模板类。
+++++++++++++++++++++++++++++++++++++++++++
common/xf_axi.h
这些函数用于CSIM。
template<int W,int NPC>
void IplImage2AXIvideoxf(IplImage* img, hls::stream<ap_axiu<W,1,1,1> >& AXI_video_strm)
template<int W,int NPC>
void AXIvideo2IplImagexf(hls::stream<ap_axiu<W,1,1,1> >& AXI_video_strm, IplImage* img)
实现axivideo和IplImage之间的转换。
template<int W,int NPC>
void cvMat2AXIvideoxf(cv::Mat& cv_mat, hls::stream<ap_axiu<W,1,1,1> >& AXI_video_strm);
template<int W>
void AXIvideo2cvMatxf(hls::stream<ap_axiu<W,1,1,1> >& AXI_video_strm, cv::Mat& cv_mat);
实现axivideo和cvmat之间的转换。
template<int NPC,int W>
void AXIvideo2cvMatxf(hls::stream<ap_axiu<W,1,1,1> >& AXI_video_strm, cv::Mat& cv_mat) {
IplImage img = cv_mat;
AXIvideo2IplImagexf<W,NPC>(AXI_video_strm, &img);
}
template<int NPC,int W>
void cvMat2AXIvideoxf(cv::Mat& cv_mat, hls::stream<ap_axiu<W,1,1,1> >& AXI_video_strm) {
IplImage img = cv_mat;
IplImage2AXIvideoxf<W,NPC>(&img, AXI_video_strm);
}
实际上我们可以看出,本质上,还是axivideo和IplImage之间完成的转换,
然后,简单的通过对象赋值,使得cvmat和IplImage,关联同一个实例图像。
++++++++++++++++++++++++++++++++++++++++++++++
common/xf_sw_utils.h
这些函数用于CSIM。
template <int _PTYPE, int _ROWS, int _COLS, int _NPC>
xf::Mat<_PTYPE, _ROWS, _COLS, _NPC> imread(char *img, int type)
用于从FILE中读取图像,存为xfmat对象。
type为0,表示是8bit gray模式,只读取原图的channel1的数据。
type为1,表示是color模式,不管原图是否是彩色,将原图颜色读取后,转存为彩色图像。
type为4,表示是any color模式。不管原图是什么颜色,转换成4通道彩色图像。
type为2,表示是any depth模式,原图的深度可以不是8,可以是10或者12。
type为-1,表示8bit normal模式,原图是什么颜色,就保持什么颜色。
实质是调用了cvimread函数。
template <int _PTYPE, int _ROWS, int _COLS, int _NPC>
void imwrite(const char *str, xf::Mat<_PTYPE, _ROWS, _COLS, _NPC> &output)
用于将一个xfmat对象存为FILE。实质上是调用了cvimwrite函数。
template <int _PTYPE, int _ROWS, int _COLS, int _NPC>
void absDiff(cv::Mat &cv_img, xf::Mat<_PTYPE, _ROWS, _COLS, _NPC>& xf_img, cv::Mat &diff_img )
void analyzeDiff(cv::Mat &diff_img, int err_thresh, float &err_per)
用于求出xfmat和cvmat之间的差异,并分析误差程度。
++++++++++++++++++++++++++++++++++++++++++++++++++
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。