Как найти координаты белого пикселя в Vivado HLS?

#vivado #vivado-hls

Вопрос:

У меня есть черно-белое изображение, заполненное белыми пикселями (255). Как я могу получить все координаты белого пикселя, присутствующие на изображении на Vivado HLS?

Я использую hls::Коврик для хранения изображений.

Вот моя функция верхнего уровня в Vivado HLS:

  #include "top.h"
 #include <iostream>
 
void dust_detect(AXI_STREAMamp; input_data, AXI_STREAMamp; output_data, int m, int n)

    {

auto int pixel;

#pragma HLS DATAFLOW
//Create AXI streaming interfaces for the core
#pragma HLS INTERFACE axis port=input_data
#pragma HLS INTERFACE axis port=output_data
#pragma HLS INTERFACE ap_ctrl_none port=return


/************* Arrays used ***************/

     gray_IMAGE img_0;
#pragma HLS STREAM variable=img_0
    gray_IMAGE img_1;
#pragma HLS STREAM variable=img_1
    gray_IMAGE img_2;
#pragma HLS STREAM variable=img_2
    gray_IMAGE img_2a;
#pragma HLS STREAM variable=img_2a
    gray_IMAGE img_2b;
#pragma HLS STREAM variable=img_2b
    gray_IMAGE img_3;
#pragma HLS STREAM variable=img_3
    gray_IMAGE img_4;
#pragma HLS STREAM variable=img_4
    gray_IMAGE img_5;
#pragma HLS STREAM variable=img_5
    gray_IMAGE img_6;
#pragma HLS STREAM variable=img_6
    gray_IMAGE img_7;
#pragma HLS STREAM variable=img_7
    gray_IMAGE img_7a;
#pragma HLS STREAM variable=img_7a
    gray_IMAGE img_7b;
#pragma HLS STREAM variable=img_7b


    const char coefficients1[7][10] = { { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
                                        { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
                                        { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
                                        { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
                                        { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
                                        { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
                                        { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} };

     hls::Window<7,10,char> erodewindow;
        for (int i=0;i<7;i  ){
            for (int j=0;j<10;j  ){
               erodewindow.val[i][j]=coefficients1[i][j];
          }
       }

 const char coefficients2[9][12] = { { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
                                     { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
                                     { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
                                     { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
                                     { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
                                     { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
                                     { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
                                     { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
                                     { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}  };

    hls::Window<9,12,char> dilatewindow;
        for (int i=0;i<9;i  ){
            for (int j=0;j<12;j  ){
                   dilatewindow.val[i][j]=coefficients2[i][j];
                      }
                   }


hls::AXIvideo2Mat(input_data, img_0);

hls::Threshold(img_0,img_1,80,255,HLS_THRESH_BINARY);//OTSU THRESHOLDING

hls::Threshold(img_1,img_2,80,255,HLS_THRESH_BINARY_INV);//Invert the Thresholded output

hls::Duplicate(img_2,img_2a,img_2b);

hls::Erode<4,4>(img_2a,img_3,erodewindow);

hls::Dilate<6,6>(img_3,img_4,dilatewindow);

hls::Threshold(img_4,img_5,100,255,HLS_THRESH_BINARY_INV);//Invert the Dilated output

hls::Threshold(img_5,img_6,100,1,HLS_THRESH_BINARY);

hls::Mul(img_2b,img_6,img_7);

hls::Duplicate(img_7,img_7a,img_7b);

    for(m=0; m<MAX_HEIGHT; m  ) {

        for(n=0; n<MAX_WIDTH; n  ) {

#pragma HLS PIPELINE IT=1

            auto pixel = img_7a.read();

            if(pixel != 0)
            {
                printf("White pixel found at x: "   m   "ty: "   n) ; // White pixel found at (x,y)
            }

                                 }
                              }

    hls::Mat2AXIvideo(img_7b,output_data);

}
 

Мне нужна помощь с той частью кода после hls::Mul, которая используется для поиска координат белого пикселя в изображении img_7a.

Ответ №1:

Вопрос довольно широкий, так как может быть много способов достижения вашей цели в зависимости от ваших настроек и требований.

Однако, если вы используете hls::Mat тип для хранения изображения, фактическое изображение сохраняется в FIFO. Таким образом, для идентификации всех белых пикселей вам придется последовательно сканировать все пиксели изображения, что-то вроде:

 for (i = 0; i < img.rows;   i) {
  for (j = 0; j < img.cols;   j) {
#pragma HLS PIPELINE II=1
    auto pixel = img.read();
    if (pixel != 0) {
      // White pixel found: use i and j (the coordinates) or store them somewhere.
    }
    // Eventually write back the pixel into the image: img.write(pixel);
  }
}
 

Если вместо этого изображение хранится в буфере, таком как регистры или БРЭМ, то описанный выше цикл по строкам и столбцам изображения можно распараллелить. Например:

 const int kUnrollFactor = 4;
pixel_t img[H][W];
#pragma HLS ARRAY_PARTITION variable=img block factor=kUnrollFactor dim=2 

for (i = 0; i < H;   i) {
  for (j = 0; j < W;   j) {
#pragma HLS PIPELINE II=1
#pragma HLS UNROLL factor=kUnrollFactor
    if (img[i][j] != 0) {
      // White pixel found: use i and j (the coordinates) or store them somewhere.
    }
  }
}
 

Что касается конечного сохранения вашего результата: поскольку может быть не более W * H белых пикселей, вам может потребоваться буфер W * H * log2(max(W, H)) битов.

Редактировать

Основываясь на обновленном вопросе, последняя часть кода может вызвать некоторые проблемы.

Поскольку определения AXI_STREAM и gray_IMAGE не даны, тип данных потока (и, в свою очередь, внутренних потоков img_* ) может быть несопоставим с 255 (значение белого пикселя).

Предположим, что пиксель определен как структура, тогда выполнение pixel == 255 просто не будет компилироваться. С другой стороны, если это «сглаженный» массив RGB, например ap_uint<24> (три 8-битных пикселя), сравнение с 255 может быть бессмысленным (вместо этого вам нужно будет сравнить его с 0xFFFFFF ).

В противном случае, если тип пикселя является целочисленным или беззнаковым символом, то сравнение его с 255 или 0 не вызовет проблем.

Комментарии:

1. Большое Вам спасибо, что нашли время ответить. Но, к сожалению, я не могу интегрировать этот блок кода с другими шагами моего алгоритма. Могу я, пожалуйста, написать вам лично и обратиться за помощью? @Stefano Ribes

2. Может быть, вы сначала попробуете обновить вопрос с помощью какого-нибудь кода, чтобы больше людей и я могли помочь сузить проблему. Если это все равно не сработает, тогда мы, возможно, сможем поговорить по почте.

3. Мне нужна помощь с последним битом кода, т. Е. после hls::Mat, чтобы найти координаты белого пикселя, присутствующие в изображении img_7a. Пожалуйста, помогите.

4. ошибка: недопустимые операнды типов ‘const char [25]’ и ‘const char [5]’ для двоичного оператора ‘ printf(«Белый пиксель, найденный в x:» m «ty: » n) ; // Белый пиксель, найденный в (x,y) // @подавить(«Недопустимые аргументы») Как я могу устранить эту ошибку ?

5. Эта ошибка от printf, а не от HLS: это не то, как использовать эту функцию (используйте стандартный ввод-вывод и std::cout в C (я предполагаю, что вы используете C , так как hls::Mat не поддерживается в C)).