在2年前,我寫(xiě)過(guò)SSE圖像算法優(yōu)化系列十八:三次卷積插值的進(jìn)一步SSE優(yōu)化 一文,在那里使用了SSE對(duì)三次卷積插值進(jìn)行了SSE優(yōu)化,原本以為那個(gè)速度已經(jīng)比較極限了,最新遇到一個(gè)項(xiàng)目需要更高速的效果,自己又對(duì)這個(gè)算法進(jìn)行了下構(gòu)思,發(fā)現(xiàn)原來(lái)根本不是那回事,速度極限離天花板還早著呢。 早期的優(yōu)化中,僅僅是在每個(gè)像素的放大內(nèi)部使用SIMD指令進(jìn)行處理,而沒(méi)有考慮每個(gè)相鄰像素或者相鄰行像素之間的聯(lián)系和關(guān)系,因此呢計(jì)算量依舊是很大。 再來(lái)仔細(xì)看看三次立方插值,他需要涉及到像素是4*4的領(lǐng)域,共有16個(gè)權(quán)重,但是16個(gè)權(quán)重可以看成是水平和垂直分離的,因此可以先計(jì)算行方向的累計(jì)值,然后再計(jì)算列方向的累加和,我們發(fā)現(xiàn),在放大和縮小時(shí),這4行的取樣點(diǎn)一般來(lái)說(shuō)總會(huì)有部分是重疊的,甚至是完全重疊的,如果是完全重疊,那么水平方向的累加和是根本無(wú)需進(jìn)行計(jì)算的,部分重疊時(shí),也可以只計(jì)算重疊的部分,這個(gè)時(shí)候,整體的計(jì)算量將大大的減少。這也是行和列分離計(jì)算所帶來(lái)的好處。4*4的取樣這個(gè)特性,決定他在某方面非常合適使用SIMD指令進(jìn)行優(yōu)化。對(duì)于灰度圖,由于其一個(gè)采樣點(diǎn)水平方向只涉及到4個(gè)像素(4個(gè)字節(jié)),不適合在取樣時(shí)就計(jì)算其水平方向的累加值(是指不適合用SIMD指令,如果純C實(shí)現(xiàn)反而就要在取樣時(shí)計(jì)算了),我們先收集取樣數(shù)據(jù),然后再整體計(jì)算累加值時(shí)使用SIMD指令優(yōu)化,而對(duì)于24位或者是32位圖,由于取樣4個(gè)像素占用了12個(gè)字節(jié)和16個(gè)字節(jié),此時(shí)就可以直接在取樣時(shí)進(jìn)行計(jì)算,避免了收集取樣數(shù)據(jù)的耗時(shí),使得彩色模式圖像比灰度也僅僅多了一倍時(shí)間,而不是3倍或4倍。 就是這么一個(gè)簡(jiǎn)單的思路,能極大的提高算法的速度,而對(duì)于另外一個(gè)經(jīng)典的Lanczos4插值算法,他涉及到的領(lǐng)域范圍是8*8,同樣可以使用上述的方式進(jìn)行優(yōu)化。 測(cè)試一幅720P的彩色圖放大到1080P,三次立方插值單次的執(zhí)行時(shí)間越月8.5ms, Lanczos4的耗時(shí)17.7ms左右,如果是灰度圖像,則三次立方耗時(shí)約6ms,Lanczos4用時(shí)7.5ms,差異很小。 如果4K彩色圖縮小到1080P圖,三次立方插值單次的執(zhí)行時(shí)間越15ms, Lanczos4的耗時(shí)31ms左右,如果是灰度圖像,則三次立方耗時(shí)約10ms,Lanczos4用時(shí)也是10ms左右,也差異很小。 和Opencv比較發(fā)現(xiàn),CV你如果調(diào)用100次某個(gè)圖的放大,他是多線程的執(zhí)行的,CPU使用率到了100%,而且這個(gè)時(shí)候他的速度也就是和我的差不多。 另外,三次立方插值其實(shí)有個(gè)參數(shù)可以調(diào)節(jié),他控制了結(jié)果是銳化還是模糊一些,如下圖所示:
|
|
來(lái)自: 新進(jìn)小設(shè)計(jì) > 《待分類(lèi)》