首页 > 解决方案 > 如何在 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 中的白色像素坐标的代码部分的帮助。

标签: vivadovivado-hls

解决方案


这个问题相当广泛,因为根据您的设置和要求,可以有多种方法来实现您的目标。

但是,如果您使用一种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.
    }
  }
}

至于最终存储您的结果:由于最多可以有W * H白色像素,您可能需要一个W * H * log2(max(W, H))位缓冲区。

编辑

根据更新的问题,代码的最后一部分可能会出现一些问题。

由于没有给出AXI_STREAMand的定义gray_IMAGE ,因此流的数据类型(以及内部流img_*)可能无法与 255(白色像素值)进行比较。

假设像素被定义为一个结构,那么做pixel == 255就不会编译。另一方面,如果它是像ap_uint<24>(三个 8 位像素)这样的“扁平化”RGB 数组,则与 255 进行比较可能没有意义(您需要将其与 进行比较0xFFFFFF)。

否则,如果像素类型是整数或无符号字符,则将其与 255 或 0 进行比较不会有任何问题。


推荐阅读