像素行與像素窗口
一幅圖像是由一個個像素點構成的,對于一幅480*272大小的圖片來說,其寬度是480,高度是272。在使用FPGA進行圖像處理時,最關鍵的就是使用FPGA內部的存儲資源對像素行進行緩存與變換。由于在圖像處理過程中,經常會使用到卷積,因此需要對圖像進行開窗,然后將開窗得到的局部圖像與卷積核進行卷積,從而完成處理。
圖像數據一般按照一定的格式和時序進行傳輸,在我進行實驗的時候,處理圖像時,讓其以VGA的時序來進行工作,這樣能夠為我處理行緩存提供便利。
基于FIFO的行緩存結構
在FPGA中對圖像的一行數據進行緩存時,可以采用FIFO這一結構,如上圖所示,新一行圖像數據流入到FIFO1中,FIFO1中會對圖像數據進行緩存,當FIFO1中緩存有一行圖像數據時,在下一行圖像數據來臨的時候,將FIFO1中緩存的圖像數據讀出,并傳遞給下一個FIFO,于此同時,將新一行的圖像數據緩存到FIFO1中,這樣就能完成多行圖像的緩存。
若要緩存多行圖像,下面的菊花鏈式的結果更能夠直觀地表現圖像數據地流向。
新輸入地圖像緩存到FIFO1當中,當FIFO中緩存有一行數據的時候,下一個輸入像素來臨的時候,會將數據從本FIFO中讀出,并給到下一個FIFO,來形成類似于一個流水線的結構。
上面的圖中,就是實現一個5X5大小的窗口的一個結構圖。
代碼設計
實現一個可以生成任意尺寸大小的開窗的模塊,需要注意參數的使用,可以通過調節KSZ來調整窗口的大小。最終將窗口中的圖像像素,轉換成一個一維的數據輸出給到下一個模塊。
在設計的時候,對于FIFO要選擇精準計數模式,這樣才能讓流水正常工作起來。
在代碼中通過generate語句來實現多個line_buffer的例化,line buffer的個數可以根據卷積窗口的大小來選擇,例如3X3大小的卷積窗口需要緩存兩行,5X5大小的卷積窗口需要緩存4行,可以通過設置參數來選擇要例化多少個line_buffer。
時序設計
在設計FIFO的菊花鏈結構時,需要根據當前FIFO中存儲的數據個數來判斷,這時候使用到精準計數模式,可以反應FIFO中的存儲的數據。當FIFO中存儲有一行數據的時候,使能pop_en信號,表示當前可以將數據從FIFO中讀出。
在將數據寫入到FIFO中的時候,需要對數據進行擴充,也即需要對輸入的圖像的邊界補充數據,因為進行卷積之后的圖像將會比原始圖像數據尺寸減少,因此在形成卷積窗口時,將圖像擴充,能夠讓圖像處理完成之后,保持原來的尺寸,只是會在邊界出現黑邊。
win_buf這個模塊的最終輸出,就是一個矩陣內的所有像素,組成一個信號輸出到外部,供進行卷積的處理。
仿真驗證
輸入的第三行數據的前三個數據是:0x00,0x78,0x7c
輸入的第二行數據的前三個數據是:0x00,0x7d,0x7d
輸入的第一行數據的前三個數據是:0x00,0x7e,0x7f
輸出的第一個矩陣的值是:0x0078_7c00_7d7d_007e_7f
輸入行數據第一個數據是0x00這是因為擴充了邊界的原因。
可以看到,設置KSZ為3,可以得到一個位寬為72bit的輸出數據,該數據包含了一個窗口中的9個數據。
5X5開窗
設置開窗大小為5x5之后,也可以看到輸出信號的位寬變為了8*25=200bit,也就是一個5X5大小的矩陣中的數據。
輸入的第5行數據的前5個數據是:0x00,0x00,0x7e,0x7c,0x7f
輸入的第4行數據的前5個數據是:0x00,0x00,0x7e,0x7e,0x7e,
輸入的第3行數據的前5個數據是:0x00,0x00,0x78,0x7c,0x7c
輸入的第2行數據的前5個數據是:0x00,0x00,0x7d,0x7d,0x7a
輸入的第1行數據的前5個數據是:0x00,0x00,0x7e,0x7f,0x7d
從輸出結果看,輸出的矩陣數據,剛好是這5行的前5數據,并且前兩個數據是0x00,這是因為在每一行前面補充了兩個0的原因。
經過測試,這種開窗算子是能夠完成任意此村的開窗的。
實際應用
在實際應用中,我也將這個模塊正確地使用上了,完成了一個3x3的sobel算子和5x5的均值濾波。
原始圖像
3x3 Sobel
審核編輯 :李倩
-
FPGA
+關注
關注
1626文章
21678瀏覽量
602031 -
圖像處理
+關注
關注
27文章
1282瀏覽量
56657
原文標題:FPGA學習-圖像處理基礎實現緩存卷積窗口
文章出處:【微信號:gh_9d70b445f494,微信公眾號:FPGA設計論壇】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論