vivado - 如何在 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 中的白色像素坐标的代码部分的帮助。
解决方案
这个问题相当广泛,因为根据您的设置和要求,可以有多种方法来实现您的目标。
但是,如果您使用一种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_STREAM
and的定义gray_IMAGE
,因此流的数据类型(以及内部流img_*
)可能无法与 255(白色像素值)进行比较。
假设像素被定义为一个结构,那么做pixel == 255
就不会编译。另一方面,如果它是像ap_uint<24>
(三个 8 位像素)这样的“扁平化”RGB 数组,则与 255 进行比较可能没有意义(您需要将其与 进行比较0xFFFFFF
)。
否则,如果像素类型是整数或无符号字符,则将其与 255 或 0 进行比较不会有任何问题。
推荐阅读
- c# - Visual Studio 2013 的自定义代码分析
- c - 无法在 C 中使用带有 pow() 的模数
- sql-server - 出勤进出
- sql - SQL DELETE From 带有子查询语法错误
- php - 如何在 php 中使用 substr()?
- graphql - Apollo GraphQL:未在突变子字段上调用解析器
- sql-server - 尝试更新多行会引发 512 错误
- webview - 如何使用flutter dart webview渲染本地HTML文件
- java - 编译 javadoc 时包含外部 jar
- c# - Azure Blob 和表存储以更简单的方式重写代码