大俠好,歡迎來到FPGA技術江湖,江湖偌大,相見即是緣分。大俠可以關注FPGA技術江湖,在“闖蕩江湖”、"行俠仗義"欄里獲取其他感興趣的資源,或者一起煮酒言歡。
今天和大俠簡單聊一聊基于FPGA的圖像處理,之前也和各位大俠聊過相關的圖像處理圖像處理能做什么,這里面也超鏈接了幾篇,具體如下: 需要的可以參考一下,歡迎一起交流學習。話不多說,上貨。
使用FPGA做圖像處理優勢最關鍵的就是:FPGA能進行實時流水線運算,能達到最高的實時性。因此在一些對實時性要求非常高的應用領域,做圖像處理基本就只能用FPGA。例如在一些分選設備中圖像處理基本上用的都是FPGA,因為在其中相機從看到物料圖像到給出執行指令之間的延時大概只有幾毫秒,這就要求圖像處理必須很快且延時固定,只有FPGA進行的實時流水線運算才能滿足這一要求。
所以要了解FPGA進行圖像處理的優勢就必須理解FPGA所能進行的實時流水線運算和DSP,GPU等進行的圖像處理運算有何不同。DSP,GPU,CPU對圖像的處理基本是以幀為單位的,從相機采集的圖像數據會先存在內存中,然后GPU會讀取內存中的圖像數據進行處理。假如采集圖像的幀率是30幀,那么DSP,GPU要是能在1/30秒內完成一幀圖像的處理,那基本上就能算是實時處理。
FPGA對圖像進行實時流水線運算是以行為單位的。FPGA可以直接和圖像傳感器芯片連接獲得圖像數據流,如果是RAW格式的則還可以進行差值以獲得RGB圖像數據。FPGA能進行實時流水線處理的關鍵是它可以用其內部的Block Ram緩存若干行的圖像數據。這個Block Ram可以說是類似于CPU里面的Cache,但Cache不是你能完全控制的,但Block Ram是完全可控的,可以用它實現各種靈活的運算處理。這樣FPGA通過緩存若干行圖像數據就可以對圖像進行實時處理,數據就這樣一邊流過就一邊處理好了,不需要送入DDR緩存了之后再讀出來處理。
這樣的數據流處理顯然是順序讀取數據的,那么也就只能實現那些順序讀取數據的算法,也就是圖像處理中那一大類用3x3到NxN的算子進行的濾波、取邊緣、膨脹腐蝕等算法??赡艽蠹視X得這些運算似乎都是最基本的圖像處理運算,只是個前端的預處理,似乎用處不大。但問題是只有FPGA做這樣的運算才是速度最快效率最高的,比如用CPU做一個取邊緣的算法根本就達不到實時。另外別小看了這種NxN算子法,它可以有各種組合和玩法,可以實現分選多種顏色,甚至分辨簡單形狀等功能。FPGA進行的這種算子法處理是并行流水線算法圖像處理能做什么,其延時是固定的,比如用3x3的算子進行處理其給出結果的延時是兩行圖像的時間。還有這個算子法和現在卷積神經網絡中最前面的卷積層運算是類似的。
FPGA中的Block Ram是重要和稀缺資源,能緩存的圖像數據行數是有限的,所以這個NxN的算子中的N不能特別大。當然FPGA也可以接DDR把圖像緩存到其中再讀出來進行處理,但這種處理模式就和CPU差不多了,達不到最高的實時性。其實有些我們認為需要隨機讀取數據的圖像處理算法也是可以并行流水線化的。
在密集運算中,耽誤時間和消耗功耗的操作往往不是運算本身,而是把數據從內存中搬來搬去。GPU,CPU在進行運算時要把數據從內存中取出來,算好了在放回去。這樣內存帶寬往往成了運算速度的瓶頸,數據搬運過程中的功耗占的比重也不會小。FPGA則可以通過堆很多計算硬件的方法把要做的運算都展開,然后數據從中流過,完成一個階段的運算之后就直接流入第二個階段,不需要把一個計算階段完成后的數據再送回內存中,再讀出來交給下一個階段的運算。這樣就會節省很多時間和功耗?,F在用FPGA做圖像處理就是這樣干的,比如先用一個3x3的算子進行濾波,再用一個3x3的算子進行取邊緣,在FPGA流水線算法中,濾波處理完了數據立即就會進行取邊緣處理,是不需要像CPU那樣存回內存再讀出來的。
FPGA進行圖像處理的前景還是挺廣闊的,越來越多的工業應用場合都要求更高的實時性,而這正是FPGA所適合的。還有機器學習領域,神經網絡這種層狀的,不需要很隨機的讀取數據的運算是比較適合用FPGA來做的。不過FPGA不擅長浮點運算,如果能整出不需要浮點運算的神經網絡,那么FPGA在這方面的應用將會更大。
前些年用和做圖像處理。近一段時間通過FPGA處理攝像頭視頻數據,有太多感觸,復雜的算法先不提及,單是上面文章中提到的一些處理手段及策略,非常受用。
下面就幾個方面簡單列一些:
神圣分割線
圖像處理系統設計注意點:
1.將算法開發和FPGA實現分離
用軟件的圖像處理環境可以使用大批量的圖像樣本進行測試及調試算法,再將算法映射到硬件上,這樣大大節省了硬件調試周期。
2.算法的精度
圖像處理的算法中,大部分需要采用浮點數運算,而浮點數運算在FPGA中是非常不劃算的,因此需要轉換成定點數計算,此時會設計到浮點運算轉定點運算時精度下降的問題。
3.軟件和硬件的合理劃分
這里的軟件是指DSP、CPU等等,硬件是指FPGA;一般結構規則、計算量大的操作如sobel算子、均值濾波可以采用硬件進行,不規則的動態可變長度循環的底層算法由軟件進行。
神圣分割線
圖像處理FPGA 設計基本方法:
1.陣列結構結合流水線處理設計
例如RGB圖像,包括三組數據,處理時需要并行三通道后,每個通道進行分別的串行流水處理。
2.緩存設計
幀緩存行緩存列對齊
3.資源
分辨率處理窗口對資源影響成倍增加
神圣分割線
基于FPGA設計框架舉例:
1、灰度直方圖統計
直方圖是圖像的灰度分布統計的一種表示方法,統計目標圖像中各個灰度點的像素個數,很多對于圖像的調整算法都是基于此進行的;
如何基于FPGA進行統計呢?
1)由于是統計圖像的直方圖,所以一定是統計結果會在圖像經過之后才能產生,因此需要進行緩存;
緩存一:統計后的結果;
緩存二:經過統計處理器的圖像數據,以便后面和直方圖做同步處理。
2)圖像常常用8位、24位、32位來表示一個像素的灰度值。因此,統計種類分別為2^8=256/2^24=/2^32=,地址位寬根據此進行選擇設定。根據不同的精度選擇不同的緩存方式:片內或片外緩存。
3)處理流程:
首先根據當前來的灰度值做為讀RAM地址,讀出RAM中對應灰度值的的統計值;
第二步將讀出結果加一并回寫回RAM的當前地址中;
第三步重復操作至當前圖像處理結束;
第四步下一幅圖像到來之前順序按灰度值從0到最大的順序將最終結果讀出;
第五步讀出最終結果后,將RAM清空。
4)處理細節
定義參數圖像高度IH 圖像寬度IW像素逐行輸入,因此以行同步脈沖的上升沿作為統計開始,行同步脈沖作為行統計計數器,行統計計數器達到最大高度時,作為統計結束標志。
2.灰度直方圖均衡化處理
1.統計出直方圖,獲取各個像素灰度累加和;
2.乘以均衡系數:(2^DW-1)/IW*IH(像素最大值/圖像的面積)。
3.直方圖線性拉伸處理
此節暫時略過,不太精通,后續有時間可以研究再分享一下;
4.線性濾波器
首先需要區分線性和非線性濾波器的區別,區別在于其輸出與輸入之間是否有唯一且確定的函數傳遞。
線性濾波器分類:
平滑濾波器:主要包括均值濾波器和高斯濾波器等;
銳化濾波器:主要包括SOBEL算子、算子、梯度運算等。
濾波器的物理意義主要是響應信號對目標信號響應后的樣子,也就是響應函數g(i,j)滑過整個圖像,即對圖像做一個卷積處理,就得到了濾波結果。
1)均值濾波器概述
用一個圖像區域的各個像素的平均值來代替原圖像的各個像素值,主要作用是減小銳度,減小噪聲。
均值濾波一般出現在圖像處理的預處理步驟,
預處理后,根據噪聲來源,例如針對椒鹽噪聲做中值濾波處理,針對高斯噪聲做高斯濾波處理
后續可能繼續做邊緣提取等復雜操作處理。
2)均值濾波器設計
設計一個濾波器可以理解成設計一個響應函數g(x,y)=Σi=-rrΣj=-rrI(x+i,y+j)) / (2r+1)2
數學公式很好理解,就是求一個窗口的所有像素灰度值之后后再除以整個窗口的面積也就是像素點個數,求出平均值;
均值濾波的方法將數據存儲成3x3的矩陣,然后求這個矩陣。在圖像上對目標像素給一個模板,
該模板包括了其周圍的臨近像素(以目標像素為中心的周圍 8 個像素,構成一個濾波模板,即去掉目標像素本身),再用模板中的全體像素的平均值來代替原來像素值。
進行數據矩陣化,將3x3矩陣的中心像素的周圍八個點求和,采取了流水線的設計方法,來增加吞吐量,然后再求平均值代替目標像素的值。
3)sobel算子
包括X和Y兩個方向的兩套3X3矩陣,使其分別和圖像的X和Y方向進行卷積計算(矩陣的卷積計算即將所有元素做乘加計算),兩個方向的卷積結果求平方根計算,計算結果如果大于閾值則等于,如果小于閾值則等于0,最終輸出則是圖像的邊緣。
參考代碼如下:由于算子簡單以及有正負區分,因此需要做正值和負值分別計算后再進行相減計算。
| -1 0 +1 |
| -2 0 +2 | =
| -1 0 +1 |
//
| -1 -2 -1 |
| 0 0 0 | =
| +1 +2 +1 |
reg [8:0] p_x_data ,p_y_data ; // x 和 y 的正值之和
reg [8:0] n_x_data ,n_y_data ; // x 和 y 的負值之和
reg [8:0] gx_data ,gy_data ; //最終結果
always @(posedge clk or negedge rst_n)begin
=1'b0)begin =
p_x_data <=0;
n_x_data <=0;
gx_data <=0;
end
else if(per_href_ff1==1) begin
p_x_data <= p_13 + (p_23<<1) + p_33 ;
n_x_data <= p_11 + (p_12<<1 )+ p_13 ;
gx_data <= (p_x_data >=n_x_data)? p_x_data - n_x_data : n_x_data - p_x_data ;
end
else begin
0; =
0; =
gx_data <=0;
end
end
always @(posedge clk or negedge rst_n)begin
=1'b0)begin =
p_y_data <=0;
n_y_data <=0;
gy_data <=0;
end
else if(per_href_ff1==1) begin
p_y_data <= p_11 + (p_12<<1) + p_13 ;
n_y_data <= p_31 + (p_32<<1) + p_33 ;
gy_data <= (p_y_data >=n_y_data)? p_y_data - n_y_data : n_y_data - p_y_data ;
end
else begin
p_y_data <=0;
n_y_data <=0;
gy_data <=0;
end
end
//求平方和,調用ip核開平方
reg [16:0] gxy; // Gx 與 Gy 的平方和
always @(posedge clk or negedge rst_n)begin
=1'b0)begin =
0; =
end
else begin
gy_data* gy_data + gx_data* gx_data ; =
end
end
wire [8:0] squart_out ;
altsquart u1_altsquart ( //例化開平方的ip核
(gxy),
(squart_out), //輸出的結果
.remainder()
);
//與閾值進行比較
reg [15:0] post_y_data_r;
always @(posedge clk or negedge rst_n)begin
=1'b0)begin =
16'h00; =
end
else if(squart_out>=threshold)
16'h00 ; =
else
16'hffff ; =
end
5.非線性濾波器
非線性濾波器通常下是沒有特定的轉移函數,統計排序濾波器;
中值濾波 將 3*3 滑動塊中的灰度值進行排序,然后用排序的中間值取代 3*3 滑塊中心的值。示意圖如下圖所示。
第一步:將每一行按最大值、中間值、最小值排列;
第二步:提取出最大值的最小值,中間值的中間值,最小值的最大值;
第三步:將第二步提取出來的三個數進行排序,中間值即我們要求的中間值。
6.圖像分割
圖像分割是將圖像劃分成若干個互不相交的小區域的過程,將圖像中有意義的特征或應用所需要的特征信息提取出來,最終結果是分割成一些具有某種特征的單元,稱為圖像的基元。
神圣分割線
本篇到此結束,后續有時間再更新,歡迎一起交流學習,共同進步!
END
后續會持續更新,帶來、 ISE、 II 、等安裝相關設計教程,學習資源、項目資源、好文推薦等,希望大俠持續關注。大俠們,江湖偌大,繼續闖蕩,愿一切安好,有緣再見!
FPGA技術江湖廣發江湖帖
無廣告純凈模式,給技術交流一片凈土,從初學小白到行業精英業界大佬等,從軍工領域到民用企業等,從通信、圖像處理到人工智能等各個方向應有盡有,QQ微信雙選,FPGA技術江湖打造最純凈最專業的技術交流學習平臺。
FPGA技術江湖微信交流群
加群主微信,備注職業+方向+名字進群
FPGA技術江湖QQ交流群
備注地區+職業+方向+名字進群