影像處理初級技巧
這裡只介紹初級技巧,並且多數只是一些提示,不包含代碼和一些概念的詳細說明。
技巧一:雙緩衝消除閃爍。
很多初學者認為閃爍產生的原因是重新整理速度太慢,這是個完全錯誤的認識。
閃爍產生的原因是相鄰的兩幀或多幀之間,映像內容的差異過大。在實際編程中,這個差異的來源主要有三個:
1,windows自身對程式視窗背景的擦除,導致兩幀之間插入空白幀。這個可以通過處理OnEraseBkgnd或者類似的
地方來解決。
2,程式自身清除背景。這個就是雙緩衝要取代的。
3,繪製過程表現。由於沒有使用雙緩衝,繪圖的整個過程會重現在螢幕上,這種過程的重現會引起閃爍。
雙緩衝技術的實質是:在後台緩衝繪製下一幀要顯示的圖形,繪製完成後切換到前台顯示。由於前台顯示的是上
一次繪製的結果,對於連續運動的映像來說,兩幀之間的差異很小,人感覺起來就是平滑的變化了。
這一技術的實現,請參考遊戲開發和影像處理的書籍和資料。
技巧二:資料與顯示分離。
這個技巧常見於影像處理程式,例如繪圖軟體等。
絕大多數初學者的第一個影像處理程式,把繪製好的映像儲存為檔案的過程,都是直接從DC中擷取資料,然後轉
為BMP或者其他格式的。
這種方式對於一個簡單的demo或者不做商業用途的小程式來說,是完全可以的。而一旦影像處理需要涉及一些複
雜的演算法,例如alpha融合,模糊,銳利化等,這種方式就無法滿足要求了。
正確的做法是:定義自己的映像資料格式(一般認為24bitBMP的格式就是很優秀的格式了,也能滿足多數情況的
需要),然後制定自訂格式到DC等裝置的映射規則。所有的資料運算都在自己的資料結構內部完成,而結果經
過映射後,顯示在給定的裝置上。
之所以不用DC,有四個主要原因:
1,DC是易變的。同一程式的不同部分,都擁有對DC的修改許可權,甚至其他程式也會修改你程式的DC資源。
2,DC的精度是受限的。對於一個特定的影像處理演算法,可能會引起資料的丟失或上溢,多次處理的結果會導致圖
像的色彩和形狀完全失真。為瞭解決這個問題,包括photoshop在內的許多影像處理軟體都提供了諸如48bit等高
精度圖形格式。
3,DC的尺寸是受限的。你可能想處理一個長寬都很大(例如,長寬都超過10k象素)的映像,但是DC的尺寸有它
自己的限制,有些情況無法滿足要求。
4,DC是裝置相關的,在不同的案頭解析度設定下的表現是不一致的。這個不用多說,256色/16位色/24位色/32位
色下,截取同一DC內容得到的結果可能是不同的。你總不能要求使用你軟體的使用者必須使用你用的案頭設定吧?
這一技巧更重要的用途是在向量圖的繪製,向量圖一般使用浮點類型的資料儲存圖形細節資訊,而以象素座標為
單位的螢幕DC對此無能為力。
技巧三:恰當的UNDO方式。
多數映像演算法是無法復原的,例如模糊,為了能夠undo每一步的操作,相當多的時候只能把處理前的圖片儲存一個
備份,undo的時候直接恢複。
事實上,由於使用者的操作可能非常複雜,那麼這種備份的數量極有可能超過磁碟剩餘空間。其實有個最佳化的方式
:
原理:使用者的操作雖然不能被有效undo,但是卻可以被重現。
使用:儲存原始的圖片,記錄每一步使用者操作的細節,當需要undo到某一步的時候,從原始圖片開始,依次重現
使用者的操作細節,直到需要的那個步驟。
這一技巧還可以通過在一些重現時間過長的複雜操作前後增加備份次數以改善效能。總的來說這是個時間換磁碟
空間的技巧,多數時候也能加快程式的響應速度(畢竟記憶體計算比讀取磁碟快不是一點半點鐘)。
技巧四:必要的時候,彙編。
影像處理多數是耗時運算,即使1024×1024的bmp,總資料量也超過3M,對於一個需要逐象素處理的演算法來說,這
種資料量會佔據大量的CPU時間。
為了改善這種狀況,除了改進演算法本身外,唯一的方法恐怕就是利用彙編了,可以通過MMX,SSE等特殊指令加快處
理速度,多數情況,經過彙編最佳化的演算法會比原始演算法快2~3倍。
但是,你也必須保留原始的演算法版本以支援不具備那些特有指令的CPU(例如Intel的CPU就不支援3DNow指令),並
驗證彙編的正確性。
技巧五:多線程和空閑時間利用。
為了在處理映像的同時,及時響應使用者的操作,多線程一般而言在所難免,除了多線程本身的複雜性,這裡需要
提醒:在只有單個CPU的機器上,多線程只會降低你的運行速度而不是加快,如果你的處理不是那麼耗時,或者用
戶介面響應不是那麼重要,請謹慎考慮為程式付出多線程的代價是否值得。
無論是遊戲,還是影像處理程式,總是或多或少有些空閑時間,例如使用者停止操作等等,程式可以選擇使用這段
時間來做一些幕後處理的工作,例如把緩衝中的資料寫入磁碟等。
技巧六:有計劃的記憶體管理。
影像處理程式耗盡系統可用記憶體,這並不是什麼新鮮事,再優秀的記憶體管理也不能處理記憶體需求超過供給的情況
。這裡有個致命問題,就是當使用者的某個操作需要分配大量記憶體,而系統此時又無法滿足的時候,你的程式可能
連儲存當前編輯狀態的記憶體都拿不出來了。
為了避免這種情況,記憶體使用量上要有一個有效預算和反饋機制,事先預測可能發生的狀況做好恢複準備,而不
是等到系統記憶體告急的時候手忙腳亂。
與此同時,一些熱門檔案和資料的緩衝是提高效率的途徑,也是記憶體缺乏時可以暫時釋放的資源。
技巧七:看懂以上的所有技巧,如果你不能,那麼你還沒有為你所涉足的這個領域做好最基本的準備。