Действительно ли Mat в hls:Mat представляет собой матрицу?

Я работаю над Vivado HLS. Я читаю изображение через поток и сохраняю его в hls:mat. Я хочу выполнить поэлементную операцию над этим mat. Действительно ли мат представляет собой матрицу? Есть ли способ, которым я могу получить к нему доступ, как Матрица, то есть A[rows][columns]?

Метод A.at<double>(0,0) не работает.


person A.k.    schedule 23.01.2018    source источник


Ответы (2)


Нет, согласно примечанию по применению Xilinx XAPP1167:

Второе ограничение заключается в том, что тип данных hls::Mat<>, используемый для моделирования изображений, внутренне определяется как поток пикселей с использованием типа данных hls::stream<>, а не как массив пикселей во внешней памяти. В результате произвольный доступ к изображениям не поддерживается, а метод cv::Mat<>.at() и функция cvGet2D() не имеют соответствующих эквивалентных функций в синтезируемой библиотеке.

Таким образом, вы можете передавать данные только в/из hls::Mat и не можете получить доступ к случайному элементу.

person haggai_e    schedule 24.01.2018
comment
Но я нашел нечто, называемое окном памяти. Окна памяти При обработке видео и изображений окно памяти определяется как окрестность из N пикселей с центром в пикселе P. Окно памяти также можно рассматривать как набор сдвиговых регистров, формирующих двумерный элемент хранения данных. - person A.k.; 24.01.2018
comment
Этот вид памяти обычно реализован в виде триггеров по следующим причинам: • В ней меньше элементов данных. Сохраняются только пиксели, необходимые для вычисления некоторой характеристики P. Примером этого являются окна памяти 3 x 3, используемые при обнаружении границ. • Все соседние пиксели должны быть доступны одновременно при вычислении значения P. Самое простое определение окна памяти в C/C++ — это двумерный массив. Например, окно памяти 3 x 3 B может быть определено как: int B[3][3]; - person A.k.; 24.01.2018
comment
Эти окна памяти кажутся полезной конструкцией, если вы можете выразить свой алгоритм, используя их. - person haggai_e; 24.01.2018
comment
Я хочу найти связанные объекты в бинарном изображении, но не могу это реализовать. Алгоритм отлично работает на CPP, но я новичок в HLS, поэтому все еще пытаюсь реализовать его в HLS. - person A.k.; 25.01.2018
comment
Вы должны ожидать, что код HLS будет отличаться от кода C++ общего назначения. Это ограничено из-за требований синтеза. Я видел, что вы опубликовали еще один вопрос о подключенных компонентах, поэтому, возможно, вам следует обсудить эту конкретную проблему там. - person haggai_e; 25.01.2018

Я нашел ответ, используя код Собеля (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);
}
person A.k.    schedule 08.03.2018