hls:Mat中的Mat真的代表矩阵吗?
Does Mat in hls:Mat really represents a matrix?
我正在研究 Vivado HLS。我正在通过流读取图像并将其存储在 hls:mat
中。我想对此 mat
执行逐元素操作。 mat 真的代表矩阵吗?有没有一种方法可以像矩阵一样访问它,即 A[rows][columns]
?
方法A.at<double>(0,0)
无效。
没有,根据Xilinx application note XAPP1167:
A second limitation is that the hls::Mat<>
datatype used to model
images is internally defined as a stream of pixels, using the
hls::stream<>
datatype, rather than as an array of pixels in external
memory. As a result, random access is not supported on images, and the
cv::Mat<>.at()
method and cvGet2D()
function have no corresponding
equivalent function in the synthesizable library.
因此您只能流式传输数据 to/from hls::Mat
而您不能访问随机元素。
我使用 Sobel 代码 (XAP1167) 找到了答案
void created_window(MY_IMAGE& src, MY_IMAGE& dst, int rows, int cols)
{
MY_BUFFER buff_A;
MY_WINDOW WINDOW_3x3;
for(int row = 0; row < rows+1; row++){
for(int col = 0; col < cols+1; col++){
#pragma HLS loop_flatten off
#pragma HLS dependence variable=&buff_A false
#pragma HLS PIPELINE II = 1
// Temp values are used to reduce the number of memory reads
unsigned char temp;
MY_PIXEL tempx;
//Line Buffer fill
if(col < cols){
buff_A.shift_down(col);
temp = buff_A.getval(0,col);
}
//There is an offset to accommodate the active pixel region
//There are only MAX_WIDTH and MAX_HEIGHT valid pixels in the image
if(col < cols && row < rows){
MY_PIXEL new_pix;
src >> new_pix;
tempx = new_pix;
buff_A.insert_bottom(tempx.val[0],col);
}
//Shift the processing window to make room for the new column
WINDOW_3x3.shift_right();
//The processing window only needs to store luminance values
//rgb2y function computes the luminance from the color pixel
if(col < cols){
WINDOW_3x3.insert(buff_A.getval(2,col),2,0);
WINDOW_3x3.insert(temp,1,0);
WINDOW_3x3.insert(tempx.val[0],0,0);
}
MY_PIXEL conn_obj;
//The operator only works on the inner part of the image
//This design assumes there are no connected objects on the boundary of the image
conn_obj = find_conn(&WINDOW_3x3);
//The output image is offset from the input to account for the line buffer
if(row > 0 && col > 0) {
dst << conn_obj;
}
}
}
}
void create_window(AXI_STREAM& video_in, AXI_STREAM& video_out, int rows, int cols)
{
//Create AXI streaming interfaces for the core
#pragma HLS INTERFACE axis port=video_in bundle=INPUT_STREAM
#pragma HLS INTERFACE axis port=video_out bundle=OUTPUT_STREAM
#pragma HLS INTERFACE s_axilite port=rows bundle=CONTROL_BUS offset=0x14
#pragma HLS INTERFACE s_axilite port=cols bundle=CONTROL_BUS offset=0x1C
#pragma HLS INTERFACE s_axilite port=return bundle=CONTROL_BUS
#pragma HLS INTERFACE ap_stable port=rows
#pragma HLS INTERFACE ap_stable port=cols
MY_IMAGE img_0(rows, cols);
MY_IMAGE img_1(rows, cols);
#pragma HLS dataflow
hls::AXIvideo2Mat(video_in, img_0);
created_window(img_0, img_1, rows, cols);
hls::Mat2AXIvideo(img_0, video_out);
}
我正在研究 Vivado HLS。我正在通过流读取图像并将其存储在 hls:mat
中。我想对此 mat
执行逐元素操作。 mat 真的代表矩阵吗?有没有一种方法可以像矩阵一样访问它,即 A[rows][columns]
?
方法A.at<double>(0,0)
无效。
没有,根据Xilinx application note XAPP1167:
A second limitation is that the
hls::Mat<>
datatype used to model images is internally defined as a stream of pixels, using thehls::stream<>
datatype, rather than as an array of pixels in external memory. As a result, random access is not supported on images, and thecv::Mat<>.at()
method andcvGet2D()
function have no corresponding equivalent function in the synthesizable library.
因此您只能流式传输数据 to/from hls::Mat
而您不能访问随机元素。
我使用 Sobel 代码 (XAP1167) 找到了答案
void created_window(MY_IMAGE& src, MY_IMAGE& dst, int rows, int cols)
{
MY_BUFFER buff_A;
MY_WINDOW WINDOW_3x3;
for(int row = 0; row < rows+1; row++){
for(int col = 0; col < cols+1; col++){
#pragma HLS loop_flatten off
#pragma HLS dependence variable=&buff_A false
#pragma HLS PIPELINE II = 1
// Temp values are used to reduce the number of memory reads
unsigned char temp;
MY_PIXEL tempx;
//Line Buffer fill
if(col < cols){
buff_A.shift_down(col);
temp = buff_A.getval(0,col);
}
//There is an offset to accommodate the active pixel region
//There are only MAX_WIDTH and MAX_HEIGHT valid pixels in the image
if(col < cols && row < rows){
MY_PIXEL new_pix;
src >> new_pix;
tempx = new_pix;
buff_A.insert_bottom(tempx.val[0],col);
}
//Shift the processing window to make room for the new column
WINDOW_3x3.shift_right();
//The processing window only needs to store luminance values
//rgb2y function computes the luminance from the color pixel
if(col < cols){
WINDOW_3x3.insert(buff_A.getval(2,col),2,0);
WINDOW_3x3.insert(temp,1,0);
WINDOW_3x3.insert(tempx.val[0],0,0);
}
MY_PIXEL conn_obj;
//The operator only works on the inner part of the image
//This design assumes there are no connected objects on the boundary of the image
conn_obj = find_conn(&WINDOW_3x3);
//The output image is offset from the input to account for the line buffer
if(row > 0 && col > 0) {
dst << conn_obj;
}
}
}
}
void create_window(AXI_STREAM& video_in, AXI_STREAM& video_out, int rows, int cols)
{
//Create AXI streaming interfaces for the core
#pragma HLS INTERFACE axis port=video_in bundle=INPUT_STREAM
#pragma HLS INTERFACE axis port=video_out bundle=OUTPUT_STREAM
#pragma HLS INTERFACE s_axilite port=rows bundle=CONTROL_BUS offset=0x14
#pragma HLS INTERFACE s_axilite port=cols bundle=CONTROL_BUS offset=0x1C
#pragma HLS INTERFACE s_axilite port=return bundle=CONTROL_BUS
#pragma HLS INTERFACE ap_stable port=rows
#pragma HLS INTERFACE ap_stable port=cols
MY_IMAGE img_0(rows, cols);
MY_IMAGE img_1(rows, cols);
#pragma HLS dataflow
hls::AXIvideo2Mat(video_in, img_0);
created_window(img_0, img_1, rows, cols);
hls::Mat2AXIvideo(img_0, video_out);
}