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

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

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

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

 #include "top.h"
 #include <iostream>
 
void dust_detect(AXI_STREAM& input_data, AXI_STREAM& 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.


person Nikhil    schedule 24.05.2021    source источник


Ответы (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);
  }
}

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

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.
    }
  }
}

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

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

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

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

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

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

person Stefano Ribes    schedule 24.05.2021
comment
Большое спасибо, что нашли время ответить. Но, к сожалению, я не могу интегрировать этот блок кода с другими шагами моего алгоритма. Могу ли я написать вам лично и обратиться за помощью? @Стефано Рибес - person Nikhil; 26.05.2021
comment
Может быть, вы можете сначала попытаться обновить вопрос с помощью кода, чтобы больше людей и я могли помочь сузить проблему. Если это все равно не сработает, тогда мы можем поговорить по почте. - person Stefano Ribes; 27.05.2021
comment
Мне нужна помощь с последним битом кода, то есть после hls::Mat, чтобы найти координаты белого пикселя, присутствующие в изображении img_7a. Пожалуйста, помогите. - person Nikhil; 30.05.2021
comment
ошибка: недопустимые операнды типов 'const char [25]' и 'const char [5]' для двоичного 'operator+' printf(белый пиксель найден в x: + m + \ty: + n) ; // Обнаружен белый пиксель в точке (x,y) // @suppress(Недопустимые аргументы) Как устранить эту ошибку? - person Nikhil; 31.05.2021
comment
Эта ошибка связана с printf, а не с HLS: эту функцию использовать нельзя (используйте стандартный ввод-вывод и std::cout в C++ (я предполагаю, что вы используете C++, поскольку hls::Mat не поддерживается в C)) . - person Stefano Ribes; 31.05.2021
comment
Хорошо, как я могу сохранить все координаты белого пикселя в изображении (img_7a)? - person Nikhil; 01.06.2021
comment
Это зависит от ваших требований. Есть много способов добиться этого, обновите вопрос, указав более подробную информацию, или отметьте его как решенный. - person Stefano Ribes; 01.06.2021
comment
Можете ли вы помочь с получением координат белого пикселя, я попытался использовать std::cout, как было предложено, но все равно получил ошибки. - person Nikhil; 01.06.2021
comment
Я не могу вам помочь, если вы используете общие термины, такие как получить координаты и ошибки (какие ошибки?), Мне нужно больше подробностей о том, что вы пытаетесь сделать. Использование стандартного ввода-вывода предназначено для печати и отладки вашего алгоритма. Но нет никакой концепции печати, когда ваш дизайн синтезирован, это аппаратное обеспечение, это электронная схема. Я предлагаю вам проверить и изучить руководство Vivado HLS по системным вызовам. - person Stefano Ribes; 02.06.2021