Search code examples
fpgavivadovivado-hls

Does Mat in hls:Mat really represents a matrix?


I am working on Vivado HLS. I am reading an image via stream and storing it in hls:mat. I want to perform an element-wise operation on this mat. Does mat really represent a matrix? Is there a way in which I can access it like a Matrix i.e. A[rows][columns]?

Method A.at<double>(0,0) is not working.


Solution

  • I found the answer using Sobel code (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);
    }