【第八節(jié)】程序性能檢測及優(yōu)化
目標(biāo)
????????在圖像處理中你每秒鐘都要做大量的運(yùn)算,所以你的程序不僅要能給出正確的結(jié)果,同時(shí)還必須要快。所以這節(jié)我們將要學(xué)習(xí):
????????除了OpenCV, Python 也提供了一個(gè)叫time的的模塊,你可以用它來測量程序的運(yùn)行時(shí)間。另外-個(gè)叫做profile的模塊會(huì)幫你得到--份關(guān)于你的程序的詳細(xì)報(bào)告,其中包含了代碼中每個(gè)函數(shù)運(yùn)行需要的時(shí)間,以及每個(gè)函數(shù)被調(diào)用的次數(shù)。如果你正在使用IPython的話,所有這些特點(diǎn)都被以-種用戶友好的方式整合在一起了。我們會(huì)學(xué)習(xí)幾個(gè)重要的,要想學(xué)到更加詳細(xì)的知識就打開更多資源中的鏈接吧。
1、使用OpenCV檢測程序效率
????????CV2.getTickCount函數(shù)返回從參考點(diǎn)到這個(gè)函數(shù)被執(zhí)行的時(shí)鐘數(shù)。所以當(dāng)你在一個(gè)函數(shù)執(zhí)行前后都調(diào)用它的話,你就會(huì)得到這個(gè)函數(shù)的執(zhí)行時(shí)間(時(shí)鐘數(shù))。
????????CV2.getTickFrequency返回時(shí)鐘頻率,或者說每秒鐘的時(shí)鐘數(shù)。所以你可以按照下面的方式得到一個(gè)函數(shù)運(yùn)行了多少秒:
????????我們將會(huì)用下面的例子演示。下面的例子使用窗口大小不同(5,7,9)的核函數(shù)來做中值濾波:
2、OpenCV中的默認(rèn)優(yōu)化
????????OpenCV中的很多函數(shù)都被優(yōu)化過(使用SSE2, AVX等)。也包含一些沒有被優(yōu)化的代碼。如果我們的系統(tǒng)支持優(yōu)化的話要盡量利用只一點(diǎn)。在編譯時(shí)優(yōu)化是被默認(rèn)開啟的。因此OpenCV運(yùn)行的就是優(yōu)化后的代碼,如果你把優(yōu)化關(guān)閉的話就只能執(zhí)行低效的代碼了。你可以使用函數(shù)CV2.useOptimized()來查看優(yōu)化是否被開啟了,使用函數(shù)CV2.setUseOptimized()來開啟優(yōu)化。
3、更多 IPython的魔法命令
????還有幾個(gè)魔法命令可以用來檢測程序的效率,profiling, line profiling,內(nèi)存使用等。他們都有完善的文檔。所以這里只提供了超鏈接。感興趣的可以自己學(xué)習(xí)一下。
4、 效率優(yōu)化技術(shù)
????????有些技術(shù)和編程方法可以讓我們最大的發(fā)揮Python和Numpy的威力。我們這里僅僅提一下相關(guān)的,你可以通過超鏈接查找更多詳細(xì)信息。我們要說的最重要的- -點(diǎn)是:首先用簡單的方式實(shí)現(xiàn)你的算法(結(jié)果正確最重要),當(dāng)結(jié)果正確后,再使用上面的提到的方法找到程序的瓶頸來優(yōu)化它。
盡量避免使用循環(huán),尤其雙層三層循環(huán),它們天生就是非常慢的。
算法中盡量使用向量操作,因?yàn)镹umpy和OpenCV都對向量操作進(jìn)行了優(yōu)化。
利用高速緩存一致性。
沒有必要的話就不要復(fù)制數(shù)組。使用視圖來代替復(fù)制。數(shù)組復(fù)制是非常浪費(fèi)資源的。
就算進(jìn)行了上述優(yōu)化,如果你的程序還是很慢,或者說大的訓(xùn)話不可避免的話,你應(yīng)該嘗試使用其他的包,比如說Cython,來加速你的程序。