介紹
開發(fā)嵌入式視覺系統(tǒng)不需要使用昂貴的 FPGA 或 SoC、大型幀緩沖存儲器和外部攝像頭。
我們可以使用直接與 CMOS 傳感器連接的成本優(yōu)化的 FPGA / SoC 來開發(fā)非常強(qiáng)大的圖像處理系統(tǒng)。這允許創(chuàng)建一種解決方案,該解決方案不僅可以實(shí)現(xiàn)成本目標(biāo),而且還可以實(shí)現(xiàn)緊湊和節(jié)能。
直接與傳感器接口是帶有照相機(jī)的接口,因為我們已經(jīng)做了不同的先前。當(dāng)我們與相機(jī)接口時,我們通過 HDMI、CameraLink 等接收視頻信號,這是相當(dāng)直接的。
當(dāng)我們與圖像傳感器連接時,我們通常會以不同的格式接收圖像,例如 MIPI 或并行格式,在接收視頻之前,我們需要首先配置成像器以按照我們的需要進(jìn)行操作。
通常,成像器需要通過 I2C 或 SPI 進(jìn)行配置,并且通過接口發(fā)送的命令數(shù)量可能很大。
為了演示我們?nèi)绾螌鞲衅髋c成本優(yōu)化的 FPGA 集成到該項目中,我們將研究集成
TDNext 1.26 兆像素 Pmod
藝術(shù)S7-50
由于 Arty S7 不直接在板上提供 HDMI 或其他視頻輸出,因此本示例將使用 Avnet 10 英寸觸摸屏。然而,這是可選的輸出最終圖像的另一個選項是Digilent Pmod VGA。該 Pmod 還可用于實(shí)施成本非常低的解決方案。
與 TDNext Pmod 的接口非常簡單,可以分為視頻和配置兩個元素。
視頻接口由 10 位像素(拆分 8 位和 2 位 LSB)幀和行有效、像素時鐘和參考時鐘 (24 MHz) 組成。
配置接口由連接到成像設(shè)備的 I2C 和 I2C IO 擴(kuò)展器組成,用于生成對成像器的復(fù)位。
該解決方案的架構(gòu)如下,將使用軟核處理器通過 I2C 配置成像器。然而,雖然圖像處理路徑將在 FPGA 內(nèi)實(shí)現(xiàn),但由于這是一個低成本應(yīng)用,該解決方案不會在 DDR 存儲器中實(shí)現(xiàn)外部幀緩沖器,而是圖像處理流水線將完全在 FPGA 中實(shí)現(xiàn)。
該設(shè)計還將使用軟核處理器來控制視頻時序和圖像處理路徑的其他相關(guān)配置任務(wù)。
背景
TDNext 是一種彩色成像器,這意味著該成像器應(yīng)用了拜耳模式,可以過濾每個像素的波長。這意味著在積分期間,每個像素僅累積紅色、綠色或藍(lán)色波長的光子。
在積分時間完成時,每個像素被讀出為 8 位或 10 位像素。該像素值稱為 RAW8 或 RAW10 像素。為了重新創(chuàng)建彩色圖像,使用去拜耳算法組合包含不同波長像素的周圍像素的值。
Vivado 構(gòu)建
我們需要做的第一件事是創(chuàng)建 Vivado 平臺,這將接收來自 TDNext Pmod 的圖像。
為了創(chuàng)建框圖,我們將主要使用 Vivado 庫中的 IP 核,但我們將使用攝像頭接口塊和 Avnet 庫中的輸出塊。
第一步是安裝板定義文件,這使 Vivado 能夠了解 Arty S7 的配置。
下載后,這些文件應(yīng)安裝在以下路徑下的 Vivado 目錄中:
<安裝路徑>/Vivado/<版本>/data/boards/board_files/
這將允許您選擇 Arty S7 板作為創(chuàng)建新 Vivado 項目的目標(biāo)板。
安裝好電路板后,下一步是創(chuàng)建新項目、框圖并創(chuàng)建 MicroBlaze 系統(tǒng)。
隨著 MicroBlaze 系統(tǒng)的啟動和運(yùn)行,下一步是添加視頻處理管道。處理鏈將使用以下 IP 塊
CAM 接口 - 與 TDNext 視頻接口接口
Video to AXIS - 將并行視頻轉(zhuǎn)換為 AXI Streaming 格式
Sensor Demosaic - 將代表 R、G 或 B 的 RAW 像素值轉(zhuǎn)換為 24 位 RGB 格式
Video Timing Generator - 生成輸出格式的視頻時序信號
AXI Stream to Video Out - 將 AXI Stream 轉(zhuǎn)換為并行視頻
ZED ALI3 控制器 - 驅(qū)動 10 英寸觸摸屏的 IP 模塊
AXI IIC - 連接到 MicroBlaze 這將用于配置成像器
AXI UART - 連接到 MicroBlaze,用于向用戶報告系統(tǒng)狀態(tài)
如果我們使用 Pmod VGA,我們不需要使用 ZED ALI3 控制器 IP 塊。
在我們添加 Zed ALI3 和 CAM 接口之前,我們需要重新配置 IP 核,以便能夠包含在 Spartan 7 設(shè)計中。我們從 IP 目錄視圖執(zhí)行此操作,選擇所需的 IP 核并單擊 packager 中的編輯 IP。
這將打開一個新項目并使您能夠選擇可比性選項卡并添加對 Spartan 7 設(shè)備的支持。重新打包設(shè)計并更新 Vivado 項目中的 IP 庫。
一旦 IP 升級為支持 Spartan 7,我們就可以完成設(shè)計。完整的方框圖應(yīng)如下所示。
與之前基于異構(gòu) SoC 的示例不同,該示例使用外部幀緩沖區(qū)。此示例不會使用 VDMA 從外部幀緩沖區(qū)讀取和寫入,這種方法需要 AXIS 到 Video 和 VTC 的不同配置。
通常情況下,AXIS to video 配置為主控,VTC 不受控制。然而,在這種方法中,AXIS to video 被配置為從設(shè)備,并且 VTC 發(fā)生器時鐘使能受到控制。
這種方法允許 AXIS 到視頻 IP 模塊通過啟用和禁用 VTC 來控制同步的時序,因此它們與處理管道中的同步時序相匹配。
在 AXI Stream 中,幀的開始由 TUser 指示,行尾由 TLast 指示。
IP 塊的關(guān)鍵定制是:-
視頻輸入到 AXI 4 流
傳感器去馬賽克設(shè)置
AXI IIC 設(shè)置
在設(shè)計中我還加入了幾個集成邏輯分析儀(ILA),以實(shí)現(xiàn)系統(tǒng)狀態(tài)的內(nèi)部監(jiān)控和調(diào)試。
項目完成后Arty S7-50的總利用率如下圖所示。
我們可以使用額外的資源來實(shí)現(xiàn)使用 HLS 的圖像處理算法是必要的。如果我們想節(jié)省資源,我們可以使用 MicroBlaze 的最小占用空間并移除 ILA。
在 SDK 中編寫軟件
生成 Vivado 硬件后,下一步是編寫應(yīng)用軟件,該軟件將在視頻處理內(nèi)核上配置成像器和 IP 內(nèi)核。
因此,該軟件將執(zhí)行以下操作
初始化 AXI IIC、VTC 和中斷控制器
設(shè)置中斷控制器以生成 AXI 相關(guān)中斷 - 這包括三個中斷服務(wù)例程。IIC 發(fā)送、接收和狀態(tài)各一個。
為 10 英寸顯示器配置 VTC 上的計時
通過 I2C 重置相機(jī)并點(diǎn)亮 PMOD 上的 LED
通過 I2C 檢測攝像頭,我們正在尋找檢測 MT9M114
通過 I2C 鏈接初始化相機(jī) - 這將需要幾秒鐘來編寫所有命令
為了初始化成像器,我已將 TDM114 示例設(shè)計提供的基于 Zynq 的庫轉(zhuǎn)換為可用于 AXI IIC 的格式。
相機(jī)初始化后,我們將能夠在連接到 AXI 流組件的視頻流的 ILA 上看到視頻。
監(jiān)控TDNext Pmod 背面的I2C 通信顯示Arty S7 和TDNext 之間的通信。
檢測到攝像頭后,應(yīng)用程序?qū)⑾螺d多個 I2C 攝像頭配置設(shè)置。
將使用 AXI UART 報告進(jìn)度
一旦相機(jī)被初始化,我們就可以使用 ILA 來驗證成像器正在生成視頻,并且它是我們配置的分辨率。
我們通過使用 ILA 并直接檢查在 FPGA 中接收到的視頻來做到這一點(diǎn)。
上圖顯示了 1280 像素的線寬,這正是我們所期望的。
接收到的像素從并行格式轉(zhuǎn)換為 AXI 流。
AXI Stream 是一種單向總線,用于將數(shù)據(jù)從主機(jī)傳輸?shù)綇臋C(jī),作為數(shù)據(jù)流,它不包含地址通道。為了控制流和通過 AXI 流傳輸視頻時序信息,使用以下信號
TReady - 準(zhǔn)備好接收數(shù)據(jù)時由下游外設(shè)置位
TValid - 當(dāng)輸出數(shù)據(jù)有效時由發(fā)送外設(shè)斷言
TUser - 為幀開始發(fā)出
TLast - 為行尾發(fā)布
第二個 ILA 可用于確保正確生成 AXI 流。
由于我們沒有 VDMA,重要的是 AXIS 流上的視頻輸出是一個連續(xù)塊,并且 TValid 在活動像素期間不會斷言和取消斷言。
我們可以通過將像素時鐘用于圖像處理鏈來確保 Tvalid 是連續(xù)的。
該項目中使用的庫 API 如下,但包含 IIC 配置數(shù)據(jù)的 camera_initial.h 除外。Xilinx 根據(jù)硬件配置提供所有其他頭文件。
設(shè)備地址和標(biāo)識符
應(yīng)用程序的主循環(huán)可以在下面看到
int main()
{
u32 Status;
XIic_Config *iic_conf;
XVtc VtcInst;
XVtc_Config *vtc_config;
XVtc_Timing vtcTiming;
XVtc_SourceSelect SourceSelect;
XV_demosaic_Config *mosaic_config;
init_platform();
printf("www.adiuvoengineering.com?S7 Imager example ");
mosaic_config = XV_demosaic_LookupConfig(XPAR_XV_DEMOSAIC_0_DEVICE_ID);
XV_demosaic_CfgInitialize(&mosaic,mosaic_config,mosaic_config->BaseAddress);
XIntc_Initialize(&InterruptController, int_dev);
SetUpInterruptSystem();
iic_conf = XIic_LookupConfig(IIC_dev);
Status = XIic_CfgInitialize(&iic, iic_conf, iic_conf->BaseAddress);
if (Status != XST_SUCCESS) {
printf("XIic initial is fail ") ;
return XST_FAILURE;
}
XIic_SetSendHandler(&iic, &iic, (XIic_Handler) SendHandler);
XIic_SetRecvHandler(&iic, &iic, (XIic_Handler) ReceiveHandler);
XIic_SetStatusHandler(&iic, &iic,(XIic_StatusHandler) StatusHandler);
vtc_config = XVtc_LookupConfig(XPAR_VTC_0_DEVICE_ID);
XVtc_CfgInitialize(&VtcInst, vtc_config, vtc_config->BaseAddress);
vtcTiming.HActiveVideo = 1280;
vtcTiming.HFrontPorch = 65;
vtcTiming.HSyncWidth = 55;
vtcTiming.HBackPorch = 40;
vtcTiming.HSyncPolarity = 0;
vtcTiming.VActiveVideo = 800;
vtcTiming.V0FrontPorch = 7;//8;
vtcTiming.V0SyncWidth = 4;
vtcTiming.V0BackPorch = 12;
vtcTiming.V1FrontPorch = 7;
vtcTiming.V1SyncWidth = 4;
vtcTiming.V1BackPorch = 12;
vtcTiming.VSyncPolarity = 0;
vtcTiming.Interlaced = 0;
memset((void *)&SourceSelect, 0, sizeof(SourceSelect));
SourceSelect.VBlankPolSrc = 1;
SourceSelect.VSyncPolSrc = 1;
SourceSelect.HBlankPolSrc = 1;
SourceSelect.HSyncPolSrc = 1;
SourceSelect.ActiveVideoPolSrc = 1;
SourceSelect.ActiveChromaPolSrc= 1;
SourceSelect.VChromaSrc = 1;
SourceSelect.VActiveSrc = 1;
SourceSelect.VBackPorchSrc = 1;
SourceSelect.VSyncSrc = 1;
SourceSelect.VFrontPorchSrc = 1;
SourceSelect.VTotalSrc = 1;
SourceSelect.HActiveSrc = 1;
SourceSelect.HBackPorchSrc = 1;
SourceSelect.HSyncSrc = 1;
SourceSelect.HFrontPorchSrc = 1;
SourceSelect.HTotalSrc = 1;
XVtc_RegUpdateEnable(&VtcInst);
XVtc_SetGeneratorTiming(&VtcInst,&vtcTiming);
XVtc_SetSource(&VtcInst, &SourceSelect);
XVtc_EnableGenerator(&VtcInst);
XIic_Reset(&iic);
PCA9534_CTRL ();
Detect_Camera();
Soft_Reset_Camera();
Initial_Camera();
XV_demosaic_Set_HwReg_width(&mosaic,0x500);
XV_demosaic_Set_HwReg_height(&mosaic,0x31f);
XV_demosaic_Set_HwReg_bayer_phase(&mosaic,0x1);
XV_demosaic_EnableAutoRestart(&mosaic);
XV_demosaic_Start(&mosaic);
while(1){
}
cleanup_platform();
return 0;
}
我需要調(diào)整一些設(shè)置以增加集成時間,但是,基本圖像處理管道正在按我們的預(yù)期工作。
結(jié)論
很容易創(chuàng)建一個視覺處理系統(tǒng),它直接與成像器一起工作,而不是相機(jī)。隨著處理鏈的顯著減少,這通常允許更具???????成本效益和潛在的響應(yīng)更快的解決方案。
審核編輯:黃飛
?
評論
查看更多