[問題] python 速度 FOR_LOOP

看板Python作者 (R大)時間11年前 (2014/08/05 00:27), 編輯推噓14(14013)
留言27則, 8人參與, 最新討論串1/1
目前剛接觸python 以python撰寫了一段Sobel影像處理,程式碼如下 =================================================== import cv2 import numpy as np img=cv2.imread("/home/chenposhao/Desktop/IMAGE/cameraman.tif",0) [row,col]=img.shape resx=np.zeros((row,col),np.uint8) kernalx=np.array([[1,2,1],[0,0,0],[-1,-2,-1]]) kernaly=np.array([[1,0,-1],[2,0,-2],[1,0,-1]]) for x in range(row): for y in range(col): if x==0 or x==row-1 or y==0 or y==col-1: pass else: subxsum=0 subysum=0 for i in range(-1,2): for j in range(-1,2): newx=img[x+i,y+j]*kernalx[i+1,j+1] subxsum=subxsum+newx newy=img[x+i,y+j]*kernaly[i+1,j+1] subysum=subysum+newy respixel=abs(subxsum+subysum/2) if respixel>255: respixel=255 elif respixel<0: respixel=0 resx[x,y]=respixel cv2.imshow("IMAGE",img) cv2.imshow("SOBELX",resx) cv2.waitKey(0) cv2.destroyAllWindows() ================================================================ 首先要先說,跑的圖片是256*256 我知道CV有SOBEL函式庫可以用, 但因為用他的函式庫發現他並沒有將所計算的像素取絕對值 因此有方向性的問題,為了驗證才寫此程式碼 但發現這個程式碼再執行的時候不如預期的快 從中間的for x in range(row): 到 resx[x,y]=respixel 整個FORLOOP跑完要5.5秒左右 VB,C幾毫秒即可跑完 想問一下這是python所必須要克服的事情嘛? 因為剛接觸Python,早有相傳他因為直譯所以速度慢 但想不到落差有些許的大 還是說其實這是能改善的? 謝謝 -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 140.120.101.45 ※ 文章網址: http://www.ptt.cc/bbs/Python/M.1407169658.A.D84.html

08/05 01:00, , 1F
直譯擅長的不在效率呀,有改進方法但要追上很難~
08/05 01:00, 1F

08/05 01:10, , 2F
你不應該一個元素一個元素自己乘,這樣會慢很多
08/05 01:10, 2F

08/05 01:14, , 3F
多用 numpy array級操作才會快,python for-loop 會太慢
08/05 01:14, 3F

08/05 01:14, , 4F
另外,我找到 scipy.ndimage.filters.sobel 可以呼叫
08/05 01:14, 4F

08/05 01:15, , 5F
點旁邊的 source 就可以知道它 code 怎麼寫的
08/05 01:15, 5F

08/05 08:37, , 6F
不知道range改xrange會不會比較快
08/05 08:37, 6F

08/05 09:36, , 7F
想更詳細的問一下何謂 numpy array級操作
08/05 09:36, 7F

08/05 10:24, , 8F
比如 i j 迴圈改成 np.sum(img * (kernalx + kernaly))
08/05 10:24, 8F

08/05 10:30, , 9F
選部份矩陣應該用 img[x:x+3, y:y+3] 這型式的取值
08/05 10:30, 9F

08/05 10:31, , 10F
大原則避免自己寫 for 或複雜運算,numpy 本身是 C 速度
08/05 10:31, 10F

08/05 10:32, , 11F
看 scipy 寫法,它只用了 correlate1d 這函式就實作完了
08/05 10:32, 11F

08/05 10:33, , 12F
我不懂 sobel 沒法給建議,不夠快的話也可考慮 Cython
08/05 10:33, 12F

08/06 20:27, , 13F
它會編譯成 bytecode 來跑呀,只是 CPython 挺慢是事實
08/06 20:27, 13F

08/06 20:28, , 14F
現階段 CPython 也沒有像 Java 或 .NET 有做 JIT 優化
08/06 20:28, 14F

08/06 20:29, , 15F
迴圈自然就是不會快去哪邊,做 Convolution 用 GPU 最快
08/06 20:29, 15F

08/06 20:33, , 16F
退而求其次就是用 numpy.convolve + numpy.absolute
08/06 20:33, 16F

08/06 20:35, , 17F
NumbaPro 聽說挺不錯的,可以用到 GPU 來加速...
08/06 20:35, 17F

08/06 22:19, , 18F
另外,Sobel filter 是 separable filter 我想你知道 :D
08/06 22:19, 18F

08/06 22:20, , 19F
儘管從 2D kernel 改 1D kernel 對於 Python 也沒快很多
08/06 22:20, 19F

08/06 22:48, , 20F
這個 http://goo.gl/CrQiXl 可以跑跑看,也許有幫助 :P
08/06 22:48, 20F

08/08 06:36, , 21F
Numba
08/08 06:36, 21F

08/08 09:28, , 22F
社群版的 Numba 效果應該也不錯吧,NumbaPro 得花錢就是
08/08 09:28, 22F

08/11 11:10, , 23F
跟matlab道理差不多啊 多用 vectorization
08/11 11:10, 23F

08/13 16:31, , 24F
感謝大家的發問,我持續摸索,大家對我幫助很大,謝謝
08/13 16:31, 24F

08/14 16:45, , 25F
similar question in stackoverflow http://ppt.cc/pSIw
08/14 16:45, 25F

08/14 16:56, , 26F
離題一下 希望 numpy on pypy 早日實現
08/14 16:56, 26F

08/14 16:56, , 27F
文章代碼(AID): #1JtxHws4 (Python)
文章代碼(AID): #1JtxHws4 (Python)