2015-11-09 57 views
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') 

是否有任何可能的解決方案來顯着改善此邊緣檢測器的性能?

+0

看看[OpenCV的文檔(http://docs.opencv.org/master/dc/d0d/tutorial_py_features_harris.html#gsc.tab=0 ) – sturkmen

回答

0
import cv2 
import numpy as np 

filename = 'chess1.jpg' 
img = cv2.imread(filename) 
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) 

gray = np.float32(gray) 
dst = cv2.cornerHarris(gray,2,3,0.04) 

#result is dilated for marking the corners, not important 
dst = cv2.dilate(dst,None) 

# Threshold for an optimal value, it may vary depending on the image. 
img[dst>0.01*dst.max()]=[0,0,255] 

cv2.imshow('dst',img) 
if cv2.waitKey(0) & 0xff == 27: 
    cv2.destroyAllWindows() 

更多信息請參閱本link