基於FPGA的局部自適應分割

局部自適應閾值分割原理

全局閾值分割算法簡單,對於雙峯直方圖圖像有很好的分割效果。但對於圖像噪聲和光照不均勻性十分敏感。圖6-1是圖像的OTSU分割效果。可見,由於邊緣光照不均勻性,造成邊緣分割失敗。圖像邊緣光線較暗的地方被分割爲0,中間較亮的地方分割成功。
在這裏插入圖片描述
如何規避光線不均勻帶來的影響?一種典型的處理方法就是採用局部自適應閾值分割。根據像素鄰域塊的像素值分佈來確定該像素位置上的二值化閾值。這樣做的好處在於每個像素位置處的二值化閾值不是固定不變的,而是由其周圍鄰域像素的分佈來決定的。亮度較高的圖像區域二值化閾值通常較高,而亮度較低的圖像區域二值化閾值則會相應地變小。不同亮度、對比度、紋理的局部圖像區域將會擁有相對應的局部二值化閾值。

常用的局部自適應閾值是局部鄰域塊的均值和局部鄰域塊的高斯加權和。將處理窗口設爲矩形移動窗,設r爲處理窗口的半徑,μ爲窗口內像素均值,σ2爲窗口內像素方差,I(x,y)爲輸入像素值,g(x,y)爲分割後的像素值,K爲一個大於0的常數。有如下定義:
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

算法轉換

在這裏插入圖片描述

FPGA結構設計

爲了充分利用FPGA的並行特性,採用流水線結構來實現上訴設計。需要完成以下計算工作:

(1) 計算當前窗口內的像素均值μ。
(2) 計算當前窗口中心像素與均值之差的平方(din-μ)2。
(3) 將上式與225相乘,完成不等式左邊的計算。
(4) 計算當前窗口內225個所有像素值與均值之差的平方和,完成不等式右邊的計算。
(5) 將第(3)和(4)的結果進行比較,完成圖像分割。
(6) 完成行列對齊與邊界處理。
在這裏插入圖片描述
average_filter模塊是均值濾波模塊,其內部使用了win_buf和add_tree。共消耗11拍,爲了均值與窗口緩存電路win_buf時序對齊,din輸入到win_buf需要延時11拍。

得到了窗口均值μ和當前窗口的像素隊列225個像素數據din_buf,需要做的是把窗口內225個din_buf分別於均值相減後計算平方。從圖6-4可以看出,減法消耗一拍,平方也消耗一拍,計算完後再將他們拼接在一起,組成新的向量,方便輸入到add_tree模塊進行加法計算(模塊端口不能是數組,只能將他們拼接成一個向量,然後再輸入到模塊端口中,其他和數組的效果是一樣的!)。加法電路消耗了8拍。

中心像素與均值之差的平方值可以直接從新向量中取出,無需重新計算,然後進行乘255,乘法電路需要消耗兩拍,爲了與add_tree輸出的數據對齊,乘法電路輸出的數據還需要延時8-2=6拍。至此左邊不等式和右邊不等式都已經計算完畢。將不等式進行比較,利用比較結果對原圖進行分割即可。最後的根據有效數據標誌清零是爲了將邊界清零。至少對上邊界清零。左右兩邊沒有考慮(左右邊界清零比較麻煩,以後可能會更新左右邊界清零!)。

子模塊設計

窗口緩存模塊win_buf

本模塊不做任何算法上的處理,只是負責將當前輸入像素的二維窗口元素緩存並組成一個一維的向量輸出。

模塊的構建非常簡單,對圖像分別做行列方向的延遲即可。對於行方向上的延時,可以採用行FIFO來實現,對於列方向上的延遲,則採用寄存器來實現。

設需要緩存的窗口尺寸爲KSZ,則需要KSZ-1行FIFO,以及KSZ*KSZ個寄存器來實現。

我們將以7*7的窗口緩存模塊爲例來說明,其設計框圖如下:
在這裏插入圖片描述
我們不難把這個電路擴展到尺寸15x15的窗口中,在圖中也重點標註出了窗口中心像素點。這個中心像素點就代表當前處理的像素中心。此電路也可以用來實現圖像的卷積運算,例如排序、sobel算子、高斯濾波或者均值濾波等。

數據累加模塊add_tree

數據累加模塊負責將窗口內所有元素與均值之差的平方相加。每個加法器限制兩個輸入,這樣,對於225個數據,在第一個時鐘,共有112對數據進行相加。同時把剩餘的一個數據進行緩存,第二個時鐘有56個數據進行相加,同時將之前的數據緩存,依次類推,如下圖所示:
在這裏插入圖片描述
問題的關鍵在於如何描述這個電路,當然可以使用最笨的方法:將上訴電路中所有的寄存器及加法器和中間信號均描述出來。這樣帶來的工作量是非常大的,還容易出錯,代碼可維護性和可讀性極差。

如果在仔細發泄上訴框圖,就很容易發現規律:除了最後一個時鐘直接完成兩個數的相加,在其他的每個時鐘內,加法運算電路都是相似的,不同的只是待加的數目不同。

爲了總結出這個規律,我們列出幾個時鐘如下:

第一個時鐘:需完成225個數據相加,共需112個加法器,113個寄存器。
第二個時鐘:需完成113個數據相加,共需56個加法器,57個寄存器。
第三個時鐘:需完成57個數據相加,共需28個加法器,29個寄存器。
……
最後一個時鐘:需完成2個數據相加,共需1個加法器,1個寄存器。
爲此,我們總結出以下規律:

設定本次待相加的數目爲n,則下次需要相加的數目爲n/2+n%2。

本次需要的加法器數目爲n/2,寄存器數目爲n/2+n%2。

每次的計算開銷是1個時鐘。

很明顯,可以通過利用數學上的遞歸運算來解決這個問題。實際上,在數學上也把這種方法稱爲二分遞歸調用。
數學公式推導如下:

遞歸求和電路框圖如下所示:
在這裏插入圖片描述
圖6-7中的input_vector爲當前窗口的並行像素向量(由win_buf模塊得到),new_vector爲第一次遞歸運算之後獲得的新向量,作爲下一次遞歸的input_vector。

均值濾波模塊設計

前面章節已經設計好win_buf模塊和add_tree模塊,在此基礎上很容易設計出均值模塊。其設計框圖如下:
在這裏插入圖片描述
從圖6-4頂層模塊中可以看出,頂層也使用了win_buf模塊用來緩存窗口,所以本教程以win_buf模塊爲起始點,可以看出均值模塊共消耗了11拍,所以在頂層模塊需要先將輸入數據延時11拍後再輸入給win_buf,目的就是爲了時序對齊。

福利

本教程的所有 verilog 源碼以及上位機源碼都會公佈,本次教程是收取一定 費用的,畢竟博主寫的這麼詳細,也是花費了很多時間和精力的,總之物有所值!無論是做課程設計還是做畢業設計還是自己學習,本教程都是不可多得 的。有問題可以加我 QQ 好友,直接留言即可,我看到就會回覆的~,微信掃描 下面的二維碼即可購買:
在這裏插入圖片描述
微信掃描下面的二維碼關注[春哥筆記]公衆號,關注我的公衆號可以獲取更 多 FPGA 的教程,也希望大家轉發支持哦~
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章