2
我建立了這個哈里斯角探測器,其功能完全符合預期,但是當涉及到性能時,它非常緩慢。我幾乎可以肯定,這與我訪問圖像的每個像素的事實有關,但也可能是我實施了錯誤的事情。我一直在考慮如何優化用於應用濾波器的np數組訪問權限,但由於這些濾波器的特性,我仍然無法想出一個好主意。 該方法本身並不慢,因爲OpenCV對於相同的圖像基本上是即時的。提高哈里斯角探測器的效率
import numpy as np
import cv2 as cv
import matplotlib.pyplot as pl
import matplotlib.cm as cm
import math
def hor_edge_strength(x, y, img_in = [], filter = []):
strength = 0
for i in range (0,3):
for j in range (0,3):
strength += img_in[x+i-1][y+j-1] * filter[i][j]
return strength
def ver_edge_strength(x, y, img_in = [], filter = []):
strength = 0
for i in range (0,3):
for j in range (0,3):
strength += img_in[x+i-1][y+j-1] * filter[i][j]
return strength
def gauss_kernels(size,sigma=1):
## returns a 2d gaussian kernel
if size<3:
size = 3
m = size/2
x, y = np.mgrid[-m:m+1, -m:m+1]
kernel = np.exp(-(x*x + y*y)/(2*sigma*sigma))
kernel_sum = kernel.sum()
if not sum==0:
kernel = kernel/kernel_sum
return kernel
sobel_h = [[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]]
sobel_v = [[1, 2, 1], [0, 0, 0], [-1, -2, -1]]
img_arr = ['checker.jpg'] #Test image
for img_name in img_arr:
img = cv.imread(img_name,0)
sep = '.'
img_name = img_name.split(sep, 1)[0]
print img_name
gray_img = img.astype(float)
gx = np.zeros_like(gray_img)
gy = np.zeros_like(gray_img)
print 'Getting strengths'
for i in range(1, len(gray_img) - 1):
for j in range(1, len(gray_img[0]) - 1):
gx[i][j] = hor_edge_strength(i, j, gray_img, sobel_h)
gy[i][j] = ver_edge_strength(i, j, gray_img, sobel_v)
I_xx = gx * gx
I_xy = gx * gy
I_yy = gy * gy
gaussKernel = gauss_kernels(3,1)
W_xx = np.zeros_like(gray_img)
W_xy = np.zeros_like(gray_img)
W_yy = np.zeros_like(gray_img)
print 'Convoluting'
for i in range(1, len(gray_img) - 1):
for j in range(1, len(gray_img[0]) - 1):
W_xx[i][j] = hor_edge_strength(i, j, I_xx, gaussKernel)
W_xy[i][j] = hor_edge_strength(i, j, I_xy, gaussKernel)
W_yy[i][j] = hor_edge_strength(i, j, I_yy, gaussKernel)
print 'Calculating Harris Corner'
k = 0.06
HCResponse = np.zeros_like(gray_img)
for i in range(1, len(gray_img) - 1):
for j in range(1, len(gray_img[0]) - 1):
W = np.matrix([[W_xx[i][j],W_xy[i][j]],[W_xy[i][j],W_yy[i][j]]]) #For lap purposes, but not needed
detW = W_xx[i][j]*W_yy[i][j] - (W_xy[i][j] * W_xy[i][j])
traceW = W_xx[i][j] + W_yy[i][j]
HCResponse[i][j] = detW - k*traceW*traceW
threshold = 0.1
imageTreshold = max(HCResponse.ravel()) * threshold
HCResponseTreshold = (HCResponse >= imageTreshold) * 1
candidates = np.transpose(HCResponseTreshold.nonzero())
print 'Drawing'
x, y = gray_img.shape
image = np.empty((x, y, 3), dtype=np.uint8)
image[:, :, 0] = gray_img
image[:, :, 1] = gray_img
image[:, :, 2] = gray_img
for i in candidates:
x,y = i.ravel()
image[x][y] = [255,0,0]
pl.imshow(image)
pl.show()
pl.savefig(img_name + '_edge.jpg')
是否有任何可能的解決方案來顯着改善此邊緣檢測器的性能?
看看[OpenCV的文檔(http://docs.opencv.org/master/dc/d0d/tutorial_py_features_harris.html#gsc.tab=0 ) – sturkmen