本方案利用 HLS 功能創(chuàng)建圖像處理解決方案,在可編程邏輯中實現(xiàn)邊緣檢測 (Sobel)。
介紹
高級綜合 (HLS) 允許我們在開發(fā) FPGA 應(yīng)用程序時在更高的抽象級別上工作,如果是商業(yè)項目,有望節(jié)省時間并降低非經(jīng)常性成本。
HLS 的一個重要應(yīng)用是圖像或信號處理,我們可能已經(jīng)用 C 或 C++ 創(chuàng)建了一個高級模型,或者我們希望使用開源行業(yè)標(biāo)準(zhǔn)框架,例如 OpenCV。
在本項目中,我們將研究如何使用 HLS 構(gòu)建 Sobel 邊緣檢測 IP 核,然后將其包含在我們選擇的 Xilinx FPGA 中。
所選器件可以是傳統(tǒng)的 FPGA,例如 Spartan Seven 或 Artix,或者也可以在異構(gòu) SoC 的可編程邏輯中實現(xiàn),例如 Zynq 7000 或 Zynq MPSoC。
理論
在我們進入應(yīng)用程序之前,我應(yīng)該先簡單介紹一下 Sobel 算法的工作原理。Sobel 算法通過識別圖像中的邊緣并強調(diào)它們以便可以輕松識別它們來發(fā)揮作用。通常這將創(chuàng)建一個灰度圖像,其中邊緣被識別為灰色/白色陰影。
Sobel 邊緣檢測的工作原理是檢測圖像在水平和垂直方向上的梯度變化。為此,將兩個卷積濾波器應(yīng)用于原始圖像,然后組合這些卷積濾波器的結(jié)果以確定梯度的大小。
執(zhí)行
如果我們使用傳統(tǒng)的 VHDL / Verilog RTL 方法在 FPGA 中實現(xiàn)這一點,那么開發(fā)時間將不會很短。因為我們需要為卷積創(chuàng)建行緩沖區(qū),然后實現(xiàn)幅度計算。我們還需要創(chuàng)建一個測試平臺,以確保我們的代碼在進行實施之前按預(yù)期工作。
幸運的是,當(dāng)我們使用 HLS 時,我們真的可以跳過很多繁重的工作,讓 Vivado HLS 實現(xiàn)較低級別的 Verilog/VHDL RTL 實現(xiàn)。
為了在這個更高的抽象級別上工作,我們將使用 Vivado HLS 及其 HLS_OpenCV 和 HLS_Video 庫。
第一個庫 HLS_OpenCV 允許我們使用非常流行的 OpenCV 框架。而 HLS 視頻庫提供了許多可以加速為可編程邏輯的圖像處理功能。
而是有益的HLS視頻庫包括我們需要創(chuàng)建一個索貝爾IP核心,內(nèi)容包括: -
HLS::CvtColor - 這將根據(jù)其配置在顏色和灰度之間轉(zhuǎn)換顏色方案。
HLS::Gaussian - 這將對圖像執(zhí)行高斯模糊以減少圖像中存在的噪聲。
HLS::Sobel - 根據(jù)其配置在垂直或水平方向執(zhí)行 Sobel 卷積。我們將需要在我們的 IP 核中使用這兩個實現(xiàn)。
HLS::AddWeighted - 這允許我們使用來自垂直和水平 Sobel 算子的結(jié)果來執(zhí)行結(jié)果幅度計算。
這些不是我們將使用的所有 HLS 函數(shù),因為我們需要使用其他函數(shù)。我們需要包含這些附加功能,以便更輕松地使用 HLS 優(yōu)化和與 Vivado 設(shè)計的接口。
界面
在可編程邏輯內(nèi)部移動圖像數(shù)據(jù)的最佳方法是使用 AXI 流。
這允許創(chuàng)建高性能圖像處理路徑,其中元素可以根據(jù)需要輕松添加或創(chuàng)建。
Vivado IP 庫中存在多個 IP 模塊,可實現(xiàn)視頻輸入和輸出與 AXI 流之間的轉(zhuǎn)換。以及其他圖像處理功能,例如混合器和色彩空間轉(zhuǎn)換器。
因此,我們希望我們的 Sobel IP 核能夠接受 AXI Stream 輸入并以相同的 AXI Stream 格式生成其輸出。為此,我們使用以下函數(shù)允許在 AXI 流和 HLS 函數(shù)使用的 HLS::Mat 格式之間進行轉(zhuǎn)換。
HLS::AXIvideo2Mat - 從 AXI 流轉(zhuǎn)換為用于 AXI 流輸入的 HLS::Mat 格式。
HLS::Mat2AXIvideo - 從 HLS::Mat 格式轉(zhuǎn)換為 AXI Stream 格式,用于 AXI Stream 輸出。
C 綜合和優(yōu)化
與 Verilog 和 VHDL 設(shè)計不同,我們用來描述設(shè)計的高級語言是不定時的。這意味著當(dāng) HLS 工具將 C 轉(zhuǎn)換為 Verilog 或 VHDL 時,它必須經(jīng)過多個階段才能創(chuàng)建輸出 RTL
調(diào)度 - 確定操作及其發(fā)生的順序。
綁定 - 將操作分配給設(shè)備內(nèi)可用的邏輯資源。
控制邏輯提取 - 提取控制邏輯并創(chuàng)建控制結(jié)構(gòu),例如狀態(tài)機以控制模塊的行為。
由于 HLS 工具在運行綜合時必須在性能和邏輯資源之間進行權(quán)衡,因此在實現(xiàn)過程中將遵循許多規(guī)則。這些可能會影響生成的 IP 核的性能,例如循環(huán)(HLS 編碼中的常見結(jié)構(gòu))保持滾動。
當(dāng)然,我們可能希望更改 HLS 工具在 C 綜合期間做出的決定以獲得更好的性能。我們可以在我們的 C 中使用 #pragmas 來做到這一點,我們可以使用幾個。
對于這個實現(xiàn),我們將使用 Dataflow pragma 來確保我們可以達到最高的幀速率。
為了能夠使用此編譯指示,我們需要確保 HLS 綜合工具并行執(zhí)行兩個 Sobel 操作。這將允許我們在 HLS C 綜合期間指定數(shù)據(jù)流優(yōu)化,從而優(yōu)化通過函數(shù)的數(shù)據(jù)流。實際上,數(shù)據(jù)流優(yōu)化是粗粒度流水線。
如果我們先執(zhí)行一個 Sobel 操作,然后按順序執(zhí)行另一個操作,我們將無法應(yīng)用此優(yōu)化。
因此,我們需要將高斯模糊的結(jié)果分成兩條平行路徑,然后在 AddWeighted 階段重新組合。為此,我們使用函數(shù)
HLS::Duplicate - 這將輸入圖像復(fù)制到兩個單獨的輸出圖像中,我們可以并行處理這些圖像。
軟件
了解所有這些之后,我們就可以編寫用于 Sobel IP 核的代碼
#include "cvt_colour.hpp"
void image_filter(AXI_STREAM& INPUT_STREAM, AXI_STREAM& OUTPUT_STREAM)//, int rows, int cols)
{
#pragma HLS INTERFACE axis port=INPUT_STREAM
#pragma HLS INTERFACE axis port=OUTPUT_STREAM
RGB_IMAGE img_0(MAX_HEIGHT, MAX_WIDTH);
GRAY_IMAGE img_1(MAX_HEIGHT, MAX_WIDTH);
GRAY_IMAGE img_2(MAX_HEIGHT, MAX_WIDTH);
GRAY_IMAGE img_2a(MAX_HEIGHT, MAX_WIDTH);
GRAY_IMAGE img_2b(MAX_HEIGHT, MAX_WIDTH);
GRAY_IMAGE img_3(MAX_HEIGHT, MAX_WIDTH);
GRAY_IMAGE img_4(MAX_HEIGHT, MAX_WIDTH);
GRAY_IMAGE img_5(MAX_HEIGHT, MAX_WIDTH);
RGB_IMAGE img_6(MAX_HEIGHT, MAX_WIDTH);
;
#pragma HLS dataflow
hls::AXIvideo2Mat(INPUT_STREAM, img_0);
hls::CvtColor
hls::GaussianBlur<3,3>(img_1,img_2);
hls::Duplicate(img_2,img_2a,img_2b);
hls::Sobel<1,0,3>(img_2a, img_3);
hls::Sobel<0,1,3>(img_2b, img_4);
hls::AddWeighted(img_4,0.5,img_3,0.5,0.0,img_5);
hls::CvtColor
hls::Mat2AXIvideo(img_6, OUTPUT_STREAM);
}
#include "hls_video.h"
#include
#define MAX_WIDTH 1280
#define MAX_HEIGHT 720
typedef hls::stream
typedef hls::Mat
typedef hls::Mat
void image_filter(AXI_STREAM& INPUT_STREAM, AXI_STREAM& OUTPUT_STREAM);//int rows, int cols);
當(dāng)然,我們希望能夠同時運行 C Simulation 和 Co Simulation,因此我們需要一個可以用來測試算法的測試臺。
當(dāng)我們運行 C Simulation 時,我們可以看到測試輸入圖像的結(jié)果如下。
有了 C 仿真和 Co 仿真結(jié)果,我們可以導(dǎo)出內(nèi)核并將其添加到 Vivado 硬件設(shè)計中。
但是,在我們執(zhí)行此操作之前,您可能需要檢查分析、在 Vivado HLS 中查看并確認兩個 Sobel 函數(shù)并行運行。
我們可以使用 Vivado HLS 中的導(dǎo)出 RTL 選項導(dǎo)出 IP 核,如果我們希望我們可以進一步配置 IP 核參數(shù)
實現(xiàn)核心
導(dǎo)出核心后,您將在 《project》/solutionX/imp 目錄下找到一個 zip 文件。該目錄包含將新創(chuàng)建的 Sobel IP 核添加到 Vivado 設(shè)計所需的所有必要信息。
該文件可以添加到我們的 Vivado IP 存儲庫中,然后包含在 Vivado 框圖中
有了這一切集成,您可以構(gòu)建應(yīng)用程序和目標(biāo)到您選擇的開發(fā)板。
對于下面的演示視頻,我使用 Zybo Z7 和 HDMI 輸入和 HDMI 輸出將視頻應(yīng)用于 Sobel IP 核并顯示結(jié)果。
-
圖像處理
+關(guān)注
關(guān)注
27文章
1292瀏覽量
56744 -
邊緣檢測
+關(guān)注
關(guān)注
0文章
92瀏覽量
18211 -
HLS
+關(guān)注
關(guān)注
1文章
129瀏覽量
24113
發(fā)布評論請先 登錄
相關(guān)推薦
評論