xF::Mat Image Container Class

xF::Mat is a template class that serves as a container for storing image data and its attributes.

Note: The xF::Mat image container class is similar to the cv::Mat class of the OpenCV library.

Class Definition

template<int TYPE, int ROWS, int COLS, int NPC>
class Mat {
public:
	Mat();                         // default constructor
	Mat(int _rows, int _cols);
       Mat(int _rows, int _cols, void *_data);
	Mat(int _size, int _rows, int _cols);
	~Mat();
	void init(int _rows, int _cols);
	void copyTo(XF_PTSNAME(T,NPC)* fromData);
	XF_PTSNAME(T,NPC)* copyFrom();
	int rows, cols, size;               // actual image size
#ifndef __SYNTHESIS__
	XF_TNAME(T,NPC)*data;
#else
	XF_TNAME(T,NPC) data[ROWS*(COLS>> (XF_BITSHIFT(NPC)))];
#endif
};

Parameter Descriptions

The following table lists the xF::Mat class parameters and their descriptions:

Table 1. xF::Mat Class Parameter Descriptions
Parameter Description
rows The number of rows in the image or height of the image.
cols The number of columns in the image or width of the image.
size The number of words stored in the data member. The value is calculated using rows*cols/(number of pixels packed per word).
*data The pointer to the words that store the pixels of the image.

Member Functions Description

The following table lists the member functions and their descriptions:

Table 2. xF::Mat Member Function Descriptions
Member Functions Description
Mat() This default constructor initializes the Mat object sizes, using the template parameters ROWS and COLS.
Mat(int _rows, int _cols) This constructor initializes the Mat object using arguments _rows and _cols.
Mat(int _rows, int _cols, void *_data) This constructor initializes the Mat object using arguments _rows, _cols, and _data. The *data member of the Mat object points to the memory allocated for _data argument, when this constructor is used. No new memory is allocated for the *data member.
copyTo(* fromData) Copies the data from Data pointer into physically contiguous memory allocated inside the constructor.
copyFrom() Returns the pointer to the first location of the *data member.
~Mat() This is a default destructor of the Mat object.

Template Parameter Descriptions

Template parameters of the xF::Mat class are used to set the depth of the pixel, number of channels in the image, number of pixels packed per word, maximum number of rows and columns of the image. The following table lists the template parameters and their descriptions:

Table 3. xF::Mat Template Parameter Descriptions
Parameters Description
TYPE Type of the pixel data. For example, XF_8UC1 stands for 8-bit unsigned and one channel pixel. More types can be found in includes/common/xf_params.h.
HEIGHT Maximum height of an image.
WIDTH Maximum width of an image.
NPC The number of pixels to be packed per word. For instance, XF_NPPC1 for 1 pixel per word; and XF_NPPC8 for 8 pixels per word.

Pixel-Level Parallelism

The amount of parallelism to be implemented in a function from xfOpenCV is kept as a configurable parameter. In most functions, there are two options for processing data.

  • Single-pixel processing
  • Processing eight pixels in parallel

The following table describes the options available for specifying the level of parallelism required in a particular function:

Table 4. Options Available for Specifying the Level of Parallelism
Option Description
XF_NPPC1 Process 1 pixel per clock cycle
XF_NPPC2 Process 2 pixels per clock cycle
XF_NPPC8 Process 8 pixels per clock cycle

Macros to Work With Parallelism

There are two macros that are defined to work with parallelism.

  • The XF_NPIXPERCYCLE(flags) macro resolves to the number of pixels processed per cycle.
    • XF_NPIXPERCYCLE(XF_NPPC1) resolves to 1
    • XF_NPIXPERCYCLE(XF_NPPC2) resolves to 2
    • XF_NPIXPERCYCLE(XF_NPPC8) resolves to 8
  • The XF_BITSHIFT(flags) macro resolves to the number of times to shift the image size to right to arrive at the final data transfer size for parallel processing.
    • XF_BITSHIFT(XF_NPPC1) resolves to 0
    • XF_BITSHIFT(XF_NPPC2) resolves to 1
    • XF_BITSHIFT(XF_NPPC8) resolves to 3

Pixel Types

Parameter types will differ, depending on the combination of the depth of pixels and the number of channels in the image. The generic nomenclature of the parameter is listed below.
XF_<Number of bits per pixel><signed (S) or unsigned (U) or float (F)>C<number of channels>

For example, for an 8-bit pixel - unsigned - 1 channel the data type is XF_8UC1.

The following table lists the available data types for the xF::Mat class:

