傳統(tǒng)嵌入式視覺(jué)系統(tǒng)采用FPGA/處理器組合來(lái)實(shí)現(xiàn),也有越來(lái)越多地使用將高性能處理器與FPGA相結(jié)合的片上系統(tǒng)來(lái)實(shí)現(xiàn)。在本文中我們將會(huì)介紹嵌入式視覺(jué)系統(tǒng)的高級(jí)元素;如何簡(jiǎn)便快捷地使用軟件 API 和 IP 庫(kù)構(gòu)建嵌入式視覺(jué)系統(tǒng),如何把算法開(kāi)發(fā)的增值部分添加到圖像處理鏈中。
從監(jiān)控?cái)z像頭等簡(jiǎn)單監(jiān)控系統(tǒng)到更高級(jí)的應(yīng)用,例如當(dāng)今最新款汽車配備的高級(jí)駕駛員輔助系統(tǒng) (ADAS)和先進(jìn)生產(chǎn)設(shè)施及工廠里使用的機(jī)器視覺(jué),嵌入式視覺(jué)系統(tǒng)已在一系列應(yīng)用中得到使用。不論何種應(yīng)用,嵌入式視覺(jué)系統(tǒng)都具備一些共同之處,總體來(lái)講它們可以分為下列三大類:
設(shè)備接口 — 提供到所選成像設(shè)備的接口。根據(jù)選擇的設(shè)備類型,提供所需的時(shí)鐘、偏置和配置數(shù)據(jù)。這樣還可以從設(shè)備接收?qǐng)D像數(shù)據(jù),根據(jù)需要進(jìn)行解碼和格式化,以供圖像處理鏈做進(jìn)一步處理。
圖像處理鏈 — 通過(guò)設(shè)備接口接收?qǐng)D像數(shù)據(jù)并進(jìn)行彩色濾波器陣列內(nèi)插和色域轉(zhuǎn)換(即從彩色轉(zhuǎn)換到灰度)等操作。這部分仍處于我們對(duì)接收到的圖像使用大量算法的圖像處理鏈內(nèi)。這些可以是降噪或邊緣增強(qiáng)等簡(jiǎn)單算法,也可以是對(duì)象識(shí)別或光流等復(fù)雜得多的算法。常見(jiàn)情況是在圖像處理鏈的上游部分調(diào)用算法實(shí)現(xiàn)方案。當(dāng)然圖像處理鏈上游的實(shí)現(xiàn)復(fù)雜性取決于要實(shí)現(xiàn)的應(yīng)用。而輸出格式化部分(即將處理后的圖像數(shù)據(jù)轉(zhuǎn)換為正確格式,以輸出到顯示器或是通過(guò)通信接口輸出)被稱為下游部分。
系統(tǒng)監(jiān)視與控制 – 這是一項(xiàng)獨(dú)立于設(shè)備接口和圖像處理鏈的類別,它從兩個(gè)方面提供系統(tǒng)監(jiān)視和控制。第一個(gè)位于設(shè)備內(nèi)部,它提供:
圖像處理鏈的配置
圖像分析功能
在算法執(zhí)行過(guò)程中根據(jù)要求更新圖像處理鏈
第二個(gè)是更廣泛的嵌入式視覺(jué)系統(tǒng)的控制與管理,它提供:
電源管理和圖像設(shè)備上電排序
執(zhí)行自檢及其他系統(tǒng)管理功能
網(wǎng)絡(luò)支持通信或點(diǎn)對(duì)點(diǎn)通信
在首次成像操作前通過(guò) I2C 或 SPI 配置圖像設(shè)備
部分應(yīng)用允許系統(tǒng)監(jiān)視功能訪問(wèn)幀存儲(chǔ)器并在其中的幀上執(zhí)行算法。在這種情況下系統(tǒng)監(jiān)視能夠構(gòu)成圖像處理鏈的一部分。
這三大類別因?yàn)槊總€(gè)階段內(nèi)在的難點(diǎn)不同,需要不同的實(shí)現(xiàn)方法。設(shè)備接口和圖像處理鏈都要求有能力處理帶寬高數(shù)據(jù),從而在內(nèi)部實(shí)現(xiàn)圖像處理鏈,在外部從系統(tǒng)傳輸圖像數(shù)據(jù)。而系統(tǒng)監(jiān)視與控制要求能夠處理和響應(yīng)通過(guò)通信接口接收到的命令并為外部通信提供支持。如果系統(tǒng)監(jiān)視也要構(gòu)成圖像處理鏈的組成部分,就需要一個(gè)高性能處理器。
照此,傳統(tǒng)嵌入式視覺(jué)系統(tǒng)采用FPGA/處理器組合來(lái)實(shí)現(xiàn),也有越來(lái)越多地使用將高性能處理器與FPGA相結(jié)合的片上系統(tǒng)來(lái)實(shí)現(xiàn)。在我們演示上述幾個(gè)方面如何結(jié)合在一起之前,我們先來(lái)了解一下這三個(gè)類別中每一個(gè)的不同難點(diǎn)。
設(shè)備接口
傳感器接口由應(yīng)用所選擇的設(shè)備決定,大多數(shù)嵌入式視覺(jué)應(yīng)用使用 CMOS 圖像傳感器 (CIS)。一般情況下這些傳感器使用 CMOS 并行輸出總線,用控制信號(hào)提示行和幀的有效順序,或者使用速率更高的串行通信,實(shí)現(xiàn)較簡(jiǎn)單的系統(tǒng)接口,但會(huì)導(dǎo)致 FPGA 實(shí)現(xiàn)方案略顯復(fù)雜。與并行總線相比,這些串行數(shù)據(jù)流能通過(guò)更少數(shù)量的通道傳輸圖像,因?yàn)樗鼈円钥斓枚嗟臄?shù)據(jù)速率運(yùn)行,因此相比并行接口而言,能讓成像器支持更高的幀速率。為實(shí)現(xiàn)同步,常見(jiàn)的做法是讓包含圖像及其它數(shù)據(jù)字的數(shù)據(jù)通道與包含用于定義數(shù)據(jù)通道上的內(nèi)容的代碼字的同步通道相結(jié)合。與數(shù)據(jù)通道和同步通道結(jié)合的還有一個(gè)時(shí)鐘通道,因?yàn)樵摻涌诓捎迷赐?。這些高速串行通道一般實(shí)現(xiàn)為 LVDS 或微擺幅差分信號(hào) (Reduced Swing LVDS),以降低系統(tǒng)噪聲和功耗。
不論輸出圖像格式如何,通常是 CIS 設(shè)備在獲取任何圖像之前需要由嵌入式視覺(jué)系統(tǒng)加以配置。這是由 CIS 設(shè)備的多功能性造成的。這種多功能性在提供強(qiáng)大的片上處理功能的同時(shí),也需要在輸出圖像前使用正確的設(shè)置進(jìn)行配置。這些接口對(duì)帶寬的要求沒(méi)有圖像傳輸要求的那么高,因此常常使用 I2C 或 SPI 接口標(biāo)準(zhǔn)。
因?yàn)樗璧膱D像數(shù)據(jù)帶寬較高,經(jīng)常把該接口實(shí)現(xiàn)在 FPGA 中,這樣更便于與圖像處理鏈集成。該 CIS 設(shè)備的配置接口一般使用 I2C 或 SPI,它們既可以用 FPGA 實(shí)現(xiàn),也可以用支持這種接口的系統(tǒng)監(jiān)視與控制處理器實(shí)現(xiàn)。
圖像處理鏈
圖像處理鏈由上下游元件和接口組成,像素?cái)?shù)據(jù)通過(guò)設(shè)備接口輸出。但是接收到的像素的格式可能不能用于正確顯示圖像。我們可能需要進(jìn)行圖像校正,尤其是在使用彩色成像器的情況下。 為維持所需數(shù)據(jù)率下的吞吐量,圖像處理鏈常實(shí)現(xiàn)在 FPGA 中,以發(fā)揮其并行優(yōu)勢(shì)。這樣可以生成圖像處理流水線,使得處理鏈的每一步都將并行實(shí)現(xiàn),從而獲得更高的幀速率。但是對(duì)部分應(yīng)用我們必須考慮時(shí)延,尤其是對(duì)高級(jí)駕駛員輔助系統(tǒng) (ADAS) 這樣的系統(tǒng)而言。為有效建立圖像處理鏈,我們需要使用通用互聯(lián)協(xié)議作為圖像處理內(nèi)核的基礎(chǔ),從而方便處理 IP 的互聯(lián)。這樣可以帶來(lái)兩重好處:一是可以重復(fù)使用的庫(kù);二是由于每個(gè) IP 核旨在根據(jù)定義的標(biāo)準(zhǔn)接收和發(fā)送數(shù)據(jù),從而方便流水線的建立。這里有多種常用的協(xié)議可供選用,其中最常見(jiàn)的是 AXI,因其具有同時(shí)支持內(nèi)存映射接口和流接口的靈活性。
圖像處理鏈內(nèi)的典型處理階段包括:
彩色濾波器陣列 – 在CIS設(shè)備上用貝爾 (Bayer) 濾色片生成每個(gè)像素的彩色
色域轉(zhuǎn)換 – 從RGB轉(zhuǎn)換為YUV
色度重采樣 – 將 YUV 像素轉(zhuǎn)換為更高效的像素編碼
應(yīng)用圖像校正算法,比如色彩校正或伽馬校正,或是進(jìn)行圖像增強(qiáng)或降噪
在下游側(cè)我們可以配置視頻輸出時(shí)序,然后在輸出到指定的目標(biāo)前轉(zhuǎn)換回本機(jī)并行輸出視頻格式
部分系統(tǒng)也使用外部?jī)?nèi)存,例如DDR 的內(nèi)存作為幀存儲(chǔ),在 SoC 內(nèi)部 DDR 內(nèi)存也往往提供給 SoC 的處理器側(cè)。共享內(nèi)存空間的能力讓系統(tǒng)監(jiān)視側(cè)能通過(guò)千兆位以太網(wǎng)或 USB 傳輸數(shù)據(jù),或成為圖像處理鏈的延伸。
系統(tǒng)監(jiān)視
傳統(tǒng)上該功能實(shí)現(xiàn)在處理器內(nèi)部,能夠處理相關(guān)命令,以按應(yīng)用需求對(duì)圖像處理鏈進(jìn)行配置。為接收和處理命令,系統(tǒng)監(jiān)視功能必須能夠支持從簡(jiǎn)單的 RS232、千兆位以太網(wǎng)、USB、PCIe 到 CAN 汽車專用接口等一系列不同的通信接口。
只要嵌入式視覺(jué)系統(tǒng)的架構(gòu)能夠支持,我們就能使用處理器來(lái)生成圖像疊加信息,可供疊加在輸出圖像上。在能夠訪問(wèn)圖像數(shù)據(jù)的條件下,我們也能夠使用處理器對(duì)圖像開(kāi)展進(jìn)一步處理,或是收集統(tǒng)計(jì)數(shù)據(jù)(像素值分布柱狀圖等)。這樣系統(tǒng)監(jiān)視就成為圖像處理鏈的一部分,讓開(kāi)發(fā)人員能利用各種開(kāi)源圖像處理庫(kù),如OpenCV、OpenCL 和 OpenVX。
EVK使用實(shí)例
在闡明嵌入式視覺(jué)系統(tǒng)的基本元素后,下文將示范這些概念,展現(xiàn)如何綜合運(yùn)用它們創(chuàng)建出可工作的系統(tǒng)。該實(shí)例將展示我們?nèi)绾问褂?a href="http://wenjunhu.com/tags/安富利/" target="_blank">安富利 MicroZed 嵌入式視覺(jué)套件 (EVK)創(chuàng)建嵌入式視覺(jué)系統(tǒng)。
該套件使用安森美 Python 1300C 成像設(shè)備和賽靈思 Zynq 7020。 Python 1300C 是一個(gè) 1280 像素×1024行的色彩圖像傳感器,通過(guò) SPI 接口配置。此型號(hào)傳感器使用串行輸出實(shí)現(xiàn)高幀率,同時(shí)EVK 支持通過(guò) HDMI 接口輸出圖像到顯示器。
Zynq 7020 為嵌入式視覺(jué)系統(tǒng)的實(shí)現(xiàn)提供了一個(gè)極好的平臺(tái),因?yàn)槲覀兡苁褂?FPGA 架構(gòu)中的可編程邏輯 (PL) 實(shí)現(xiàn)該設(shè)備的接口和圖像處理鏈。而 FPGA 架構(gòu)中的 ARM A9雙核處理器(即處理系統(tǒng) (PS))可用于根據(jù)我們的需要實(shí)現(xiàn)系統(tǒng)監(jiān)視功能和圖像處理鏈延伸。
為開(kāi)發(fā)該應(yīng)用,我們將用到兩個(gè) SoC 開(kāi)發(fā)工具。一個(gè)是賽靈思 Vivado 2015.4,另一個(gè)是賽靈思SDK 2015.4。在 Vivado 中我們將實(shí)現(xiàn)設(shè)備的接口、圖像處理鏈,在 Zynq 內(nèi)配置 PS,建立 PS 到 PL 存儲(chǔ)器映射以完成下列操作:
根據(jù)圖像大小和幀速率所要求的參數(shù)以及所需操作在圖像處理鏈內(nèi)配置 IP。為此我們將在 PS和 PL 間使用通用 AXI 互聯(lián),以 PS 為主設(shè)備。使用該接口我們能在 PS 和 PL 間實(shí)現(xiàn) 高達(dá) 1,200Mbps 的傳輸速率。
如有必要,將處理器的 DDR 內(nèi)存置于圖像處理鏈中,以便處理器訪問(wèn)。為此我們將在 PL 和 PS 間使用高性能 AXI 互聯(lián),以 PL 為主設(shè)備。使用該接口我們能在 PL 和 PS DDR 內(nèi)存間實(shí)現(xiàn)高達(dá) 2,400Mbps 的傳輸速率。
該演示將使用 HDMI 展示如何將圖像輸出到顯示器上。相當(dāng)有用的是,EVK 制造商安富利為Python 1300C 提供了一個(gè)設(shè)備接口 IP 模塊,并為在 EVK 上接口輸出到 HDMI 設(shè)備提供了一個(gè) HDMI 輸出 IP 模塊。我們將本實(shí)例中使用所有這些模塊。在 Vivado 中我們可以使用 IPXact 格式把這些 IP 模塊添加到 Vivado IP 目錄中。
圖像處理鏈將與安森美設(shè)備接口并執(zhí)行下列處理階段,除了 Python 1300C 和 HDMI IP 核,所有使用的 IP 核均來(lái)自 Vivado 中的標(biāo)準(zhǔn)賽靈思圖像處理 IP 庫(kù)(實(shí)際 IP 核的名稱在下面顯示):
圖1:圖像處理流程
將來(lái)自 Python 接口 IP 的并行視頻和水平及垂直同步轉(zhuǎn)換為 AXIS Stream,以便我們能夠?qū)⑵渑c后續(xù)的圖像處理IP核接口。 視頻輸入到 AXIS (Video in to AXIS)
彩色濾波器陣列使用貝爾濾色片為每個(gè)輸出像素賦予一個(gè) RGB 值(僅以 R、G 或 B 表示)。彩色濾波器陣列插值 (Color Filter Array interpolation)
RGB 到 YUV色域轉(zhuǎn)換,將 RGB 色域轉(zhuǎn)換為 HDMI 驅(qū)動(dòng)器優(yōu)選的 YUV 色域輸出格式。RGB 到 YCRCB色域轉(zhuǎn)換器 (RGB to YCRCB Color-Space Convertor)
將 YUV 從 4:4:4 格式重新縮放為 4:2:2 格式。 色度重采樣 (Chroma Resampler)
配置視頻 DMA 以傳輸圖像幀到 PS DDR。 AXI VDMA
配置同一視頻 DMA,以從 PS DDR 讀取圖像幀。 AXI VDMA
將 AXI Stream 轉(zhuǎn)換回并行格式。 AXIS 到視頻輸出
為輸出視頻時(shí)序提供時(shí)序參考生成器。 視頻時(shí)序控制器
除了確保系統(tǒng)正常運(yùn)行,我們還需要兩個(gè) AXI 互聯(lián)。一個(gè)是高性能 AXI 互聯(lián),另一個(gè)是通用AXI 互聯(lián),以及每個(gè)時(shí)鐘域所需的復(fù)位模塊。
圖像處理應(yīng)用需要一系列的時(shí)鐘域,大部分時(shí)鐘域我們可以使用 Zynq 內(nèi)部的 PS 提供給 PL的時(shí)鐘。就該應(yīng)用而言,我們需要下列時(shí)鐘:
108 MHz – 這是以 1280x1024 分辨率和 60 Hz幀速率輸出圖像所需的像素時(shí)鐘速率。
75 MHz – 用于存儲(chǔ)器映射的 AXI 和 AXI Lite 接口。
150 MHz – 用于圖像處理鏈,也稱為AXI Streaming時(shí)鐘。AXI Stream 時(shí)鐘的速率必須至少與像素速率相同。但是我們必須考慮處理鏈中的所有 IP 核的吞吐量。雖然大多數(shù)模塊能夠每時(shí)鐘周期處理一個(gè)像素,留出部分裕度并減少所需的緩存是明智的做法。
200 MHz – 提供給 Python 1300C CIS 設(shè)備作為基準(zhǔn)。
為實(shí)現(xiàn)像素時(shí)鐘,我們需要使用時(shí)鐘向?qū)?lái)生成該 108MHz 像素時(shí)鐘,因?yàn)樵摃r(shí)鐘需要極為準(zhǔn)確的設(shè)置。雖然在用 PL 架構(gòu)時(shí)鐘設(shè)置時(shí),75MHz和150MHz時(shí)鐘允許部分容差,但 200MHz時(shí)鐘也要求精確。與 108MHz 時(shí)鐘不同的是該時(shí)鐘可由 PL 架構(gòu)時(shí)鐘精確生成。
所使用的 IP 模塊的時(shí)鐘結(jié)構(gòu)如下表所示:
?
在 Vivavdo 方框圖編輯器中的整個(gè)實(shí)現(xiàn)方案如下面兩個(gè)圖所示。這兩個(gè)圖分別顯示的是圖像處理鏈的上游和下游。您還能夠看到使用通用 AXI 互聯(lián)和高性能 AXI 互聯(lián)實(shí)現(xiàn)的 ARM 內(nèi)核處理器的互聯(lián)情況。
圖2:EVK實(shí)例設(shè)計(jì) — 突出顯示的是上游圖像處理鏈
圖3:EVK實(shí)例設(shè)計(jì) — 突出顯示的是下游圖像處理鏈
一旦我們完成設(shè)計(jì)驗(yàn)證,并為AXI外設(shè)分配地址(可自動(dòng)完成)后,我們就能在 Vivado 2015.4 中構(gòu)建硬件并將其導(dǎo)入到 SDK 2015.4 軟件開(kāi)發(fā)環(huán)境中。我們需要在該環(huán)境中編寫一些簡(jiǎn)單軟件,讓系統(tǒng)啟動(dòng)并運(yùn)行。
在 SDK 內(nèi)部,我們不僅需要在 Zynq 內(nèi)配置設(shè)計(jì),還需要在使用設(shè)計(jì)之前在 EVK 上配置部分元素。記住在本實(shí)例中 PS 起著系統(tǒng)監(jiān)視和控制功能,因此必須對(duì)整個(gè)嵌入式視覺(jué)系統(tǒng)進(jìn)行配置,而不僅僅是在 Zynq 中配置 Vivado 設(shè)計(jì)。
我們需要開(kāi)發(fā)用于配置下列內(nèi)容的軟件:
使用SPI 接口的 Python 1300C 攝像頭
AXI Python 1300C 接口模塊
?AXI VDMA,從 DDR 內(nèi)存讀取和向 DDR 內(nèi)存寫入幀
AXI 彩色濾波器陣列
?用于 AD7511 的 HDMI 輸出設(shè)備。該設(shè)備使用 I2C 進(jìn)行配置
I2C 多路復(fù)用器及其連接的相關(guān)外設(shè)
用于控制 Python 1300C 設(shè)備電源軌的 I2C IO 擴(kuò)展器
該 EVK 使用 Zynq PS I2C 控制器對(duì) HDMI 輸出設(shè)備進(jìn)行配置,來(lái)對(duì) Python 設(shè)備供電。安富利還向我們提供了能用來(lái)控制 I2C 并進(jìn)行如下配置的 API:
ADV7511 – 用于 HDMI 輸出的 API
CAT9554 – 用于位于攝像頭模塊上的 I2C I/O 擴(kuò)展器的 API
TCA9548 – 用于位于 EVCC 上的 I2C 多路復(fù)用器的 API
PCA9534 – 用于位于 EVCC 上的 I2C IO 擴(kuò)展器的 API
OnSemi_Python_SW – 用于 Python 1300C 的 API
XAXIVDMA_EXT – 用于配置 VDMA 的 API
XIICPS_EXT – 用于驅(qū)動(dòng)外部 I2C 的 API
我們所需做的就是將這些 API 與賽靈思軟件 API 耦合,用于圖像處理鏈中的 IP,這樣我們就能快速創(chuàng)建軟件可執(zhí)行文件。要?jiǎng)?chuàng)建軟件應(yīng)用,我們需要將硬件設(shè)計(jì)導(dǎo)入到 SDK 中,為硬件創(chuàng)建板級(jí)支持包 (BSP)。該 BSP 內(nèi)置所有所需的賽靈思 API,在與安富利的 API 耦合后,就能夠驅(qū)動(dòng)圖像處理鏈中的硬件和 Zynq。
軟件本身需要執(zhí)行下列步驟:
初始化所有的 AXI 外設(shè)
?
為圖像傳感器軌加電
?
對(duì)安森美 Python 1300C、彩色濾波器陣列和 VDMA 進(jìn)行配置
?
完成這些步驟后,當(dāng)軟件運(yùn)行在 EVK 上您將看到圖像正被輸出到您所選定的 HDMI 監(jiān)控器上,如下圖所示。
圖4:使用演示系統(tǒng)抓取的居民區(qū)場(chǎng)景的一幀圖像
結(jié)論
在本文中我們介紹了嵌入式視覺(jué)系統(tǒng)的高級(jí)元素;如何簡(jiǎn)便快捷地使用軟件 API 和 IP 庫(kù)構(gòu)建嵌入式視覺(jué)系統(tǒng),如何把算法開(kāi)發(fā)的增值部分添加到圖像處理鏈中。
評(píng)論
查看更多