2012-01-10 67 views
3

在Python + Python圖像庫腳本中,有一個稱爲processPixel(image,pos)的函數,該函數根據圖像和位置計算數學指數。使用簡單的for循環爲每個像素計算此索引:使用多線程在python上更快地處理圖像?

for x in range(image.size[0)): 
    for y in range(image.size[1)): 
     myIndex[x,y] = processPixel(image,[x,y]) 

這花費了太多時間。如何執行線程來分割加速它的工作?多線程代碼可以多快?特別是,這是由處理器內核的數量來定義的嗎?

+0

另外,我很願意打賭'processPixel'可能是「numpy的-指明分數」,在這種情況下,你會看到在你目前所採用的巨大加速。 – 2012-01-11 15:23:16

回答

6

由於Global Interpreter Lock,您無法使用螺紋加速。 Python解釋器的某些內部狀態受該鎖的保護,這可防止需要修改該狀態的不同線程同時運行。

可能通過使用multiprocessing產卵實際進程加速它。每個進程都會在自己的解釋器中運行,從而繞過線程的限制。通過多處理,您可以使用共享內存,也可以爲每個進程分配自己的數據副本/分區。

根據您的任務,您可以通過對單個圖像進行分區來並行處理,也可以並行處理圖像列表(後者很容易使用pool完成)。如果您想使用前者,您可能需要將圖像存儲在可作爲共享內存訪問的Array中,但仍需解決寫入結果的問題(寫入共享內存會損害性能嚴重)。還要注意,進程之間的特定通信類型(隊列,管道或模塊中某些函數的參數/返回值傳遞)需要使用Pickle對數據進行序列化。這對數據施加了一定的限制,並可能造成顯着的性能開銷(特別是如果您有許多小任務)。

爲提高此類操作的性能的另一種方法是嘗試在Cython寫他們,它有自己的support for parallelization使用OpenMP - 我從來沒有使用過,雖然,所以我不知道多少的幫助可以。

+0

如果您需要處理圖像(或你這樣做需要大量計算能力的任何操作),那麼你也應該看看GPU。 Python肯定支持它。 – freakish 2012-01-10 12:08:29

+0

由於@freakish建議,你應該使用[基於GPU(http://stackoverflow.com/a/8821745/462302)解決方案,爲這類問題。你所說的GIL和多處理是正確的,但對圖像處理仍然沒有幫助。而且,當涉及到陣列處理I [推薦使用NumPy的](http://stackoverflow.com/a/8821745/462302),因爲它被設計用於有效的陣列處理。 – aculich 2012-01-11 15:26:41

0

關於多處理,請看Doug Hellmans tutorial。正如Björn所指出的那樣,在並行處理方面存在着各種各樣的問題,您需要花費一些時間,但這確實值得付出努力。

提示:您可以使用multiprocessing.cpu_count()來檢查可用的核心數量。

1

這裏有圖書館,你會想探索做高效影像處理的列表:

OpenCV - 是的編程功能的實時計算機視覺和包含Python綁定圖像處理庫。

PyOpenCL允許您從Python訪問GPU和其他大規模並行計算設備。

PyCUDA是姊妹項目PyOpenCL

NumPy and SciPy是這樣做的科學計算,其可以是具有這樣做有效的圖像和陣列處理上述程序包有幫助基本包。

還要注意的是做圖像處理多道庫,有些人認爲是不會幫助你有效地處理圖像處理,所以你應該避免使用操作系統線程來做到這一點。如果由於某種原因,你需要做的粗粒度並行,那麼你可以使用python library for MPI,但你可能想堅持GPU-based libraries