電路城福利:電路城經(jīng)與黑金溝通,給予本項目板卡優(yōu)惠支持,有意愿參與本項目的電路城用戶,購買黑金板卡可有優(yōu)惠,詳情請加qq(453972551)了解。
各位工程師朋友,同學(xué)們大家好!我是本期“來實戰(zhàn)”項目《運動目標(biāo)追蹤系統(tǒng)》的執(zhí)行官。本項目由電路城發(fā)起,由ALINX贊助的黑金國產(chǎn)FPGA板卡Logos系列PGL22G學(xué)習(xí)板實現(xiàn)。
我是一個熱愛技術(shù)的在校學(xué)生。希望可以通過本次的項目來幫助更多的同學(xué),給予一個機(jī)會來了解什么是真正的實戰(zhàn)項目,也讓之前沒有競賽經(jīng)驗的朋友了解一下,競賽對于我們學(xué)生來說并沒有那么遠(yuǎn)。幫助更多的電子專業(yè)的同學(xué)找到學(xué)習(xí)的方向,更順利的進(jìn)入這個行業(yè),為電子行業(yè)做出一份自己的貢獻(xiàn)。許多同學(xué)在學(xué)校期間不去做項目的原因并不是不愿意去做,而是沒有方向。其實大項目就可以通過競賽來獲得,競賽中的一些命題項目可以給予你很多靈感,有了方向之后,即使是個大項目,他也是由一個一個小部分組成的,一步一步完成一個個小項目,自己的大工程不久也就成功了。項目本身的意義可能是在做保護(hù)區(qū)的攝像頭,捕捉動態(tài)視頻;也可以在監(jiān)控中做一些應(yīng)用。更重要的意義就是給廣大同學(xué)們一個學(xué)習(xí)視頻處理的機(jī)會,讓想學(xué)而不知道怎么去學(xué)的同學(xué)一個模板。
很多在最初接觸FPGA的同學(xué)都有這個問題,甚至以為FPGA和單片機(jī)一樣下板子燒代碼。其實不是這樣的,F(xiàn)PGA不是單片機(jī),首先FPGA和單片機(jī)的區(qū)別,本質(zhì)上是軟件和硬件的區(qū)別,F(xiàn)PGA更偏向于硬件電路,而單片機(jī)更偏于軟件。單片機(jī)是一種微處理器,類似于電腦CPU的,它一般采用的是哈佛總線結(jié)構(gòu),或者馮諾依曼結(jié)構(gòu),對單片機(jī)的編程很大程度上要考慮到它的結(jié)構(gòu)和各個寄存器的作用,而FPGA 它的結(jié)構(gòu)是查找表結(jié)構(gòu),其程序不用去太考慮芯片的結(jié)構(gòu),要注意的是時序上問題,它的結(jié)構(gòu)比較復(fù)雜,功能也很強大,一般應(yīng)用在通信領(lǐng)域等比較高端的場合,單片機(jī)是一個微控制器,通過加載模塊軟件來實現(xiàn)某種功能,是成型的芯片;FPGA是用來設(shè)計芯片的芯片。FPGA由于是硬件電路,運行速度直接取決于晶振速度,系統(tǒng)穩(wěn)定,特別適合高速接口電路。單片機(jī)由于是單線程,哪怕是常用的M3系列流水線也是單線程執(zhí)行,程序語句需要等待單片機(jī)周期才能執(zhí)行。單片機(jī)設(shè)計屬軟件范疇;它的硬件(單片機(jī)芯片)是固定的,通過軟件編程語言描述軟件指令在硬件芯片上的執(zhí)行;
FPGA開發(fā)的語言是Verilog HDL。HDL代表的就是硬件描述語言,描述就代表他并不是一個開發(fā)性的語言。相比C語言開發(fā),Verilog更像是你先設(shè)計好電路,再用Verilog描述出來你的設(shè)計。而對于一個完整的FPGA工程應(yīng)包含以下幾個步驟:算法實現(xiàn),模塊化,模塊的硬件電路設(shè)計,硬件描述語言書寫,小模塊進(jìn)行仿真,總模塊的連接,總體工程的仿真,板級驗證。下面我們就進(jìn)入正題......
步驟一:FPGA硬件資源與算法設(shè)計
1.FPGA硬件資源 介紹
首先感謝黑金ALINX提供的開發(fā)板對本項目的大力支持,期望以后能有更多的機(jī)會合作。對于黑金國產(chǎn)FPGA板卡Logos系列PGL22G學(xué)習(xí)板,它配備了以下資源:
系統(tǒng)邏輯部分由ov5640驅(qū)動模塊、RGB轉(zhuǎn)Ycbcr模塊、存儲控制模塊、HDMI驅(qū)動模塊、圖像處理模塊、追蹤控制模塊、sim900a驅(qū)動模塊共同組成。由OV5640攝像頭采集圖像,經(jīng)過RGB轉(zhuǎn)YCbCr模塊完成顏色空間轉(zhuǎn)換,為了配合幀差法的數(shù)據(jù),將數(shù)據(jù)進(jìn)行掩碼然后經(jīng)由DDR3控制器模塊控制存入DDR3中,通過HDMI時序從DDR3中取出數(shù)據(jù),此時取出的每個16bit數(shù)據(jù)同時包含了相鄰兩幅圖像的灰度信息,高8位為第n幀圖像的某個像素點灰度值,低8位為第n+1幀圖像對應(yīng)像素點的灰度值。圖像處理模塊將取出的數(shù)據(jù)進(jìn)行預(yù)處理和幀差法計算得到運動目標(biāo)的位置信息,追蹤控制模塊根據(jù)運動目標(biāo)的位置相對于圖像中心的偏移通過控制舵機(jī)轉(zhuǎn)動來調(diào)整OV5640攝像頭的方向完成追蹤。攝像頭使用黑金ALINX視頻套餐中的OV5640攝像頭;同套餐的還贈送一個屏幕,也非常適合學(xué)習(xí)視頻處理的工程。舵機(jī)模塊是使用的SC90,來完成攝像頭的轉(zhuǎn)動的,該模塊看上去很簡單,但是他和攝像頭一起組合使用就非常炫酷!
2.算法設(shè)計
(一)項目簡介與項目難點
首先FPGA的基礎(chǔ)操作,以及Verilog基礎(chǔ)語法就不再贅述。
項目簡介在前面也已經(jīng)講說,這里只放一個整體框圖來表現(xiàn)。這個框圖為了便于大家理解已經(jīng)進(jìn)行了簡化,大抵說白了就是將攝像頭采集到的數(shù)據(jù)存起來,再把圖像處理清晰,去除噪聲。最后識別出在動的東西,把采集到的圖像放在顯示屏上,并標(biāo)明哪個部分是正在運動的。
項目的難點:項目本身的難點在于驅(qū)動起來攝像頭,一個類IIC協(xié)議接口的書寫,以及對攝像頭寄存器的配置。驅(qū)動SDRAM/DDR,將采集到的數(shù)據(jù)寫進(jìn)存儲單元中。實現(xiàn)簡單的圖像處理算法來優(yōu)化采集到的圖像,識別物體的邊緣。最后抓捕再顯示出來,驅(qū)動VGA或HDMI接口將數(shù)據(jù)傳輸至顯示屏上顯示出來。
(二)整體流程
首先上電之后對各個模塊的寄存器堆進(jìn)行配置,計數(shù)器進(jìn)行初始化。之后由OV5640攝像頭采集圖像,經(jīng)過RGB轉(zhuǎn)YCbCr模塊完成顏色空間轉(zhuǎn)換,為了配合幀差法的數(shù)據(jù),將數(shù)據(jù)進(jìn)行掩碼然后經(jīng)由DDR3控制器模塊控制存入DDR3中,通過HDMI時序從DDR3中取出數(shù)據(jù),此時取出的每個16bit數(shù)據(jù)同時包含了相鄰兩幅圖像的灰度信息,高8位為第n幀圖像的某個像素點灰度值,低8位為第n+1幀圖像對應(yīng)像素點的灰度值。圖像處理模塊將取出的數(shù)據(jù)進(jìn)行預(yù)處理和幀差法計算得到運動目標(biāo)的位置信息,追蹤控制模塊根據(jù)運動目標(biāo)的位置相對于圖像中心的偏移通過控制舵機(jī)轉(zhuǎn)動來調(diào)整OV5640攝像頭的方向完成追蹤。
(三)算法基礎(chǔ)
由于我們做的是一個圖像,所以要對基礎(chǔ)的圖像算法進(jìn)行簡單學(xué)習(xí)。我們使用的算法主要有均值濾波,中值濾波,Sobel邊緣檢測及RGB轉(zhuǎn)YCbCr。
1.均值濾波與中值濾波
首先何謂濾波?圖像濾波,即在盡量保留圖像細(xì)節(jié)特征的條件下對目標(biāo)圖像的噪聲進(jìn)行抑制,是圖像預(yù)處理中不可缺少的操作,其處理效果的好壞將直接影響到后續(xù)圖像處理和分析的有效性和可靠性。消除圖像中的噪聲成分叫作圖像的平滑化或濾波操作。信號或圖像的能量大部分集中在幅度譜的低頻和中頻段是很常見的,而在較高頻段,感興趣的信息經(jīng)常被噪聲淹沒。因此一個能降低高頻成分幅度的濾波器就能夠減弱噪聲的影響。
圖像濾波的目的有兩個:一是抽出對象的特征作為圖像識別的特征模式;另一個是為適應(yīng)圖像處理的要求,消除圖像數(shù)字化時所混入的噪聲。
而對濾波處理的要求也有兩條:一是不能損壞圖像的輪廓及邊緣等重要信息;二是使圖像清晰視覺效果好。
而我們今天面對的主要為椒鹽噪聲,椒鹽噪聲是數(shù)字圖像的一個常見噪聲,就是在圖像上隨機(jī)出現(xiàn)黑色白色的像素。椒鹽噪聲是一種因為信號脈沖強度引起的噪聲。RGB圖像上,每一個像素點都是三段數(shù)字,分別對應(yīng)R,G,B三種顏色在灰白圖像中,椒鹽噪聲若果是黑點的話,就是指這一點的像素值明顯低于周圍像素點的值,而白點就是明顯高于周圍的像素值。而對于這種噪聲,只要讓他與周圍的值相持平皆可以消除。中值濾波和均值濾波就是根據(jù)這種方法來消除,每個像素點周圍都有8個像素,如果使用周圍8個像素的平均值來代替這個像素點的像素值,就是均值濾波的基本方法;如果使用8個像素點的中值來代替這個像素點的像素值,就是中值濾波的基本方法。
要做這個處理,核心就是要搭建3x3矩陣。如何搭建3x3矩陣呢?我們有三種方法:
1.通過2個或者3個RAM的存儲來實現(xiàn)3X3像素窗口;
2.通過2個或者3個FIFO的存儲來實現(xiàn)3X3像素窗口;
3.通過2行或者3行Shift_RAM的存儲來實現(xiàn)3X3像素窗口;
以shift_ram為例,shift_ram就是移位寄存器,如圖:
左方數(shù)據(jù)輸入,N是每行的像素點數(shù),每行輸出的就是要的矩陣。
2.Sobel邊緣檢測
在圖像處理中,邊緣是一幅圖像中最基本的特征,每幅圖像的邊緣包含了用于識別的有用信息,是圖像分析和模式識別的主要特征提取手段。在模式識別或進(jìn)行其他的中,在很多方法來識別,其中一種方法就是識別出來圖像邊緣。在圖像中,一幅圖像的“臨界”表示為圖像上亮度顯著變化的地方,邊緣指的是一個區(qū)域的結(jié)束,也是另一個區(qū)域的開始?!斑吘夵c”指的是圖像中具有坐標(biāo)[x,y],且處在強度顯著變化的位置上的點。常用的邊緣檢測算法大多是以原始圖像灰度值為基礎(chǔ),通過考察圖像的每個像素的某個鄰域內(nèi) 灰度的變化,利用邊緣一階或二階導(dǎo)數(shù)的規(guī)律來檢測邊緣。下圖左邊為原始的黑白灰度的圖像,通過邊緣檢測算法后變成了右邊的圖像。
sobel 是一個梯度的計算,如下圖所示,是 x 和 y 方向的 3x3 窗口的卷積。
使用算式
來計算目標(biāo)點的卷積值:
這里注意一定是絕對值,要大于0.
計算完成以后,要進(jìn)行簡單的二值化處理,將 sobel 值和閾值對比,產(chǎn)生黑白的二值化圖像。 將大于閾值設(shè)置為與背景色相反的圖像。
利用此即可確定圖像中各物體的邊緣。
3. RGB轉(zhuǎn)YCbCr
攝像頭采集的RGB565格式數(shù)據(jù)為16比特,SDRAM不能同時將兩幀RGB圖像存儲。因此在存入SDRAM前先將RGB格式轉(zhuǎn)換為YCbCr格式并提取亮度分量作為灰度圖像。YCbCr是通過有序的三元組來表示的,三元由Y(Luminance)、Cb(Chrominance-Blue)和Cr(Chrominance-Red)組成,其中Y表示顏色的明亮度和濃度,而Cb和Cr則分別表示顏色的藍(lán)色濃度偏移量和紅色濃度偏移量。人的肉眼對由YCbCr色彩空間編碼的視頻中的Y分量更敏感,而Cb和Cr的微小變化不會引起視覺上的不同,根據(jù)該原理,通過對Cb和Cr進(jìn)行子采樣來減小圖像的數(shù)據(jù)量,使得圖像對存儲需求和傳輸帶寬的要求大大降低,從而達(dá)到在完成圖像壓縮的同時也保證了視覺上幾乎沒有損失的效果,進(jìn)而使得圖像的傳輸速度更快,存儲更加方便。我們要的到灰度圖像,首先要將采集到的彩色圖像轉(zhuǎn)化為YCbCr。其轉(zhuǎn)換公式如下:
步驟二:視頻圖像采集與輸出模塊的接口時序設(shè)計
本項目的一大難點,就是這么多模塊如何驅(qū)動,接口是是用什么協(xié)議驅(qū)動的。本步驟主要來一點一點的啃各個模塊的接口時序與協(xié)議參數(shù)。
1.攝像頭模塊的時序與驅(qū)動
首先是攝像頭采集模塊,我們采用 500 萬像素的 OV5640 攝像頭模組(模塊型號:AN5640)為大家顯示更高分辨率的視頻畫面。OV5640 攝像頭模組最大支持 QSXGA (2592x1944)的拍照功能,支持 1080P、720P、VGA、QVGA 視頻圖像輸出。
攝像頭模塊的驅(qū)動實際上就是如何配置寄存器和如何按幀按行的讀取像素點。攝像頭是通過配置各個寄存器中參數(shù),來確定攝像頭運行的模式。OV5640 的寄存器配置是通過 FPGA 的 I2C(也稱為 SCCB 接口)接口來配置。用戶需要配置正確的寄存器值讓 OV5640 輸出我們需要的圖像格式,我們把攝像頭輸出分辨率和顯示設(shè)備分辨率配置成一樣的, OV5640 的攝像頭輸出的數(shù)據(jù)格式在以下的 0x4300 的寄存器里配置,我們將 OV5640 配置成 RGB565 的輸出格式。如ALINX給予的官方版文檔中書寫的:
關(guān)于 OV5640 的寄存器還有很多很多,但很多寄存器用戶無需去了解,寄存器的配置用戶可以按照 OV5640 的應(yīng)用指南來配置就可以了。如果您想了解更多的寄存器的信息,可以參考OV5640 的 datasheet 中的寄存器說明。在傳輸這種信息時,我們使用SCCB(IIC)協(xié)議來配置攝像頭寄存器。
IIC的傳輸文件如下所示:
對于IIC,很多接觸過電子、單片機(jī)的同學(xué)都一定不陌生。下面截取黑金教程中對IIC(下稱為I2C)
I2C 總線通信過程中出現(xiàn)的幾種信號狀態(tài)和時序迚行分析。
①總線空閑狀態(tài)
I2C 總線總線的 SDA 和 SCL 兩條信號線同時處于高電平時,規(guī)定為總線的空閑狀態(tài)。此時各個器件的輸出級場效應(yīng)管均處在截止?fàn)顟B(tài),即釋放總線,由兩條信號線各自的上拉電阻把電平拉高。
②啟動信號(Start)
在時鐘線 SCL 保持高電平期間,數(shù)據(jù)線 SDA 上的電平被拉低(即負(fù)跳變),定義為 I2C 總線總線的啟動信號,它標(biāo)志著一次數(shù)據(jù)傳輸?shù)拈_始。啟動信號是由主控器主動建立的,在建立該信號前 I2C 總線必須處于空閑狀態(tài),如下圖所示。
③停止信號(Stop)
在時鐘線 SCL 保持高電平期間,數(shù)據(jù)線 SDA 被釋放,使得 SDA 返回高電平(即正跳變),稱為 I2C 總線的停止信號,它標(biāo)志著一次數(shù)據(jù)傳輸?shù)慕K止。停止信號也是由主控器主動建立的,建立該信號乊后,I2C 總線將返回空閑狀態(tài)。
④數(shù)據(jù)位傳送
在 I2C 總線上傳送的每一位數(shù)據(jù)都有一個時鐘脈沖相對應(yīng)(戒同步控制),即在 SCL 串行時鐘的配合下,在 SDA 上逐位地串行傳送每一位數(shù)據(jù)。迚行數(shù)據(jù)傳送時,在 SCL 呈現(xiàn)高電平期間,SDA 上的電平必須保持穩(wěn)定,低電平為數(shù)據(jù) 0,高電平為數(shù)據(jù) 1。只有在 SCL 為低電平期間,才允許 SDA 上的電平改變狀態(tài)。
⑤應(yīng)答信號(ACK 和 NACK)
I2C 總線上的所有數(shù)據(jù)都是以 8 位字節(jié)傳送的,収送器每収送一個字節(jié),就在時鐘脈沖 9 期間釋放數(shù)據(jù)線,由接收器反饋一個應(yīng)答信號。應(yīng)答信號為低電平時,規(guī)定為有效應(yīng)答位(ACK 簡稱應(yīng)答位),表示接收器已經(jīng)成功地接收了該字節(jié);
應(yīng)答信號為高電平時,規(guī)定為非應(yīng)答位(NACK),一般表示接收器接收該字節(jié)沒有成功。對
于反饋有效應(yīng)答位 ACK 的要求是,接收器在第 9 個時鐘脈沖乊前的低電平期間將 SDA 線拉低,并確保在該時鐘的高電平期間為穩(wěn)定的低電平。如果接收器是主控器,則在它收到最后一個字節(jié)后,収送一個 NACK 信號,以通知被控収送器結(jié)束數(shù)據(jù)収送,并釋放 SDA 線,以便主控接收器収送一個停止信號。
2.攝像頭模塊硬件語言描述
根據(jù)我們的時序,可以寫Verilog代碼了。由于他也并不是一個核心代碼,就不再費勁的為大家寫了。在開源網(wǎng)站“http://opencores.org/”
上我們可以找到很多非常好的代碼,這些代碼大部分都提供詳細(xì)的...
再說回攝像頭,除過攝像頭寄存器堆,剩下的要點就是像素數(shù)據(jù)傳輸。
攝像頭的像素點信息是按行發(fā)送的,也就說依次發(fā)送一行信息,發(fā)送信息的使能信號為HREF 信號。HREF 信號為高時輸出一行的圖像數(shù)據(jù),輸出數(shù)據(jù)在 PCLK 的上升沿的時候有效。也就是在HREF為高的時候,每個PCLK的上升沿時候把數(shù)據(jù)輸出出去。因為 RGB565 顯示每個像數(shù)為 16bit, 但 OV5640 每個 PCLK 輸出的是 8bit,所以每個圖像的像數(shù)分兩次輸出,第一個 Byte 輸出為 R4~R0 和 G5~G3, 第二個 Byte 輸出為 G2~G0 和 B4~B0,將前后 2 個字節(jié)拼接起來就是 16Bit RGB565 數(shù)據(jù)。
根據(jù)時序圖,我們來書寫讀取攝像頭數(shù)據(jù)的文件。調(diào)試攝像頭的第一個問題在于視頻同時讀寫,如何做到讀寫不沖突?為了不出現(xiàn)顯示的問題,在設(shè)計幀讀寫模塊時,所有幀基地址選擇(最大 4 幀選擇),每次讀視頻幀地址和正在寫的幀地址是不同的,而是上次寫入一幀數(shù)據(jù)的地址,這樣就可以避免讀寫沖突,避免視頻畫面裂開錯位。但是注意采用了上述拆分?jǐn)?shù)據(jù)之后,要寫一個模塊模塊完成攝像頭輸入的 2 個 8bit 數(shù)據(jù)轉(zhuǎn)換到一個 16bit 數(shù)據(jù)(一個像素),數(shù)據(jù)位寬變成 2 倍,時鐘頻率不變,所以 16bit 數(shù)據(jù)是隔一個時鐘周期有效,并不是每個時鐘一直有效。要檢測的是行場信號,首先要檢測HREF信號的上升沿,每個上升沿到來的時候就是新的一行數(shù)據(jù)到來。之后每隔時鐘上升沿檢測HREF信號是否為高,如果HREF信號為高,則接收這個數(shù)據(jù)。完成這個操作的代碼如下:
攝像頭讀寫模塊通過判斷攝像頭的列同步信號 cmos_vsync 的上升沿,生成 ov5640數(shù)據(jù)寫入的請求信號,表示一幀圖像開始寫入請求。另外生成 write_addr_index 寫地址選擇和read_addr_index 讀地址選擇,這里 read_addr_index 的值會比 write_addr_index 的值延遲一幀,使得讀和寫的地址不沖突
3.HDMI接口時序與驅(qū)動
配置好攝像頭,我們來配置HDMI接口。
HDMI 顯示器掃描方式和我們更加熟悉的VGA相似,從屏幕左上角一點開始,從左向右逐點掃描,每掃描完一行,電子束回到屏幕的左邊下一行的起始位置,在這期間,CRT 對電子束進(jìn)行消隱,(每行開頭和結(jié)束有幾個數(shù)據(jù)是不顯示的)每行結(jié)束時,用行同步信號進(jìn)行同步;當(dāng)掃描完所有的行,形成一幀,用場同步信號進(jìn)行場同步,并使掃描回到屏幕左上方,同時進(jìn)行場消隱,開始下一幀。完成一行掃描的時間稱為水平掃描時間,其倒數(shù)稱為行頻率;完成一幀(整屏)掃描的時間稱為垂直掃描時間,其倒數(shù)稱為場頻率,即刷新一屏的頻率,常見的有 60Hz,75Hz 等等。標(biāo)準(zhǔn)的顯示的場頻 60Hz。時鐘頻率:以1024x768@59.94Hz(60Hz)為例,每場對應(yīng) 806 個行周期,其中 768 為顯示行。每顯示行包括 1344 點時鐘,其中 1024 點為有效顯示區(qū)。由此可知:需要點時鐘頻率:806*1344*60約 65MHz。
上圖看上去是一個二維的,實際上橫向的一個信號與縱向的一個信號,橫向的信號就是行信號,和攝像頭一樣,每當(dāng)行信號HSync的一個脈沖,即新的一行開始了。但是也不是脈沖一結(jié)束就是數(shù)據(jù)像素點,而是一串沒有意義的數(shù)據(jù)。講起來很繞,其實就是人眼睛會有留影,為了消除這些影子,每行開頭和每幀開頭設(shè)置一串供消影的數(shù)據(jù)。幀信號VSync也是每個脈沖到來,也是新的一幀到來了。根據(jù)這個信號我們來區(qū)別上一張圖像和這一張圖像的邊界。
所以我們在編寫Verilog 時要注意這些參數(shù),只有確定好這些參數(shù)才能在HDMI屏幕上顯示出圖像。
我們使用的600*800像素的上述參數(shù)如下:
dvi_encoder 模塊中包含兩個模塊 encode 和 serdes_4b_10to1 模塊,實現(xiàn) RGB 格式的圖像轉(zhuǎn)化成 TMDS 差分輸出,來驅(qū)動 HDMI 顯示。
1). encode: 紅,綠,藍(lán)的 8 位視頻數(shù)據(jù)及時鐘編碼成 10 位的 TMDS 視頻數(shù)據(jù)。關(guān)于編碼的原因和方法我們已經(jīng)在前面介紹過,具體如何實現(xiàn),可以參考下圖
TMDS視頻數(shù)據(jù)編碼(TMDS Video Data Coding)是將像素的8位數(shù)據(jù)轉(zhuǎn)化成10個位的字符,但他不是主流的8b/10b編碼方式。其編碼需兩道過程:首先將8位轉(zhuǎn)換到9位,將位的轉(zhuǎn)換最小化。轉(zhuǎn)換最小化可以降低銅連接線環(huán)境的電磁干擾(Electromagnetic Interference)。其次,產(chǎn)生10位來造成直流平衡化理想的字符。
TMDS視頻數(shù)據(jù)編碼算法過程如下(摘自DVI規(guī)范):
2). serdes_4b_10to1:方法是通過兩個 OSERDESE2 的串聯(lián)把 10 比特的并行數(shù)據(jù)轉(zhuǎn)換成串行發(fā)送出去。
4. HDMI模塊硬件語言描述
根據(jù)時序圖,和上述的模塊圖結(jié)合在一起,就可以書寫模塊了。模塊的書寫和攝像頭相類似,時序單元基本相同。具體完成的就如同上述時序,對行場信號生成,也就是寫計數(shù)器,技術(shù)標(biāo)準(zhǔn)就是前圖的參數(shù)。
再設(shè)置寄存器,將我們要顯示的數(shù)據(jù)輸出(攝像頭采集到的數(shù)據(jù))。這部分按順序一位一位的發(fā)送即可。
步驟三:存儲模塊與圖像處理模塊的設(shè)計與實現(xiàn)
1.存儲模塊
存儲模塊板卡配備的是DDR3,對于學(xué)習(xí)者而言DDR3接口時序較為困難,這里僅對接口簡單講解,代碼使用的是黑金提供的DDR3的代碼。(下面加粗部分引自黑金09.DDR3讀寫測試實驗。)
DDR SDRAM 全稱為 Double Data Rate SDRAM,中文名為“雙倍數(shù)據(jù)流 SDRAM”。DDR SDRAM 在原有的 SDRAM 的基礎(chǔ)上改進(jìn)而來。也正因為如此,DDR 能夠憑借著轉(zhuǎn)產(chǎn)成本優(yōu)勢來打敗昔日的對手 RDRAM,成為當(dāng)今的主流。本文只著重講 DDR 的原理和 DDR SDRAM 相對于傳統(tǒng) SDRAM(又稱 SDR SDRAM)的不同。
從中可以發(fā)現(xiàn)它多了兩個信號: CLK#與 DQS,CLK#與正常 CLK 時鐘相位相反,形成差分時鐘信號。而數(shù)據(jù)的傳輸在 CLK 與 CLK#的交叉點進(jìn)行,可見在 CLK 的上升與下降沿(此時正好是 CLK#的上升沿)都有數(shù)據(jù)被觸發(fā),從而實現(xiàn) DDR。在此,我們可以說通過差分信號達(dá)到了 DDR 的目的,甚至講 CLK#幫助了第二個數(shù)據(jù)的觸發(fā),但這只是對表面現(xiàn)象的簡單描述,從嚴(yán)格的定義上講并不能這么說。之所以能實現(xiàn) DDR,還要從其內(nèi)部的改進(jìn)說起。這是一顆 128Mbit 的內(nèi)存芯片,從圖中可以看出來,白色區(qū)域內(nèi)與 SDRAM 的結(jié)構(gòu)基本相同,
但請注意灰色區(qū)域,這是與 SDRAM 的不同之處。首先就是內(nèi)部的 L-Bank 規(guī)格。SDRAM 中 L-Bank存儲單元的容量與芯片位寬相同,但在 DDR SDRAM 中并不是這樣,存儲單元的容量是芯片位寬的一倍,所以在此不能再套用講解 SDRAM 時 “芯片位寬=存儲單元容量” 的公式了。也因此,真正的行、列地址數(shù)量也與同規(guī)格 SDRAM 不一樣了。以本芯片為例,在讀取時,L-Bank 在內(nèi)部時鐘信號的觸發(fā)下一次傳送 8bit 的數(shù)據(jù)給讀取鎖存器,再分成兩路 4bit 數(shù)據(jù)傳給復(fù)用器,由后者將它們合并為一路 4bit 數(shù)據(jù)流,然后由發(fā)送器在DQS 的控制下在外部時鐘上升與下降沿分兩次傳輸 4bit 的數(shù)據(jù)給北橋。這樣,如果時鐘頻率為100MHz,那么在 I/O 端口處,由于是上下沿觸發(fā),那么就是傳輸頻率就是 200MHz。
2.FIFO設(shè)計與Verilog實現(xiàn)
FIFO是我們在設(shè)計過程中最常見的存儲器。它經(jīng)常被用來處理跨時鐘域的問題。常見的FIFO分為同步FIFO與異步FIFO,他們的區(qū)別就是輸入輸出是否有同一個時鐘驅(qū)動,是由同一個時鐘驅(qū)動的就是同步FIFO,不是由同一個時鐘驅(qū)動的就是異步FIFO。
正如他的名字(First In First Out),常見的標(biāo)準(zhǔn)FIFO接口是這樣的。
我們對讀寫指針的讀取,可以判斷現(xiàn)在數(shù)據(jù)的量,而滿空信號直接告訴我們FIFO是否還可以繼續(xù)讀寫。這部分比較簡單,我們直接上代碼。
3.均值濾波算法實現(xiàn)
步驟一中我們已經(jīng)講述了算法的大致概念。而均值濾波的實質(zhì)就是用周圍8個像素的平均值。所以核心的問題就成為了如何準(zhǔn)確而又快速的找到每個像素周圍8個像素點。這里我們就要用到步驟一中的結(jié)構(gòu)
首先我們設(shè)置三個移位寄存器(Shift Reg),每個移位寄存器的的長度為一幀圖像一行的長度,三個移位寄存器首尾相連。像素點按位輸入至移位寄存器之中,這樣每個寄存器的相同位上即為同一列,這三個移位寄存器的最后三列,自然而然的形成了我們想要的九宮格(也就是第二個寄存器倒數(shù)第二個像素點及其周圍8個數(shù)據(jù))。這個結(jié)構(gòu)使用Verilog代碼實現(xiàn)為
而在這之前需要對我們數(shù)據(jù)打一拍,也就是過一級寄存器。
4.中值濾波算法實現(xiàn)
中值濾波和實現(xiàn)方法相同,只是計算方式不同。
5.SOBEL算法實現(xiàn)
邊緣是圖像最基本的特征,其在計算機(jī)視覺、圖像分析等應(yīng)用中起著重要的作用,這是因為圖像的邊緣包含了用于識別的有用信息,是圖像分析和模式識別的主要特征提取手段。
在本系統(tǒng)中識別物體時,就需要找到物體的邊緣。而邊緣檢測的方法就是SOBEL算法。sobel 是一個梯度的計算,如下圖所示,是 x 和 y 方向的 3x3 窗口的卷積。
而為了簡化計算,我們把算子簡化為下面這樣的
而計算和上面的生成3x3矩陣相似,
到這里我們基本的大模塊已經(jīng)完成了,接下來將模塊連接,遷到運算即可完成!項目相關(guān)的代碼將在最后一期分享給大家。
步驟四:系統(tǒng)整體設(shè)計的實現(xiàn)與優(yōu)化
1.差值法運動目標(biāo)識別
在上次講述完視頻處理和存儲之后,我們來簡述差值法運動目標(biāo)追蹤的方法。
本項目基于固定背景,所以采用的運動目標(biāo)識別算法為最簡單的差值法來識別計算。在上一步驟存儲的時候要將兩幀數(shù)據(jù)合并存儲。例如使用每個單元的16bits,可以把第一幀的數(shù)據(jù)存在前八位,第二幀的數(shù)據(jù)存在后八位。這樣方便進(jìn)行差值計算。
插值計算的存儲可以使用掩碼實現(xiàn)。
2.攝像頭移動模塊-舵機(jī)
我們使用的攝像頭移動模塊是舵機(jī)。
舵機(jī)使用SG90,控制的方法是調(diào)節(jié)占空比,舵機(jī)的控制一般需要一個20ms的時基脈沖,該脈沖的高電平部分一般為0.5ms~2.5ms范圍內(nèi)的角度控制脈沖部分,實現(xiàn)方法為分頻的方法。
在編寫的時候,要注意有橫向與縱向的舵機(jī),在編寫之前確認(rèn)好橫向與縱向。
3.模塊連接
在頂層模塊,實例化所有模塊。在實例化的時候,要注意模塊直接的連接線,不能重名,注意連接的接口。具體實例化如下:
4.模塊綜合
將攝像頭模塊、舵機(jī)模塊、GSM模塊、HDMI顯示模塊、DDR模塊、圖像膨脹處理模塊,圖像腐蝕處理模塊,圖像中值濾波處理模塊,YCbCr轉(zhuǎn)RGB模塊等連接在一起。在頂層模塊進(jìn)行實例化實現(xiàn)功能:(1)在靜止?fàn)顟B(tài)下的運動目標(biāo)追蹤;(2)在物體運動時根據(jù)運動方向調(diào)整角度實現(xiàn)持續(xù)追蹤。
5.資源使用率
版權(quán)聲明:本文系電路城原創(chuàng)內(nèi)容,未經(jīng)授權(quán)禁止轉(zhuǎn)載,侵權(quán)必究!