圖像處理的算法復(fù)雜度通常都比較高,計算也相應(yīng)比較耗時。利用CPU多線程處理能力可以大幅度加快計算速度。但是,為了保證多線程處理的結(jié)果和單線程處理的結(jié)果完全相同,圖像的多線程計算有一些需要特別考慮的地方。
基本思路:
為了能讓多個線程同時并行處理,那么各自處理的數(shù)據(jù)不能有交集,這很好理解。那么基本思路是將一副圖像分成多個子塊,每個子塊數(shù)據(jù)肯定是沒有交集的,每個線程對一個子塊數(shù)據(jù)進(jìn)行處理,完成后將所有子塊處理結(jié)果合成最終圖像。
首先,每個子塊的大小當(dāng)然是必須考慮的問題。通常當(dāng)應(yīng)用進(jìn)行一個較長時間的操作,應(yīng)該用合適的方式告知用戶。既然我們把圖像分子塊處理,如果單個子塊處理時間很短,那么每當(dāng)有一個子塊的數(shù)據(jù)處理完成,我們就可以立即把它相應(yīng)的處理結(jié)果展示給用戶。用戶就會看到這個圖像各個部分的處理結(jié)果不斷展示出來,直至整個圖像完成。這樣某種程度上用這種方式就是在告知用戶正在處理進(jìn)行中,避免為了把整個圖像處理完成,用戶需要等待太長時間。從這個角度來說,如果子塊尺寸取的太大,每個子塊計算時間肯定相應(yīng)地加長,對于快速顯示部分處理結(jié)果給用戶是不利的。但是如果子塊太小,子塊總數(shù)就會增加,肯定會增加線程開銷和其他一些開銷(分割圖像,分配子塊數(shù)據(jù)等等),對于總的計算時間是不利的。這是一個權(quán)衡問題,可以根據(jù)具體情況確定。
另外,很多圖像處理都要考慮像素領(lǐng)域范圍的信息,因此對于每個子塊的處理不能僅僅使用這個子塊的內(nèi)容。具體地,對于靠近子塊邊緣的像素,還要把子塊外的部分像素信息考慮進(jìn)來,加入計算,才能保證相應(yīng)像素的處理結(jié)果是正確的。準(zhǔn)確來說,如果領(lǐng)域半徑為r(對方形或圓形領(lǐng)域來說,其他領(lǐng)域可做相應(yīng)調(diào)整),那么子塊處理所需要的所有數(shù)據(jù)是子塊四周向外擴(kuò)展r像素的范圍。
代碼中extend就是子塊要向四周擴(kuò)張的大小,其實就是領(lǐng)域半徑r。pRect[i]是分割的第i個子塊的大小。Height和Width是原圖的高寬,擴(kuò)展子塊自然不能超過原圖的尺寸。那么最后rect1就是計算所需要的數(shù)據(jù)在原圖中所在的領(lǐng)域范圍,應(yīng)用原圖的尺寸對它進(jìn)行了限制。由于我是把每個子塊當(dāng)成一個新的圖像進(jìn)行處理,rect2就是新圖像中子塊處理結(jié)果所在的位置,用它來合成最終圖像。
最后關(guān)于線程具體創(chuàng)建銷毀,資源分配與回收,線程同步和通信,不做具體討論。只討論一下在這里多線程如何協(xié)調(diào)工作的問題。由于計算子塊的線程只負(fù)責(zé)處理子塊,還需要有人來做分割子塊,分配數(shù)據(jù)給子塊計算線程等等工作。本來應(yīng)該畫流程圖的,實在懶得畫了,這里簡單描述一下幾個線程如何協(xié)調(diào)工作的,其實也很簡單。界面線程A,處理和用戶之間的交互,接受用戶命令,發(fā)送計算消息給線程B。計算協(xié)調(diào)線程B接受A的消息,分割子塊,分配子塊數(shù)據(jù),創(chuàng)建子塊計算線程Ci。子塊計算線程Ci負(fù)責(zé)子塊計算,發(fā)送處理結(jié)果(成功或失敗)消息給線程B或者A。界面線程A收到子塊完成消息,可以立即顯示子塊處理結(jié)果,當(dāng)然也可以什么都不做,等到所有子塊處理完再顯示。協(xié)調(diào)線程B收到第i個子塊完成消息,回收分配給線程Ci的資源,銷毀Ci。如果所有的Ci完成了工作,B發(fā)送圖像處理完成的消息給A,A可以接著做后續(xù)的工作。這里單獨用了一個線程B來做子塊計算協(xié)調(diào)的工作,感覺這樣比較清晰一些。當(dāng)然也可以讓界面線程A來做這個工作,協(xié)調(diào)的工作量也不是很大,這樣就可以不需要B線程。
單線程和多線程處理時間對比
多線程處理速度肯定不能簡單地是單線程處理速度的N倍,這只是理想狀況。由于很多額外工作(線程開銷,準(zhǔn)備每個線程的數(shù)據(jù),處理結(jié)果的合成,線程間同步,圖像子塊結(jié)合部的部分重復(fù)計算),多線程是不可能達(dá)到理想狀況的。下表列出了一副2400x1350大小的24bit圖像分成了12個子塊,分別在一臺I5 4300U(雙核四線程)筆記本上和一臺I5 6500(四核四線程)臺式機(jī)上,處理高斯模糊的大概的平均耗時。高斯模糊算法是簡單的行列方向兩次一維計算,半徑取50。在我的測試中,還實時顯示了分塊的處理結(jié)果,速度上可能要更慢一點。
理想狀況下四線程耗時最多能減少75%,實際上肯定達(dá)不到。在雙核四線程平臺上,對亮度通道處理,多線程比單線程耗時減少了一半(50%)。對RGB通道,多線程比單線程耗時減少了大概59%。在四核四線程平臺上,多線程耗時在亮度通道和RGB通道處理時,分別減少了64%和69%。可以看到,多線程處理的加速效果還是相當(dāng)明顯的。話說牙膏廠超線程的效果還是挺驚人的,不然在雙核CPU上耗時減少是不可能超過50%的。當(dāng)然物理內(nèi)核的數(shù)量就更重要了。
而且還可以看到一個現(xiàn)象,在單線程處理下,RGB三通道的處理耗時是亮度通道處理耗時3倍略少,約為2.8倍(亮度通道還包括一些在RGB和亮度之間轉(zhuǎn)換的額外計算量)。而在多線程下,RGB三通道的處理時間大大小于亮度一個通道處理時間的3倍,約為2.38倍。相對于單線程,節(jié)省的時間更多了。這是因為RGB的處理也是在子塊的一個線程中處理的,并沒有增加新的線程開銷。因此線程開銷也是必須考慮的一個因素,不可忽略。
-
圖像處理
+關(guān)注
關(guān)注
27文章
1292瀏覽量
56764 -
多線程
+關(guān)注
關(guān)注
0文章
278瀏覽量
19981
原文標(biāo)題:圖像處理的多線程計算
文章出處:【微信號:Imgtec,微信公眾號:Imagination Tech】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論