經(jīng)常用到ffmpeg中的sws_scale來(lái)進(jìn)行圖像縮放和格式轉(zhuǎn)換,該函數(shù)可以使用各種不同算法來(lái)對(duì)圖像進(jìn)行處理。以前一直很懶,懶得測(cè)試和甄別應(yīng)該使用哪種算法,最近的工作時(shí)間,很多時(shí)候需要等待別人。忙里偷閑,對(duì)ffmpeg的這一組函數(shù)進(jìn)行了一下封裝,順便測(cè)試了一下各種算法。
簡(jiǎn)單說(shuō)一下測(cè)試環(huán)境,我使用的是Dell的品牌機(jī),i5的CPU。ffmpeg是2010年8月左右的當(dāng)時(shí)最新版本編譯而成,我使用的是其靜態(tài)庫(kù)版本。
首先,將一幅1920*1080的風(fēng)景圖像,縮放為400*300的24位RGB,下面的幀率,是指每秒鐘縮放并渲染的次數(shù)。(經(jīng)過(guò)我的測(cè)試,渲染的時(shí)間可以忽略不計(jì),主要時(shí)間還是耗費(fèi)在縮放算法上。)
算法 |
幀率 |
圖像主觀感受 |
SWS_FAST_BILINEAR |
228 |
圖像無(wú)明顯失真,感覺(jué)效果很不錯(cuò)。 |
SWS_BILINEAR |
95 |
感覺(jué)也很不錯(cuò),比上一個(gè)算法邊緣平滑一些。 |
SWS_BICUBIC |
80 |
感覺(jué)差不多,比上上算法邊緣要平滑,比上一算法要銳利。 |
SWS_X |
91 |
與上一圖像,我看不出區(qū)別。 |
SWS_POINT |
427 |
細(xì)節(jié)比較銳利,圖像效果比上圖略差一點(diǎn)點(diǎn)。 |
SWS_AREA |
116 |
與上上算法,我看不出區(qū)別。 |
SWS_BICUBLIN |
87 |
同上。 |
SWS_GAUSS |
80 |
相對(duì)于上一算法,要平滑(也可以說(shuō)是模糊)一些。 |
SWS_SINC |
30 |
相對(duì)于上一算法,細(xì)節(jié)要清晰一些。 |
SWS_LANCZOS |
70 |
相對(duì)于上一算法,要平滑(也可以說(shuō)是模糊)一點(diǎn)點(diǎn),幾乎無(wú)區(qū)別。 |
SWS_SPLINE |
47 |
和上一個(gè)算法,我看不出區(qū)別。 |
總評(píng),以上各種算法,圖片縮小之后的效果似乎都不錯(cuò)。如果不是對(duì)比著看,幾乎看不出縮放效果的好壞。上面所說(shuō)的清晰(銳利)與平滑(模糊),是一種客觀感受,并非清晰就比平滑好,也非平滑比清晰好。其中的Point算法,效率之高,讓我震撼,但效果卻不差。此外,我對(duì)比過(guò)使用CImage的繪制時(shí)縮放,其幀率可到190,但效果慘不忍睹,顏色嚴(yán)重失真。
第二個(gè)試驗(yàn),將一幅1024*768的風(fēng)景圖像,放大到1920*1080,并進(jìn)行渲染(此時(shí)的渲染時(shí)間,雖然不是忽略不計(jì),但不超過(guò)5ms的渲染時(shí)間,不影響下面結(jié)論的相對(duì)準(zhǔn)確性)。
算法 |
幀率 |
圖像主觀感受 |
SWS_FAST_BILINEAR |
103 |
圖像無(wú)明顯失真,感覺(jué)效果很不錯(cuò)。 |
SWS_BILINEAR |
100 |
和上圖看不出區(qū)別。 |
SWS_BICUBIC |
78 |
相對(duì)上圖,感覺(jué)細(xì)節(jié)清晰一點(diǎn)點(diǎn)。 |
SWS_X |
106 |
與上上圖無(wú)區(qū)別。 |
SWS_POINT |
112 |
邊緣有明顯鋸齒。 |
SWS_AREA |
114 |
邊緣有不明顯鋸齒。 |
SWS_BICUBLIN |
95 |
與上上上圖幾乎無(wú)區(qū)別。 |
SWS_GAUSS |
86 |
比上圖邊緣略微清楚一點(diǎn)。 |
SWS_SINC |
20 |
與上上圖無(wú)區(qū)別。 |
SWS_LANCZOS |
64 |
與上圖無(wú)區(qū)別。 |
SWS_SPLINE |
40 |
與上圖無(wú)區(qū)別。 |
總評(píng),Point算法有明顯鋸齒,Area算法鋸齒要不明顯一點(diǎn),其余各種算法,肉眼看來(lái)無(wú)明顯差異。此外,使用CImage進(jìn)行渲染時(shí)縮放,幀率可達(dá)105,效果與Point相似。
個(gè)人建議,如果對(duì)圖像的縮放,要追求高效,比如說(shuō)是視頻圖像的處理,在不明確是放大還是縮小時(shí),直接使用SWS_FAST_BILINEAR算法即可。如果明確是要縮小并顯示,建議使用Point算法,如果是明確要放大并顯示,其實(shí)使用CImage的Strech更高效。
當(dāng)然,如果不計(jì)速度追求畫(huà)面質(zhì)量。在上面的算法中,選擇幀率最低的那個(gè)即可,畫(huà)面效果一般是最好的。
不過(guò)總的來(lái)說(shuō),ffmpeg的scale算法,速度還是非常快的,畢竟我選擇的素材可是高清的圖片。
(本想順便上傳一下圖片,但各組圖片差異其實(shí)非常小,恐怕上傳的時(shí)候格式轉(zhuǎn)換所造成的圖像細(xì)節(jié)丟失,已經(jīng)超過(guò)了各圖片本身的細(xì)節(jié)差異,因此此處不上傳圖片了。)
注:試驗(yàn)了一下OpenCV的Resize效率,和上面相同的情況下,OpenCV在上面的放大試驗(yàn)中,每秒可以進(jìn)行52次,縮小試驗(yàn)中,每秒可以進(jìn)行458次。