本發(fā)明涉及圖像算法技術(shù)領(lǐng)域,具體涉及一種基于FPGA實現(xiàn)的面陣相機平場矯正實時算法。
背景技術(shù):
在光電成像系統(tǒng)中,特別是面陣相機成像系統(tǒng)中,圖像信號不能完全反應(yīng)實際目標(biāo),其原因主要包括兩方面:(1)由CCD或CMOS傳感器制作工藝引起的響應(yīng)不一致性(也稱為PRNU);(2)由于光學(xué)衍射現(xiàn)象及光學(xué)系統(tǒng)各種偏差引起的漸暈效應(yīng)。為保證圖像輸出質(zhì)量,一般需要對采集得到的原始圖像進行平場矯正(FFC)算法進行修正,以使其達到應(yīng)用要求。由于PRNU和漸暈效應(yīng)往往是非線性的,因此在FFC算法中,主要通過乘法運算進行矯正。FFC算法可以總結(jié)為如下形式:Yi=Xi*ai。其中Yi為FFC矯正后數(shù)據(jù),Xi為傳感器原始輸出數(shù)據(jù),i為每個像元的序列號,即矯正算法中每個像元對應(yīng)一個ai元素。FFC算法主要難點在于一方面需要預(yù)先保存一個和圖像分辨率同樣大小的ai數(shù)組,另一方面需要做大量的乘法運算,這導(dǎo)致高分辨高幀率下的實時FFC算法除了對處理速度提出很高要求外,對存儲資源的需求也很大。
對于小靶面相機,如1百萬像素量級的圖像,在低幀率下的軟件方式尚可勉強應(yīng)付。FFC矯正算法需要對每個像素點進行乘法運算,對于高分辨率傳感器高幀率要求的應(yīng)用場合,采用軟件實現(xiàn)實時FFC算法已經(jīng)無法滿足要求。如ON Semiconductor公司生產(chǎn)的KAI-47051,其分辨率達到4千7百萬,常規(guī)的軟件方式已經(jīng)無法滿足要求,而采用ASIC方式實現(xiàn)FFC算法一方面靈活性很差,另一方面成本很高,遠未達到實用性要求。這就使得對于高分辨率或者高幀率的實時應(yīng)用場合,不得不以犧牲圖像質(zhì)量為代價。這種情況下,F(xiàn)PGA(可編程門陣列)作為一種目前較為流行的器件,其可編程性一方面規(guī)避了ASIC實現(xiàn)方式的靈活性差高成本的缺點,另一方面其硬件實現(xiàn)方式也規(guī)避了軟件實現(xiàn)方式下的速度無法跟上的缺點。但對于高分辨率FFC算法,F(xiàn)PGA也有其自身的缺點,即內(nèi)部資源有限,可能無法應(yīng)對高分辨率圖像對存儲資源的要求。如對KAI-47051而言,其像素數(shù)量為47.8MB,即按每個像素最低8-bit計算,保存一幅圖像對應(yīng)的AI數(shù)組需要47.8MB的存儲空間;即便不計FPGA購買成本,目前最高端的FPGA也很難達到這個要求。這就要求在保證一定的輸出圖像質(zhì)量的情況下,需要對原始的FFC算法進行優(yōu)化,從而使得基于FPGA實現(xiàn)高分辨率高幀率下面陣相機實時FFC算法成為可能。
技術(shù)實現(xiàn)要素:
本發(fā)明提供一種基于FPGA實現(xiàn)的面陣相機平場矯正實時算法,為高分辨率、高幀率面陣相機實現(xiàn)實時FFC算法提供可能,為高分辨率高幀率應(yīng)用場合提供較高的輸出圖像質(zhì)量。
為解決上述技術(shù)問題,本發(fā)明采用如下技術(shù)方案:
一種基于FPGA實現(xiàn)的面陣相機平場矯正實時算法,包括如下步驟:
1)傳感器有效分辨率設(shè)為:水平colcount,豎直rowcount,將分辨率按照N×N的矩陣分割成多個基本塊,在實際照明條件下獲取圖像,以每個基本塊的圖像均值作為輸入數(shù)據(jù),進行FFC矯正計算獲得歸一化ai數(shù)組為:
2)對分辨率邊界進行復(fù)制,擴展ai數(shù)組為:
3)得到像素點所屬基本塊為:[i][j],
4)對基本塊的每個像素點,通過當(dāng)前基本塊與相鄰基本塊的FFC數(shù)據(jù)以及當(dāng)前像素點坐標(biāo)(x,y),基于雙線性插值算法計算得到像素點實際的ai值;
5)將當(dāng)前基本塊從中心等分為四個象限,根據(jù)像素點的從屬象限選擇參與運算的ai值;
6)基于FPGA的并行運算,同時計算四個象限的值,通過符號位選擇輸出,結(jié)合ai數(shù)組的二維矩陣到一維矩陣的轉(zhuǎn)換,計算最終結(jié)果,公式如下:
進一步地,步驟6)中,F(xiàn)PGA的并行運算采用8個像素為一個處理單元,具體計算過程包括如下步驟:
61)根據(jù)8像素單元地址計算基本塊[i][j];
62)根據(jù)基本塊[i][j]從ai數(shù)組讀取當(dāng)前基本塊與相鄰基本塊共9個單元,后根據(jù)y[bit3],N[bit0]值判斷該8像素單元所在的象限;
63)根據(jù)所在象限計算A、B、C、D、ao和a1;
64)計算子式:A*(N-a0)*(N-a1)、B*a0*(N-a1)、C*(N-a0)*a1和D*a0*a1;
65)將以上計算得到的四個子式相加得到ai_out,并將ai_out右移8位,得到最終結(jié)果dout=(din*ai_out)。
優(yōu)選地,步驟61)中,基本塊[i][j]為其中y為該8像素單元所在行數(shù),N為該8像素單元的索引號。
優(yōu)選地,步驟62)中,所述9個單元分別為:ai[i-1][j-1]、ai[i-1][j]、ai[i-1][j+1]、ai[i][j-1]、ai[i][j]、ai[i][j+1]、ai[i+1][j-1]、ai[i+1][j]和ai[i+1][j+1]。
進一步地,步驟4)中,像素點處于基本塊[yi][xj]內(nèi),計算ai_x0和ai_x1:
ai_x0=ai[yi][xi]+(ai[yi][xi-1]-ai[yi][xi])/N*(N/2-x%*N);
ai_x1=ai[yi-1][xi]+(ai[yi-1][xi-1]-ai[yi-1][xi])/N*(N/2-x%*N)
計算ai_out:
ai_out=ai_x0+(ai_x1-ai_x0)/N*(N/2-y%*N)。
優(yōu)選地,所述基本塊的N值為16~128。
由以上技術(shù)方案可知,本發(fā)明優(yōu)化了FPGA并行運算,為高分辨率、高幀率下的面陣相機實現(xiàn)實時FFC矯正算法提供了可能,為高分辨率、高幀率應(yīng)用場合提供了較高的輸出圖像質(zhì)量。通過使用優(yōu)化算法,在滿足高分辨率和高幀率的要求下成功的對PRNU和漸暈效應(yīng)進行了實時矯正。
附圖說明
圖1為本發(fā)明算法中基本塊分割和象限分割的示意圖;
圖2為本發(fā)明算法中基本塊分割后邊界像素ai數(shù)組擴展的示意圖;
圖3為實施例中基本塊大小為128x128下的ai算法矯正前后的仿真效果三維圖;
圖4為實施例中經(jīng)AI算法矯正前后的圖像對比。
具體實施方式
下面結(jié)合附圖對本發(fā)明的一種優(yōu)選實施方式作詳細的說明。
FFC算法主要用于矯正傳感器陣列的響應(yīng)不一致性和非理想誤差,基本算法如下:Yi=Xi*ai,其中Yi為矯正后數(shù)據(jù),Xi為傳感器輸出的原始數(shù)據(jù)。面陣相機由于分辨率太高,如果直接做單點FFC運算,那么需要維持一個和圖像分辨率同樣大小的ai數(shù)組,消耗資源過多,在FPGA中直接實現(xiàn)不可行,需要對算法進行優(yōu)化。優(yōu)化的首要目的是降低算法對存儲資源的消耗,為了減少對存儲資源的需求,可以采用基于塊的運算方法,本實施例以16x16像素塊為基本單元,對傳感器陣列進行分塊操作,在分塊基礎(chǔ)上結(jié)合插值算法可以在降低資源消耗的同時對每個點進行運算。
以KAI-47051為例,全分辨率為8880x5392,切割成555x337的矩陣,每個矩陣對應(yīng)一個16x16的基本塊。在實際照明條件下獲取圖像,以每個基本塊的圖像均值作為輸入數(shù)據(jù),計算獲得歸一化數(shù)組ai[yi][xi],使能FFC算法后,對實際圖像的每個像素點,通過當(dāng)前以及相鄰塊的FFC數(shù)據(jù)以及當(dāng)前像素點坐標(biāo)計算得到實際的ai系數(shù),計算過程基于雙線性插值算法。每個像素點參與運算的4個ai數(shù)據(jù)來自最近的4個塊,即將當(dāng)前塊從中心等分為4個象限(A/B/C/D),根據(jù)像素從屬象限選擇參與運算的ai參數(shù)。
如圖1所示,淺色像素為當(dāng)前點,處于塊[yi][xi]的左上角位置,即在象限A內(nèi)。
首先,計算ai_x0和ai_x1:
ai_x0=ai[yi][xi]+(ai[yi][xi-1]-ai[yi][xi])/N*(N/2-x%*N);
ai_x1=ai[yi-1][xi]+(ai[yi-1][xi-1]-ai[yi-1][xi])/N*(N/2-x%*N)
再計算ai_out:
ai_out=ai_x0+(ai_x1-ai_x0)/N*(N/2-y%*N)。
對于邊界像素,為保證運算過程的一致性,復(fù)制擴展ai數(shù)組,如圖2所示。
以16x16塊為例,推導(dǎo)過程如下:傳感器有效分辨率設(shè)為:水平colcount,豎直rowcount,設(shè)已完成ai數(shù)組,且已完成邊界復(fù)制,ai數(shù)組表示為:數(shù)組坐標(biāo)從0開始,設(shè)像素坐標(biāo)為(x,y),從0開始,可推導(dǎo)出像素所屬塊為:[i][j],此處加1表示對邊界進行了復(fù)制。
基于FPGA的并行運算,同時計算4個象限的值,通過符號位選擇輸出,結(jié)合ai二維矩陣到一維矩陣的轉(zhuǎn)換計算具體結(jié)果如下:
定義x[b'3]為取x的第3個bit,bit從0開始計數(shù)。
象限A:y[b'3]=0;x[b'3]=0
kya=(8-y%8);kxa=(8-x%8)
ai_A={ai[i][j]*(16-kxa)*(16-kya)+a[i][j-1]*kxa*(16-kya)
+ai[i-1][j]*(16-kxa)*kya+ai[i-1][j-1]*kxa*kya}>>8
象限B:y[b'3]=0;x[b'3]=1
kyb=(8-y%8);kxb=x%8
ai_B={ai[i][j]*(16-kxb)*(16-kyb)+a[i][j+1]*kxb*(16-kyb)
+ai[i-1][j]*(16-kxb)*kyb+ai[i-1][j+1]*kxb*kyb}>>8
象限C:y[b'3]=1;x[b'3]=0
kyc=y(tǒng)%8;kxc=(8-x%8)
ai_c={ai[i][j]*(16-kxc)*(16-kyc)+a[i][j-1]*kxc*(16-kyc)
+ai[i+1][j]*(16-kxc)*kyc+ai[i+1][j-1]*kxc*kyc}>>8
象限D(zhuǎn):y[b'3]=1;x[b'3]=1
kyd=y(tǒng)%8;kxd=x%8
ai_D={ai[i][j]*(16-kxd)*(16-kyd)+a[i][j+1]*kxd*(16-kyd)
+ai[i+1][j]*(16-kxd)*kyd+ai[i+1][j+1]*kxd*kyd}>>8
最終結(jié)果:Dout=Din*ai_X>>12,其中ai_X根據(jù)不同象限選擇ai_A/ai_B/ai_C/ai_D。
以16x16塊作為基本單元,資源消耗為單點FFC算法下的0.39%?;诔杀净蛘咂渌矫娴南拗疲贔PGA器件型號選定的情況下,即可用存儲資源數(shù)量一定的情況下,可以適當(dāng)?shù)脑龃髩K的大小來繼續(xù)降低對資源的需求,如增大到32x32塊時,消耗的資源下降到單點算法下的0.097%。隨著基本單元塊逐漸變大,雖然消耗資源越少,但是算法效果越不理想,所以在效果和資源消耗之間有一個折中,需要根據(jù)具體應(yīng)用場景進行取舍。從在Matlab中對算法進行仿真后結(jié)果來看,基本塊單元在128x128情況下,依然可以取得較好的效果(如圖3所示),此時資源消耗為單點算法下的0.006%,即使對于47.8MB高分辨率的圖像,其存儲資源消耗僅為2.9KB,這個資源消耗對于FPGA內(nèi)實現(xiàn)FFC算法將毫無問題。
在FPGA實現(xiàn)中,中間處理階段都是以8個像素為一個處理單元以增加并行效率。FFC算法需要根據(jù)像素坐標(biāo)計算索引號,令像素坐標(biāo)為(x,y),其中x為列號,y為行號,則ai數(shù)組中單元ai[i][j]而言,i=(y/16)+1,j=(x/16)+1;
對于一個8像素單元而言,y是相同的,x為8z~8z+7,z=0,1,2,…,此時計算得到的i,j都是相同的,即一個處理單元內(nèi)的8個像素對應(yīng)在ai數(shù)組中的索引號都是相同的。
按照算法思想,每個像素需要計算4個值,分別對應(yīng)4種情況。這4個值需要使用到9個ai數(shù)組單元,分別為:ai[i-1][j-1],ai[i-1][j],ai[i-1][j+1],ai[i][j-1],ai[i][j],ai[i][j+1],ai[i+1][j-1],ai[i+1][j],ai[i+1][j+1],對于算法文檔中提出的4個象限情況,一個處理單元內(nèi)的8個像素都同時屬于一個象限,所以不需要對8個像素分別進行判斷,只需要對第一個象限進行判斷即可。
對于第一個像素的判斷可以直接歸結(jié)為對一個處理單元偏移地址的判斷,比如8像素單元的索引為偶數(shù)(從0開始計數(shù)),此時單元內(nèi)的像素索引為0~7,那么就表示x[bit3]=0,如果8像素單元的索引為奇數(shù),此時單元內(nèi)的像素索引為8~15,那么就表示x[bit3]=1。
對于行數(shù)的判斷,則直接使用行編號[3]判斷即可,每個8像素單元一定在同一行內(nèi)。
總之,對于一個象限單元,比如20MB相機而言,一行有5120列,即640個8像素單元,索引號為0~639。假設(shè)某個8像素單元的索引號為N(N[0,639]),所在行數(shù)為y,則ai數(shù)組索引[i,j]為i=y(tǒng)/16+1,j=N*8/16+1=N/2+1;i,j均使用9-bit位寬寄存器表示。
計算得到[i,j]之后,需要從ai數(shù)組中讀取9個單元,這9個單元可以分成3組,組內(nèi)的3個單元都是地址連續(xù)的,此時需要看j的取值,由上知j=N/2+1,N=0,1,2,…,即j取值為1,2,3,…,這就無法實現(xiàn)組內(nèi)3個單元的一次性讀取,只能單個讀取,即9個單元需要消耗9個clock時鐘。ai數(shù)組單元總數(shù)為322×242=77924(需17-bit寄存器表示地址),每個單元為14-bit。
ai數(shù)組每行單元數(shù)量為5120/16+2=322(用一個9-bit位寬寄存器表示),可計算得到ai數(shù)組內(nèi)9個讀出單元地址(17-bit位寬寄存器表示)分別為:
(i-1)*322+(j-1),(i-1)*322+(j),(i-1)*322+(j+1)
(i)*322+(j-1),(i)*322+(j),(i)*322+(j+1)
(i+1)*322+(j-1),(i+1)*322+(j),(i+1)*322+(j+1)
因為對于一個8像素單元而言,內(nèi)部8個像素對應(yīng)的i,j都是相同的,這就表示對于8個像素而言,使用的ai元素是相同的,即一個8像素單元只需要讀取9個ai單元,同時由于8個像素也位于相同的像系中,所以對于8個像素而言,都是取相同的像系值進行最終計算。
另外4個像系的公式可以統(tǒng)一為:
ai_out=A*(16-a0)*(16-a1)+B*a0*(16-a1)+C*(16-a0)*a1+D*a0*a1;
根據(jù)像系的不同,其中的A、B、C、D、ao和a1計算方式有不同。
具體實現(xiàn)細節(jié):
1.根據(jù)行號lines_rd,8像素單元號cnt_rd計算i,j:
i=lines_rd/16+1,j=cnt_rd/2+1;
2.根據(jù)i,j計算ram_addr:
(i-1)*322+(j-1),(i)*322+(j-1),(i+1)*322+(j-1);
3.根據(jù)lines_rd,8個8像素單元對應(yīng)的cnt_rd判斷8個8像素單元的象限,獲取各單元的A、B、C、D、ao和a1值;
4.計算各單元的
ai_out=A*(16-a0)*(16-a1)+B*a0*(16-a1)+C*(16-a0)*a1+D*a0*a1;
5.計算最終結(jié)果dout=(din*ai_out)>>12。注意8個8像素單元具有不同的ai_out值,但是8像素單元內(nèi)的8個像素使用相同的ai_out,即同時可以輸出64像素的值。矯正效果參考圖4的對比結(jié)果。
以上所述實施方式僅僅是對本發(fā)明的優(yōu)選實施方式進行描述,并非對本發(fā)明的范圍進行限定,在不脫離本發(fā)明設(shè)計精神的前提下,本領(lǐng)域普通技術(shù)人員對本發(fā)明的技術(shù)方案作出的各種變形和改進,均應(yīng)落入本發(fā)明的權(quán)利要求書確定的保護范圍內(nèi)。