常文斌,牟明任,賈海鵬,張?jiān)迫?,張思?/p>
(1.大連海洋大學(xué) 信息工程學(xué)院,遼寧 大連 116023;2.中國(guó)科學(xué)院計(jì)算技術(shù)研究所 處理器芯片全國(guó)重點(diǎn)實(shí)驗(yàn)室,北京 100190)
圖像濾波是圖像處理領(lǐng)域中具有廣泛應(yīng)用場(chǎng)景的算法,主要應(yīng)用于超聲醫(yī)學(xué)、航空航天、數(shù)字媒體、人工智能等領(lǐng)域。圖像濾波可以起到降低椒鹽噪聲、圖像二值化、邊緣識(shí)別和提取圖像特征的作用。常見的圖像濾波方法有形態(tài)學(xué)濾波、盒式濾波、閾值濾波、壓縮濾波、算術(shù)濾波等。從實(shí)現(xiàn)原理來分析,各種濾波算法根據(jù)原始圖像的像素狀態(tài),經(jīng)過一系列不同的運(yùn)算得到目標(biāo)像素值。
圖像濾波算法的研究已經(jīng)相當(dāng)廣泛,但是在實(shí)際應(yīng)用中仍存在許多不足之處。例如,在Android 平臺(tái)方面,雖然開源的OpenCV 庫(kù)已經(jīng)提供了較全面的圖像濾波算法,但是與其他平臺(tái)相比,其在Android 平臺(tái)的性能表現(xiàn)仍存在較大的差距。目前,還沒有廣泛應(yīng)用的專門針對(duì)Android 平臺(tái)進(jìn)行優(yōu)化的高性能圖像濾波算法庫(kù)。
隨著移動(dòng)終端和Android 操作系統(tǒng)的發(fā)展和普及,面向多平臺(tái)可移植嵌入式設(shè)備的高性能圖像濾波算法庫(kù)亟待完善。雖然目前在Apple 平臺(tái)已有MPS、Core Image、Vision 等算法 庫(kù),但是其 僅支持Apple 硬件和iOS 系統(tǒng),并不普遍適用于Android系統(tǒng)。
為進(jìn)一步提高移動(dòng)Android 端及相關(guān)嵌入式平臺(tái)上圖像濾波算法的實(shí)際性能表現(xiàn),本文提出一種專門針對(duì)Android 端及其嵌入式平臺(tái)進(jìn)行優(yōu)化的高性能圖像濾波算法。在Android 平臺(tái)上,基于OpenGL ES 編程接口,利用OpenGL 紋理對(duì)象和緩沖傳遞圖像數(shù)據(jù),通過計(jì)算著色器實(shí)現(xiàn)算法的并行優(yōu)化,設(shè)計(jì)一種針對(duì)移動(dòng)Android 端基于OpenGL ES接口的優(yōu)化體系,實(shí)現(xiàn)并優(yōu)化一系列濾波算法,以提升算法運(yùn)算性能。
OpenGL[1]是用于渲染2D、3D 矢量圖形的跨語言、跨平臺(tái)的應(yīng)用程序編程接口,而本文用到的OpenGL ES 3.2[2]是OpenGL 的1 個(gè)子集,主要針對(duì)移動(dòng)電話、手持設(shè)備、家電設(shè)備、汽車等嵌入式設(shè)備而設(shè)計(jì)的。研究指出,在移動(dòng)設(shè)備上采用OpenGL ES實(shí)現(xiàn)的視頻濾波算法[3],相比現(xiàn)有的OpenCV 濾波算法庫(kù),在內(nèi)存和功耗方面具有更大的優(yōu)勢(shì),在算法性能方面也有顯著提升。相關(guān)研究顯示,面向Android系統(tǒng)的硬件設(shè)備對(duì)OpenGL ES 有更加友好的支持[4]。然而,目前還缺少針對(duì)Android 平臺(tái)設(shè)計(jì)、使用OpenGL ES 實(shí)現(xiàn)和優(yōu)化性能較好的圖像濾波算法。因此,上述研究為本文選擇使用OpenGL ES 編程接口來實(shí)現(xiàn)和優(yōu)化圖像濾波算法提供了有價(jià)值的參考。
在OpenGL 的眾多著色器中,計(jì)算著色器是一種用于通用計(jì)算的特殊著色器,其本身可以看作一種特殊的、單一階段的管線,以更加充分地利用GPU的計(jì)算能力[5]。目前,研究人員提出采用OpenGL 計(jì)算著色器實(shí)現(xiàn)矩陣乘法[6]。但是在使用計(jì)算著色器進(jìn)行圖像濾波計(jì)算方面的研究還較不足,為本文基于OpenGL ES 計(jì)算著色器的算法優(yōu)化工作提供了一定的參考。
相關(guān)研究指出,在OpenGL 中,紋理和緩沖的存儲(chǔ)和訪問方式非常適合在CPU 和GPU 之間高效地傳輸圖像數(shù)據(jù)[7-9]。就紋理而言,在著色器內(nèi)使用紋理坐標(biāo)對(duì)紋理像素進(jìn)行訪問,實(shí)現(xiàn)像素級(jí)的計(jì)算和操作[10]。然而,在現(xiàn)有研究中,紋理主要被用于在片元著色器中對(duì)圖像進(jìn)行采樣和處理[11],例如利用紋理映射技術(shù)將紋理圖像應(yīng)用于幾何圖形中,以獲得更逼真的渲染效果[12]。在計(jì)算著色器中使用紋理操作數(shù)據(jù)的研究相對(duì)較少。因此,在OpenGL ES 中,將紋理與計(jì)算著色器相結(jié)合,以實(shí)現(xiàn)更高效的并行計(jì)算和數(shù)據(jù)操作的研究具有一定意義。
目前,已經(jīng)有相當(dāng)一部分針對(duì)圖像濾波算法進(jìn)行優(yōu)化的研究,例如,基于NVIDIA 公司的GPU 采用CUDA 編程模型[13]對(duì)盒式濾波、高斯濾波進(jìn)行并行優(yōu)化[14],基于ARMv8 處理器,采用SIMD 和匯編指令對(duì)圖像濾波算法進(jìn)行優(yōu)化[15]。此外,研究人員通過引入Graph-Waving 架構(gòu)[16],提升SIMD 元件利用率,以有效提升算法性能。針對(duì)SIMD 等指令級(jí)并行性和流水線的優(yōu)化工作[17-19]都不同程度地提高其研究算法的性能。上述研究表明,通過并行優(yōu)化方式可以顯著提升圖像濾波算法性能,有效提高圖像濾波的處理速度和效率。然而,目前的優(yōu)化工作大多都基于多核CPU[20]或者基于GPU,使用圖形渲染方式進(jìn)行優(yōu)化?;贏ndroid 平臺(tái),使用OpenGL ES計(jì)算著色器并行優(yōu)化的研究相對(duì)不足。
此外,還有相當(dāng)一部分研究是對(duì)基于圖形學(xué)的圖像濾波效果進(jìn)行優(yōu)化[21-23],并未對(duì)算法的運(yùn)算效率和性能優(yōu)化做更多的闡述。例如,相關(guān)研究在移動(dòng)Android 設(shè)備中將油畫濾波算法通過OpenGL ES圖形渲染管線實(shí)現(xiàn)并進(jìn)行優(yōu)化[24],取得較優(yōu)的圖像效果。但是,該類工作主要側(cè)重于圖形學(xué)效果的優(yōu)化,對(duì)算法運(yùn)算效率的提升并不顯著[25]。也有研究從圖形學(xué)的實(shí)現(xiàn)原理出發(fā),對(duì)形態(tài)學(xué)濾波算法的并行實(shí)現(xiàn)進(jìn)行研究[26],取得了較高的計(jì)算精度和較優(yōu)的圖像效果。然而,在許多應(yīng)用場(chǎng)景中,本文更加關(guān)注在滿足一定精度要求的同時(shí)優(yōu)化算法性能,以提高其在實(shí)際應(yīng)用中的速度和效率。
在插值和投影等優(yōu)化算法中,查表法具有較好的優(yōu)化效果[27]。這項(xiàng)研究為本文在閾值濾波算法中使用查表法提供了一定的參考。
線性濾波是指由源圖像某一像素點(diǎn)周圍濾波窗口數(shù)量的像素值經(jīng)過一系列的算術(shù)運(yùn)算,得到最終輸出圖像像素值的濾波算法。線性濾波算法計(jì)算式如下:
其中:kkerne(lx',y')為不同的卷積算子;x'和y'的值隨卷積算子大小而定,不同的卷積核對(duì)應(yīng)不同的濾波算法。本文研究的線性濾波算法有盒式濾波和算術(shù)濾波。
從原理方面分析,線性濾波根據(jù)某一特定卷積算子(由具體的濾波算法而定),按照從左到右、從上到下的順序,對(duì)原始圖像逐個(gè)像素進(jìn)行卷積運(yùn)算。
以盒式濾波為例,當(dāng)Normalize 參數(shù)設(shè)定為True時(shí)其算法原理如圖1 所示,圖中kernel 為1 個(gè)3×3 的卷積算子。將3×3 窗口內(nèi)的源圖像數(shù)據(jù)與卷積算子對(duì)應(yīng)位置的數(shù)據(jù)相乘,再把求得的9 個(gè)數(shù)相加,將最終值賦給當(dāng)前的錨點(diǎn),即為算法所求的值。錨點(diǎn)為濾波窗口的中心,對(duì)于某些特殊的計(jì)算需求,錨點(diǎn)也可自定義為濾波窗口內(nèi)的任一位置。
非線性濾波是指源圖像通過取最值、置零和取絕對(duì)值等一系列邏輯運(yùn)算(而非算術(shù)運(yùn)算),求得目標(biāo)像素點(diǎn)的濾波算法。本文研究的非線性濾波算法包含形態(tài)學(xué)濾波、閾值濾波和壓縮濾波。從實(shí)現(xiàn)原理來分析,非線性濾波也有線性濾波中類似卷積算子的概念,但兩者的區(qū)別在于:線性濾波的卷積算子是不同算法有不同的值;在非線性濾波中,卷積算子的數(shù)值可以看作是濾波窗口內(nèi)源圖像的像素值。非線性濾波算法通過在源圖像卷積窗口內(nèi)進(jìn)行邏輯運(yùn)算,以替換源圖像像素錨點(diǎn)的值,從而實(shí)現(xiàn)相關(guān)濾波功能。
形態(tài)學(xué)濾波是一種基于數(shù)學(xué)形態(tài)學(xué)的典型非線性濾波方法,通過計(jì)算濾波窗口內(nèi)的最值來替換源圖像像素值,使得圖像內(nèi)的噪聲被濾波窗口內(nèi)的最值代替,以達(dá)到形態(tài)學(xué)的腐蝕和膨脹等目的,為圖像邊緣檢測(cè)和特征提取提供數(shù)據(jù)基礎(chǔ)。1 個(gè)大小為3×3 濾波窗口的形態(tài)學(xué)腐蝕濾波算法示意圖如圖2 所示,src 為源圖像像素值,dst 為輸出圖像像素值。
圖2 形態(tài)學(xué)腐蝕濾波算法原理示意圖Fig.2 Schematic diagram of the principle of morphological erode filtering algorithm
形態(tài)學(xué)腐蝕濾波、膨脹和梯度算法計(jì)算式分別如式(2)~式(4)所示:
其中:eelement為濾波窗口。本文只研究矩形濾波窗口,通常其長(zhǎng)、寬相等且為奇數(shù)如3×3、5×5、7×7 等。
根據(jù)算法性質(zhì),形態(tài)學(xué)執(zhí)行次數(shù)可以與卷積窗口大小相關(guān)聯(lián),當(dāng)執(zhí)行次數(shù)大于1 時(shí),通過式(5)和式(6)改變窗口大小,達(dá)到多次進(jìn)行濾波的圖像學(xué)效果,從而提升算法性能。
此外,形態(tài)學(xué)的開(Open)、關(guān)(Close)算法均基于erode 和dilate 計(jì) 算,不同之 處在于:Open 算法先執(zhí)行erode 后執(zhí)行dilate,而Close 算法先執(zhí)行dilate后執(zhí)行erode。此外,Gradient 算法則是將源圖像執(zhí)行1 次dilate,再將該計(jì)算結(jié)果與源圖像進(jìn)行erode 的計(jì)算結(jié)果做減法,得到形態(tài)學(xué)梯度圖。
本文所完成的圖像濾波算法首先在CPU 端進(jìn)行naive 實(shí)現(xiàn),再通過OpenGL ES 移植到移動(dòng)設(shè)備的CPU+GPU 異構(gòu)平臺(tái)上進(jìn)行優(yōu)化。
在形態(tài)學(xué)濾波的naive 實(shí)現(xiàn)中,本文采用先行后列求最值方式,輸入整幅圖像,按照濾波窗口大小,先將經(jīng)過邊界處理源圖像的行按照濾波窗口寬度大小求出最值,將每行的計(jì)算結(jié)果放至環(huán)形緩沖區(qū)(在算法程序內(nèi)部聲明,以首尾相連的方式組織數(shù)據(jù)的存儲(chǔ)結(jié)構(gòu)),將足夠數(shù)量的行(根據(jù)聲明的空間大小和圖像數(shù)據(jù)量而定)計(jì)算完成后,再按照濾波窗口高度計(jì)算列最值,如此往復(fù),直至循環(huán)整張圖像。該方式的優(yōu)點(diǎn):減少重復(fù)訪存,在計(jì)算列最值時(shí)直接重復(fù)使用求得的行最值,不須重復(fù)訪問源圖像數(shù)據(jù),將訪存不連續(xù)的濾波窗口變成訪存連續(xù)的行,大幅減少訪存的時(shí)間開銷。
盒式濾波的naive 實(shí)現(xiàn)與形態(tài)學(xué)先行后列的方法類似。本文將取最值操作改為求和操作,將濾波窗口內(nèi)的像素值累加并存儲(chǔ)在中間矩陣中,然后與濾波核中的數(shù)值做乘法,求得源圖像均值。在盒式濾波中,本文通過權(quán)值置一的方法提供了非歸一化的濾波算法。該算法可以用來計(jì)算源圖像各像素在濾波窗口鄰域內(nèi)的積分特征。
在閾值濾波算法的naive 實(shí)現(xiàn)中,分為定閾值濾波算法和自適應(yīng)閾值算法。在定閾值濾波算法中,本文支持自定義閾值和指定閾值計(jì)算方法。閾值計(jì)算的具體方法可以通過計(jì)算類間最大方差確定閾值的大津閾值法(Otsu's),該計(jì)算方法適合雙峰直方圖,還可以通過計(jì)算直方圖曲線與直線之間最大距離確定Triangle 閾值,適合單峰直方圖。Otsu's 算法計(jì)算類間最大方差的計(jì)算式如式(7)所示:
其中:x為像素值;n為權(quán)重。
閾值濾波還提供了5種不同的圖像二值化類型供用戶選擇。二值化(THRESH_BINARY)計(jì)算式如下:
反二值化(THRESH_BINARY_INV)計(jì)算式如下:
閾值截?cái)啵═HRESH_TRUNC)計(jì)算式如下:
閾值置零(THRESH_TOZERO)計(jì)算式如下:
反閾值置零(THRESH_TOZERO_INV)計(jì)算式如下:
自適應(yīng)閾值濾波的naive 實(shí)現(xiàn)示意圖如圖3 所示。本文首先采用高斯濾波或盒式濾波將源圖像(這里的源圖像為灰度圖)轉(zhuǎn)換為均值圖像;然后通過src-mean 對(duì)源圖像與均值圖像做減法,再結(jié)合權(quán)重,自適應(yīng)地將源圖像轉(zhuǎn)換為二值化圖像。此外,在算法的實(shí)現(xiàn)中,本文還引入查表法,提前計(jì)算灰度圖(像素值為0~255)所有可能像素值的二值化結(jié)果,并將結(jié)果存儲(chǔ)在Tab 表中,通過查表法將均值圖像的值與表的索引進(jìn)行對(duì)比。對(duì)于二值化計(jì)算,本文只需要將對(duì)比成功表中的二值化結(jié)果直接存入輸出圖像中。該方法在處理大規(guī)模的圖像像素?cái)?shù)據(jù)下可以減少一部分計(jì)算量。
圖3 自適應(yīng)閾值濾波的naive 實(shí)現(xiàn)示意圖Fig.3 Schematic diagram of naive implementation of adaptive threshold filtering
算術(shù)濾波naive 算法實(shí)現(xiàn)了單通道圖像(只包含一種顏色通道的圖像)和三通道圖像(R、G、B 圖像)像素值的加權(quán)算術(shù)運(yùn)算。通過2 幅相同尺寸圖像上對(duì)應(yīng)的像素點(diǎn),將對(duì)應(yīng)通道像素值的和、差、商、積算術(shù)運(yùn)算作為目標(biāo)像素點(diǎn)值。加權(quán)積和加權(quán)商算法計(jì)算式如下:
其中:sscale為權(quán)值;ssaturate將像素值限制在0~255 之間。
壓縮濾波在naive 實(shí)現(xiàn)中支持單通道和三通道這2 種圖像格式,支持將源圖像像素值按照行和列壓縮的2 種壓縮方法。算法原理為求得當(dāng)前行或列的像素最值、均值或者像素和,用所求值代替源圖像的當(dāng)前行或當(dāng)前列,使圖像一維化。圖4 所示為三通道圖像數(shù)據(jù)按照求均值按行壓縮以及三通道圖像數(shù)據(jù)求和按列壓縮示意圖。本文通過壓縮濾波將1 個(gè)三通道圖像變成1 個(gè)一維的三通道向量。
圖4 三通道圖像壓縮濾波算法示意圖Fig.4 Schematic diagram of three-channel image compression filtering algorithm
在本文所實(shí)現(xiàn)的圖像濾波naive 算法中,當(dāng)算法處理到圖像邊界像素時(shí),時(shí)常會(huì)出現(xiàn)超出圖像邊界的情況。如果不對(duì)邊界進(jìn)行處理,那么在訪問這些位置時(shí)可能會(huì)產(chǎn)生越界操作。針對(duì)該問題,本文提出如圖5 所示的邊界處理方法。
該方法包括默認(rèn)邊界、由用戶指定的常數(shù)邊界、用源圖像同側(cè)值填充的復(fù)制邊界、用源圖像邊界鏡像像素值填充的鏡像邊界。
圖像濾波算法本身具有較優(yōu)的數(shù)據(jù)獨(dú)立性、局部性和數(shù)據(jù)重用性的并行特征,適合在大規(guī)模的細(xì)粒度圖形處理器GPU 中進(jìn)行處理。圖像濾波算法按照計(jì)算和訪存的特性可以大致分為數(shù)據(jù)無關(guān)算法和數(shù)據(jù)相關(guān)算法。
數(shù)據(jù)無關(guān)算法是指在算法中,源圖像各個(gè)連續(xù)的像素點(diǎn)通過各自單獨(dú)運(yùn)算獲得目標(biāo)像素值,各像素點(diǎn)之間沒有關(guān)聯(lián),互不影響,如本文實(shí)現(xiàn)的算術(shù)濾波和固定閾值的閾值濾波算法。該類算法計(jì)算獨(dú)立并且訪存連續(xù),具備良好的并行性。因此,本文對(duì)該類算法的優(yōu)化重點(diǎn)在于提高單個(gè)像素點(diǎn)的計(jì)算效率、提高數(shù)據(jù)的訪存以及對(duì)數(shù)據(jù)的并行計(jì)算效率。
對(duì)于這類問題的訪存優(yōu)化,通過同時(shí)執(zhí)行多個(gè)處理單元,采用批量讀寫數(shù)據(jù)的方式可以極大程度地提升訪存效率。在CPU 向GPU 傳遞數(shù)據(jù)時(shí),OpenGL 支持紋理和緩沖2 種大規(guī)模數(shù)據(jù)的存儲(chǔ)形式。相比緩沖這種通用的存儲(chǔ)形式而言,圖像濾波算法對(duì)圖像紋理這種結(jié)構(gòu)化的存儲(chǔ)形式更加友好。紋理存儲(chǔ)形式也更加適用于計(jì)算海量數(shù)據(jù)的著色器。本文通過紋理來實(shí)現(xiàn)大規(guī)模圖像數(shù)據(jù)在本地和著色器間的傳遞和操作,提高計(jì)算著色器對(duì)圖像像素?cái)?shù)據(jù)的處理效率。
在著色器內(nèi)部對(duì)圖像紋理進(jìn)行讀取和寫入操作的具體方法有imageLoad()、imageStore(),其中imageLoad()方法的返回值類型是vec4,在單通道圖像數(shù)據(jù)中,本文嘗試使用vec4 數(shù)據(jù)類型將單通道的數(shù)據(jù)向量化,以達(dá)到高效訪存的目的。經(jīng)過實(shí)驗(yàn)發(fā)現(xiàn),imageLoad()方法在單通道圖像數(shù)據(jù)中的返回值雖然仍是vec4 類型,但是實(shí)際上該方法只支持單獨(dú)像素單元的存取,在單通道數(shù)據(jù)中,并不支持使用其他通道。因此,計(jì)算著色器內(nèi)的訪存優(yōu)化以更加合理的線程布局和紋理存取像素值為主的方式實(shí)現(xiàn)。
數(shù)據(jù)相關(guān)算法是指目標(biāo)圖像中每個(gè)目標(biāo)像素值計(jì)算需要依賴源圖像中其他像素值參與的算法。例如,在計(jì)算目標(biāo)像素值時(shí),需要利用源圖像錨點(diǎn)像素值周圍一定范圍內(nèi)的鄰域像素值作為卷積核的一部分,共同參與計(jì)算,從而得到目標(biāo)像素值。本文所實(shí)現(xiàn)的形態(tài)學(xué)濾波、自適應(yīng)閾值濾波和盒式濾波均為數(shù)據(jù)相關(guān)算法。該類算法的優(yōu)化重點(diǎn)在于利用數(shù)據(jù)局部性原理,減少對(duì)內(nèi)存的頻繁訪問,提高訪存,以提高算法的效率和性能。例如,更加充分利用GPU的共享內(nèi)存或紋理緩存從而減少數(shù)據(jù)傳輸和訪問的延遲。本文所使用的實(shí)驗(yàn)平臺(tái)采用的共享內(nèi)存沒有性能提升,其原因可能是該設(shè)備的GPU 中沒有共享內(nèi)存硬件,也沒有高速存儲(chǔ)設(shè)備做支持。這一點(diǎn)在ARM Mali GPU 的開發(fā) 者文檔 中得到證實(shí)[28],Mali GPU 不為計(jì)算著色器實(shí)現(xiàn)提供專門的片上共享內(nèi)存,而是使用系統(tǒng)的RAM 實(shí)現(xiàn)相關(guān)功能。因此,對(duì)于該類算法的優(yōu)化策略,本文使用紋理訪問圖像數(shù)據(jù)、充分利用數(shù)據(jù)局部性、合理分配線程、提高Cache的命中率,進(jìn)一步提升訪存性能的優(yōu)化策略性能。
3.3.1 并行算法
本文采用計(jì)算著色器對(duì)圖像濾波算法進(jìn)行并行優(yōu)化,計(jì)算著色器屬于無固定輸入輸出的著色器(可以自定義輸入輸出變量),是OpenGL 中一種特殊的管線。這種特性使得它具有更強(qiáng)的靈活性,可用于執(zhí)行各種通用計(jì)算任務(wù),而不僅僅局限于圖形渲染。本文所提算法采用紋理來存儲(chǔ)數(shù)據(jù),使得計(jì)算著色器在GPU 上執(zhí)行計(jì)算任務(wù)時(shí)可以并行地直接訪問和處理大規(guī)模圖像數(shù)據(jù),無須頻繁地訪問全局內(nèi)存,這種方式能有效發(fā)揮計(jì)算著色器的優(yōu)勢(shì)。在本文的工作中并行算法計(jì)算的核心是在計(jì)算著色器的眾多工作組中執(zhí)行,通過調(diào)用gldispatchCompute()方法啟動(dòng)并發(fā)計(jì)算任務(wù),將圖像按照像素點(diǎn)分配線程,在GPU 上進(jìn)行處理。在GPU 中,全局工作組被劃分為多個(gè)局部工作組,局部工作組的大小可以自定義,在每個(gè)工作組中的若干個(gè)工作項(xiàng)通過計(jì)算著色器進(jìn)行運(yùn)算和操作。二維工作組的劃分示意圖如圖6所示。在計(jì)算著色器中,每個(gè)像素點(diǎn)在全局中的位置坐標(biāo)可由當(dāng)前工作組的坐標(biāo)、局部工作組大小和工作項(xiàng)坐標(biāo)表示,即gl_GlobalInvocationID=gl_WorkGroupID*gl_WorkGroup Size+gl_LocalInvocationID。本文在計(jì)算著色器內(nèi)全局的規(guī)劃線程進(jìn)行運(yùn)算和操作。合理劃分工作組大小可以在一定程度上有效提升算法性能。
在劃分工作組后,OpenGL 的每個(gè)工作組都根據(jù)計(jì)算著色器的核心算法并行地執(zhí)行相同的運(yùn)算。所有的計(jì)算和操作均在計(jì)算著色器內(nèi)完成。三通道圖像并行算法的示意圖如圖7 所示,pipeline 為僅有計(jì)算著色器的特殊管線,每個(gè)工作項(xiàng)均進(jìn)入以計(jì)算著色器為核心的特殊管線中。
圖7 三通道圖像并行算法示意圖Fig.7 Schematic diagram of three-channel image parallel algorithm
在形態(tài)學(xué)濾波的并行算法中,本文無須將圖像整體按照行列拆分運(yùn)算,而是同時(shí)開啟圖像像素點(diǎn)數(shù)量的工作項(xiàng),以單個(gè)像素點(diǎn)為單位進(jìn)行計(jì)算。在計(jì)算著色器中,本文提取當(dāng)前錨點(diǎn)附近的濾波窗口大小的像素點(diǎn),依次比較求出最值,再傳入到目標(biāo)圖像中。針對(duì)單通道、三通道和四通道圖像數(shù)據(jù),本文分別采 用OpenGL 自帶的GL_R、GL_RGB 和GL_RGBA 向量化的方式來實(shí)現(xiàn)。由于OpenGL ES 3.2在計(jì)算著色器內(nèi)僅支持布爾類型、32 bit 整數(shù)和浮點(diǎn)操作,因此在8U 圖像中,相比單通道數(shù)據(jù),三通道數(shù)據(jù)和四通道數(shù)據(jù)能更加充分利用存儲(chǔ)空間,具有較優(yōu)的優(yōu)化效果。
在盒式濾波的并行算法中,本文開辟圖像像素點(diǎn)大小的工作項(xiàng),將每個(gè)像素點(diǎn)所在位置作為錨點(diǎn),向周圍擴(kuò)展濾波窗口大小的像素點(diǎn),在計(jì)算著色器內(nèi),將這些像素點(diǎn)求和,并乘以權(quán)值(計(jì)算均值時(shí)為1(/kernel.x*kernel.y))的大小,在計(jì)算完成后,將結(jié)果傳到輸出紋理坐標(biāo)上,每個(gè)工作項(xiàng)均執(zhí)行這一相同計(jì)算。
在自定義閾值的閾值濾波并行算法中,本文將閾值和最大值(maxval)作為統(tǒng)一變量,通過統(tǒng)一變量綁定點(diǎn)傳入計(jì)算著色器內(nèi),在計(jì)算著色器內(nèi)判斷當(dāng)前像素值與閾值的大小關(guān)系,按照不同的閾值類型,將正確的目標(biāo)值寫入到輸出圖像所在的紋理坐標(biāo)中。
在自適應(yīng)的閾值濾波中,本文將經(jīng)過盒式濾波和高斯濾波計(jì)算后的中間矩陣mean 和源圖像src 一起傳入計(jì)算著色器中,用式(15)和式(16)替代naive實(shí)現(xiàn)中使用的查表法,減小Tab 表所占用的內(nèi)存空間和多次訪存開銷,將查表法的功能拆分重組,在計(jì)算著色器內(nèi)使用如下公式精簡(jiǎn)計(jì)算,進(jìn)一步提升算法性能:
在算術(shù)濾波的并行算法中,本文針對(duì)2 幅圖像的像素值進(jìn)行并行算術(shù)運(yùn)算。為實(shí)現(xiàn)該目標(biāo),本文同時(shí)將2 幅圖像的像素值綁定到紋理單元并傳入計(jì)算著色器中,在著色器內(nèi)部對(duì)2 幅圖像的每個(gè)坐標(biāo)位置數(shù)據(jù)進(jìn)行加、減、乘、除算術(shù)運(yùn)算,各紋理坐標(biāo)對(duì)應(yīng)像素點(diǎn)并行地通過計(jì)算著色器,將計(jì)算結(jié)果傳入至輸出圖像紋理單元中。算術(shù)濾波算法是典型的數(shù)據(jù)無關(guān)算法,單獨(dú)目標(biāo)像素值的計(jì)算只需要2 個(gè)源圖像對(duì)應(yīng)的坐標(biāo)值和權(quán)值即可,不需要其他源像素值和中間計(jì)算結(jié)果的參與。這種算法對(duì)于并行訪存和并行計(jì)算非常友好。本文優(yōu)化算法在實(shí)驗(yàn)設(shè)備中相對(duì)于OpenCV 開源庫(kù)中對(duì)應(yīng)算法的性能提高7 倍左右。
在壓縮濾波的并行算法中,本文基于算法原理將源圖像根據(jù)最值、均值以及求和壓縮成一行或者一列。在劃分工作組時(shí)根據(jù)目標(biāo)矩陣的情況(即一行或者一列)將工作組劃分為對(duì)訪存和計(jì)算更加友好的狀態(tài)。例如,將矩陣壓縮為一列時(shí),本文將每行作為1 個(gè)工作組,并將工作組大小設(shè)置為height 為1 的塊。本文采用這種方式在每個(gè)工作組中計(jì)算當(dāng)前行的數(shù)據(jù),從而減少重復(fù)的計(jì)算次數(shù)和訪存操作。
3.3.2 邊界處理優(yōu)化
在并行算法的邊界處理中,由于每個(gè)線程都通過相同的計(jì)算著色器,因此并行算法將邊界處理移至計(jì)算著色器中。在這種情況下,本文只須在著色器中判斷當(dāng)前計(jì)算所需坐標(biāo)像素是否在源圖像內(nèi)部。如果超出了源圖像的邊界,本文賦予其對(duì)應(yīng)邊界鏡像坐標(biāo)值或特定值等邊緣填充值即可。該方案在一定程度上提升了并行算法的整體性能,減少處理圖像邊界所帶來的大部分空間和時(shí)間開銷。
3.3.3 數(shù)據(jù)類型優(yōu)化
在數(shù)據(jù)類型方面,本文所使用的OpenGL ES 3.2目前支持32 bit 整數(shù)、浮點(diǎn)數(shù)和布爾類型數(shù)據(jù),對(duì)于其他數(shù)據(jù)類型并不支持。本文提供除整數(shù)和32 bit浮點(diǎn)數(shù)以下的其他數(shù)據(jù)解決方案:將8UC1 數(shù)據(jù)轉(zhuǎn)換為GL_R32UI 類 型,將8UC3 和8UC4 數(shù)據(jù)轉(zhuǎn)換為GL_RGBA32UI 類型,目前本文已經(jīng)安全地支持所有常用的8~32 bit 的有符號(hào)數(shù)和無符號(hào)數(shù)在OpenGL ES 進(jìn)行傳輸和運(yùn)算。
在CPU+GPU 的異構(gòu)平臺(tái)下,將數(shù)據(jù)在CPU 和GPU 之間進(jìn)行高效的通信是非常重要的,這也是本文優(yōu)化的重點(diǎn)方向。為此,本文分別針對(duì)小規(guī)模數(shù)據(jù)和大規(guī)模數(shù)據(jù)提出不同的解決方案。
在小規(guī)模數(shù)據(jù)方面,OpenGL 提供統(tǒng)一變量(Uniform)關(guān)鍵字,允許將這些數(shù)據(jù)作為全局變量通過glUniform*()方法綁定到緩沖區(qū)。由于本文所使用的計(jì)算著色器具有在著色器和本地之間保持同步和共享數(shù)據(jù)傳輸?shù)奶匦裕虼藢⒕彌_區(qū)作為存儲(chǔ)和傳輸小規(guī)模數(shù)據(jù)的媒介。
對(duì)于大規(guī)模數(shù)據(jù),采用Uniform 需要依次綁定,這顯然是非常低效的。為此,OpenGL 提供一致區(qū)塊,將需要輸入和輸出計(jì)算著色器的大量全局?jǐn)?shù)據(jù)映射在統(tǒng)一緩沖對(duì)象(Uniform Buffer Object,UBO)上,并通過綁定點(diǎn)使其相互對(duì)應(yīng)。UBO 綁定數(shù)據(jù)示意圖如圖8 所示。
本文在圖像數(shù)據(jù)由CPU 向GPU 上傳的過程和從GPU 向CPU 下載的過程中采用一致區(qū)塊,在GPU部分采用更利于計(jì)算著色器進(jìn)行并行訪存和計(jì)算的紋理存儲(chǔ)形式。在OpenGL ES 中紋理也可以綁定在Uniform 綁定點(diǎn)上,本文經(jīng)過紋理坐標(biāo)在計(jì)算著色器內(nèi)部訪問圖像像素點(diǎn),完成與圖像濾波相關(guān)的操作和計(jì)算。
本文實(shí)現(xiàn)的高性能圖像濾波算法庫(kù)在天璣1200處理器上進(jìn)行運(yùn)行測(cè)試。該處理器包含1 個(gè)主頻為3.0 GHz 的A78 大核心、3 個(gè)主頻 為2.6 GHz 的A78中核心,以及4 個(gè)主頻為2.04 GHz 的A55 小核心。此外,處理器還搭載了基于ARM Mali-G77 架構(gòu)的Mali-G77 MC9 GPU。實(shí)驗(yàn)中采用了4.5.5 版本的OpenCV 庫(kù)和3.2 版本的OpenGL ES 接口。具體的實(shí)驗(yàn)環(huán)境配置如表1 所示。
本文使用的所有源圖像數(shù)據(jù)都是通過程序生成的隨機(jī)數(shù),使用隨機(jī)數(shù)生成的圖像數(shù)據(jù)能夠消除真實(shí)圖像數(shù)據(jù)的特殊性和偏差,從而更準(zhǔn)確地評(píng)估不同算法和優(yōu)化技術(shù)的性能,同時(shí)確保了實(shí)驗(yàn)結(jié)果的可重復(fù)性,使得其他研究人員可以在相同條件下進(jìn)行復(fù)現(xiàn)和比較,使用隨機(jī)數(shù)生成的圖像數(shù)據(jù)也使得實(shí)驗(yàn)更具普適性。因此,本文實(shí)驗(yàn)結(jié)果不僅適用于特定類型或特定領(lǐng)域的圖像數(shù)據(jù),而且具有一般性和廣泛適應(yīng)性,對(duì)于算法和優(yōu)化技術(shù)的推廣和應(yīng)用具有重要意義。此外,本文調(diào)用了部分OpenCV 庫(kù)中圖像濾波算法與本文所提的優(yōu)化算法進(jìn)行性能對(duì)比。除非特別說明,否則本文在調(diào)用這些算法時(shí)均使用了默認(rèn)參數(shù),以確保對(duì)比實(shí)驗(yàn)的公平性和一致性。
本文實(shí)現(xiàn)的形態(tài)學(xué)濾波與OpenCV 庫(kù)中morphologyEx()函數(shù)在8UC3(三通道的8 bit 無符號(hào)整數(shù))的圖像數(shù)據(jù)下進(jìn)行對(duì)比。形態(tài)學(xué)濾波性能對(duì)比如圖9 所示(3×3、5×5、7×7 表示卷積窗口的大?。?。本文將算法中iterations 參數(shù)設(shè)置為1,得到最直觀的性能差異。在不同規(guī)模圖像中,本文實(shí)現(xiàn)的基于OpenGL ES 的優(yōu)化算法性能提升最大約為30.543 倍,性能提升最小約為1.994 倍,平均性能提升約為16.269 倍。
圖9 形態(tài)學(xué)濾波性能對(duì)比Fig.9 Comparison of morphological filtering performance
從圖9 可以看出,在OpenCV 算法中,隨著卷積窗口變大,相同計(jì)算規(guī)模下的算法耗時(shí)有不同程度增加,導(dǎo)致算法的整體性能下降。本文所實(shí)現(xiàn)的優(yōu)化算法OpenGL 在相同情況下并未顯示出明顯的性能差異,其原因?yàn)樵诰矸e窗口由3×3 變?yōu)?×7 時(shí),計(jì)算單個(gè)目標(biāo)像素值需要參與運(yùn)算的數(shù)據(jù)由9 個(gè)(3×3)增加到49 個(gè)(7×7),即每個(gè)目標(biāo)像素值的計(jì)算需要增加40 個(gè)數(shù)據(jù)。在OpenCV 的算法中,整幅圖像所有像素值的計(jì)算耗時(shí)會(huì)累積,從而導(dǎo)致算法的整體性能下降。相比OpenCV,本文實(shí)現(xiàn)的基于OpenGL ES優(yōu)化算法將由增大濾波窗口所帶來的負(fù)載均衡地分配到GPU 的每個(gè)核心上(從算法的角度將負(fù)載平均分配到每個(gè)工作項(xiàng)上)進(jìn)行并行執(zhí)行,而不是在單個(gè)計(jì)算核心上累積計(jì)算耗時(shí)。因此,濾波窗口的變化對(duì)該算法性能的影響大幅減小。
本文實(shí)現(xiàn)的盒式濾波優(yōu)化算法與OpenCV 的boxFilter()函數(shù)進(jìn)行對(duì)比。圖10 所示為8UC1(單通道的8 bit 無符號(hào)整數(shù))盒式濾波性能對(duì)比。8UC1 圖像數(shù)據(jù)中性能最高提升34.425 倍,最低提升1.602 倍,平均提升15.299 倍。圖11 所示為8UC3 盒式濾波性能對(duì)比。8UC3 圖像數(shù)據(jù)下性能最高提升110.018 倍,最低提升3.903 倍,平均提升42.150 倍。從圖10和圖11可以看出,本文實(shí)現(xiàn)的基于OpenGL ES優(yōu)化算法在處理三通道數(shù)據(jù)時(shí)表現(xiàn)更明顯的優(yōu)化效果。這是因?yàn)樵谶M(jìn)行三通道數(shù)據(jù)運(yùn)算時(shí),本文進(jìn)一步利用OpenGL 中紋理的特性,對(duì)三通道圖像中每個(gè)像素點(diǎn)上的3 個(gè)8U 數(shù)據(jù)進(jìn)行向量化操作,使得數(shù)據(jù)訪問更加連續(xù)且高效。該方法將優(yōu)化前使用3 條指令才能完成的工作減少到1 條指令,顯著提升算法的執(zhí)行性能和效率。
圖10 8UC1 盒式濾波性能對(duì)比Fig.10 Comparison of 8UC1 box filtering performance
圖11 8UC3 盒式濾波性能對(duì)比Fig.11 Comparison of 8UC3 box filtering performance
本文實(shí)現(xiàn)的自適應(yīng)閾值濾波算法與OpenCV 的adaptiveThreshold()函數(shù)性能對(duì)比如圖12 所示,將對(duì)比的2 個(gè)算法adaptiveMethod 參數(shù)均設(shè)置為ADAPTIVE_THRESH_GAUSSIAN_C,threshold--Type參數(shù)均設(shè)置為THRESH_BINARY。本文實(shí)現(xiàn)的基于OpenGL ES 優(yōu)化算法性能最高提升39.251 倍,最低提升2.125 倍,平均提升20.688 倍。
圖12 自適應(yīng)閾值濾波性能對(duì)比Fig.12 Comparison of adaptive threshold filtering performance
在本文實(shí)現(xiàn)的算術(shù)濾波算法中,除法(DIV,divide)算法與OpenCV 的divide()函數(shù)性能對(duì)比如圖13 所示。該算法性能最高提升13.365 倍,最低提升1.509 倍,平均提升7.437 倍。
在壓縮濾波中,最值(MAX)、均值(AVG)以及求和(SUM)算法與OpenCV 中的reduce()函數(shù)的性能對(duì)比如圖14 所示。相比OpenCV 中對(duì)應(yīng)算法,本文優(yōu)化算法性能最高提升57.863 倍,最低提升1.509 倍,平均提升29.686 倍。
圖14 壓縮濾波性能對(duì)比Fig.14 Comparison of compression filtering performance
從圖9~圖14 可以看出,隨著圖像規(guī)模的增大,本文優(yōu)化算法相對(duì)于OpenCV 中對(duì)應(yīng)算法的性能提升也逐漸增大。這種性能提升的原因主要有:本文采用計(jì)算著色器將整幅圖像的計(jì)算任務(wù)均勻分配到GPU 的多個(gè)核心上,能夠更充分地利用GPU 的計(jì)算資源,有效提高算法的并行性;本文通過紋理存儲(chǔ)圖像數(shù)據(jù)的方式減少對(duì)圖像數(shù)據(jù)的頻繁讀寫操作,從而減少訪存延遲和數(shù)據(jù)傳輸開銷,進(jìn)一步提升訪存性能。當(dāng)圖像數(shù)據(jù)由4 096×512 個(gè)增加到4 096×2 048 個(gè)時(shí),圖像數(shù)據(jù)增加到原來的4 倍。在OpenCV 算法中,處理這些數(shù)據(jù)所需的時(shí)間在單個(gè)核心上累積,導(dǎo)致大規(guī)模圖像的計(jì)算時(shí)間呈倍數(shù)增加。本文優(yōu)化算法能夠?qū)⒂?jì)算任務(wù)并行地分配到GPU的多個(gè)計(jì)算核心上,該計(jì)算核心同時(shí)處理這些計(jì)算任務(wù),更充分地利用GPU 的計(jì)算資源,使得性能提升逐漸增大。隨著圖像規(guī)模的增大,本文優(yōu)化算法在并行性和訪存優(yōu)化方面的優(yōu)勢(shì)也變得更加顯著。
此外,OpenCV 對(duì)應(yīng)的算法出現(xiàn)了一些明顯的性能下降點(diǎn)。這是因?yàn)樵谠搶?shí)驗(yàn)中,本文按照從小到大的趨勢(shì)分別設(shè)置了圖像的長(zhǎng)和寬。當(dāng)圖像的寬度從2 160 個(gè)像素點(diǎn)減小到512 個(gè)像素點(diǎn)時(shí),因圖像規(guī)模變小,相應(yīng)算法的運(yùn)行時(shí)間也會(huì)縮短。
整體上,本文實(shí)現(xiàn)的基于移動(dòng)Android 端使用OpenGL ES 的圖像濾波算法性能明顯優(yōu)于OpenCV庫(kù)中的相關(guān)算法。實(shí)驗(yàn)結(jié)果表明,本文實(shí)現(xiàn)的圖像濾波算法進(jìn)行的一系列優(yōu)化手段是有效的。
本文實(shí)現(xiàn)針對(duì)移動(dòng)Android平臺(tái)基于OpenGL ES的圖像濾波算法庫(kù),實(shí)現(xiàn)了形態(tài)學(xué)濾波、多種閾值濾波、盒式濾波、壓縮濾波、算術(shù)濾波。通過OpenGL計(jì)算著色器、紋理和統(tǒng)一變量對(duì)算法進(jìn)行優(yōu)化,總體上其性能與OpenCV 開源庫(kù)相關(guān)算法相比得到顯著提高,平均性能為OpenCV 的21.561 倍,在優(yōu)化性能的同時(shí)也為基于Android 平臺(tái)使用OpenGL ES 的高性能圖像濾波算法提供了新的優(yōu)化方案。本文所實(shí)現(xiàn)的圖像濾波算法全面適配8U 數(shù)據(jù)類型且滿足少量32S 數(shù)據(jù)類型。下一步將在更多數(shù)據(jù)類型上對(duì)算法的實(shí)現(xiàn)和優(yōu)化進(jìn)行研究,以擴(kuò)大高性能圖像濾波算法庫(kù)的數(shù)據(jù)類型應(yīng)用場(chǎng)景。