2011-07-05 50 views
2

我目前使用此代碼來計算索貝爾梯度的大小:索貝爾梯度幅度的高效計算

sobel_x = cv.CreateImage(cv.GetSize(im), cv.IPL_DEPTH_16S, 1) 
sobel_y = cv.CreateImage(cv.GetSize(im), cv.IPL_DEPTH_16S, 1) 
cv.Sobel(im, sobel_x, 1, 0, 3) 
cv.Sobel(im, sobel_y, 0, 1, 3) 

width, height = cv.GetSize(im) 
for i in range(width*height): 
    x, _, _, _ = cv.Get1D(sobel_x, i) 
    y, _, _, _ = cv.Get1D(sobel_y, i) 
    px = int(math.sqrt(x*x + y*y)) 
    cv.Set1D(sobel, i, px) 

這是很簡單的,但它不是非常有效,因爲我訪問每一個像素一個一個。我希望有一個更好的方式來做到這一點OpenCV:

sobel_x2 = cv.CreateImage(cv.GetSize(im), cv.IPL_DEPTH_32S, 1) 
sobel_y2 = cv.CreateImage(cv.GetSize(im), cv.IPL_DEPTH_32S, 1) 
sobel_2 = cv.CreateImage(cv.GetSize(im), cv.IPL_DEPTH_32S, 1) 
cv.Mul(sobel_x, sobel_x, sobel_x2) 
cv.Mul(sobel_y, sobel_y, sobel_y2) 
cv.Add(sobel_x2, sobel_y2, sobel_2) 

在這裏,我只是平方米圖像,並添加它們。它使用更多的內存,但應該更快,因爲現在一些操作將並行完成。我堅持的是沒有基於元素的平方根函數(cv.Sqrt似乎只適用於標量)。

任何想法?

回答

3

正如您已經注意到的,cv.Sqrt()只接受Python綁定中的標量。由於有一個等效的函數,它執行一個元素方根,它也應該在主要是自動生成的Python綁定中。也許這是您正在使用的OpenCV版本中的一個錯誤。

無論如何,你應該能夠使用cv.Pow()得到相同的結果:

cv.Pow(src, dst, 0.5) 

這可能是不一樣快cv.Sqrt()會是這樣,但還是應該大大優於逐元素計算。

+1

Python綁定包裝C接口,而不是C++接口。所以'cv.sqrt'是'cvSqrt'(不是'cv :: sqrt')的封裝,它是一個接受標量的函數。不過,我會用'cv.Pow'。謝謝您的回答! – misha

+0

好的。看起來C/Python和C++ API之間的這種差異正在使用OpenCV 2.3中的[cv.Sqrt()修復](http://opencv.itseez.com/modules/core/doc/operations_on_arrays.html?highlight=開方#開方)。另外,如果它解決了您的問題,請接受我的答案。 –