Table 5. xf::Mat Class - Available Data Types
Option Number of bits per Pixel Unsigned/ Signed/ Float Type Number of Channels
XF_8UC1 8 Unsigned 1
XF_16UC1 16 Unsigned 1
XF_16SC1 16 Signed 1
XF_32UC1 32 Unsigned 1
XF_32FC1 32 Float 1
XF_32SC1 32 Signed 1
XF_8UC2 8 Unsigned 2
XF_8UC4 8 Unsigned 4
XF_2UC1 2 Unsigned 1

Manipulating Data Type

Based on the number of pixels to process per clock cycle and the type parameter, there are different possible data types. The xfOpenCV library uses these datatypes for internal processing and inside the xF::Mat class. The following are a few supported types:

  • XF_TNAME(TYPE,NPPC) resolves to the data type of the data member of the xF::Mat object. For instance, XF_TNAME(XF_8UC1,XF_NPPC8) resolves to ap_uint<64>.
  • Word width = pixel depth * number of channels * number of pixels to process per cycle (NPPC).
  • XF_DTUNAME(TYPE,NPPC) resolves to the data type of the pixel. For instance, XF_TNAME(XF_32FC1,XF_NPPC1) resolves to float.
  • XF_PTSNAME(TYPE,NPPC) resolves to the ‘c’ data type of the pixel. For instance, XF_PTSNAME (XF_16UC1,XF_NPPC2) resolves to unsigned short.
Note: ap_uint<>, ap_int<>, ap_fixed<>, and ap_ufixed<> types belong to the high-level synthesis (HLS) library. For more information, see the (UG902).

Sample Illustration

The following code illustrates the configurations that are required to build the gaussian filter on an image, using SDSoC tool for Zynq® UltraScale™ platform.
Note: In case of a real-time application, where the video is streamed in, it is recommended that the location of frame buffer is xF::Mat and is processed using the library function. The resultant location pointer is passed to display IPs.

xf_config_params.h

#define FILTER_SIZE_3 1
#define FILTER_SIZE_5 0
#define FILTER_SIZE_7 0

xf_gaussian_filter_tb.cpp

int main(int argc, char **argv) 
{
		cv::Mat in_img, out_img, ocv_ref;
	cv::Mat in_gray, in_gray1, diff;
in_img = cv::imread(argv[1], 1); // reading in the color image
		extractChannel(in_img, in_gray, 1);

xF::Mat<XF_8UC1, HEIGHT, WIDTH, XF_NPPC1> imgInput(in_gray.rows,in_gray.cols);
xF::Mat<XF_8UC1, HEIGHT, WIDTH,XF_NPPC1> imgOutput(in_gray.rows,in_gray.cols);
imgInput.copyTo(in_gray.data);
xFGaussianBlur<FILTER, XF_BORDER_CONSTANT,XF_8UC1, HEIGHT, WIDTH, XF_NPPC1>(imgInput, imgOutput, sigma);
out_img.data = imgOutput.copyFrom();

	    imwrite("output_hls.png", out_img);
}

xf_gaussian_filter.hpp

#pragma SDS data data_mover("_src.data":AXIDMA_SIMPLE)
#pragma SDS data data_mover("_dst.data":AXIDMA_SIMPLE)
#pragma SDS data access_pattern("_src.data":SEQUENTIAL)
#pragma SDS data copy("_src.data"[0:"_src.size"])
#pragma SDS data access_pattern("_dst.data":SEQUENTIAL)
#pragma SDS data copy("_dst.data"[0:"_dst.size"])

template<int FILTER_SIZE, int BORDER_TYPE, int SRC_T, int ROWS, int COLS,int NPC = 1>
void xFGaussianBlur(xF::Mat<SRC_T, ROWS, COLS, NPC> & _src, xF::Mat<SRC_T, ROWS, COLS, NPC> & _dst, float sigma)
{
//function body
}

The design fetches data from external memory (with the help of SDSoC data movers) and is transferred to the function in 8-bit or 64-bit packets, based on the configured mode. Assuming 8-bits per pixel, 8 pixels can be packed into 64-bits. Therefore, 8 pixels are available to be processed in parallel.

Enable the FILTER_SIZE_3_1 and the NO macros in the xf_config_params.h file. The #define FILTER_SIZE_3 1 macro is used to set the filter size to 3x3 and #define NO 1 macro enables 1 pixel parallelism.

Specify the SDSoC tool specific pragmas, in the xf_gaussian_filter.hpp file.

#pragma SDS data data_mover("_src.data":AXIDMA_SIMPLE)
#pragma SDS data data_mover("_dst.data":AXIDMA_SIMPLE)
#pragma SDS data access_pattern("_src.data":SEQUENTIAL)
#pragma SDS data copy("_src.data"[0:"_src.size"])
#pragma SDS data access_pattern("_dst.data":SEQUENTIAL)
#pragma SDS data copy("_dst.data"[0:"_dst.size"])
Note: For more information on the pragmas used for hardware accelerator functions in SDSoC, see the SDSoC Pragma Specification.