2017-10-03 2 views
1

Tensorflow를 사용하여 Canny 알고리즘을 구현합니다 (이것은 경계를 평가 척도로 사용하는 데 필요하지만 주제는 아닙니다). 하나의 단계는 "최대가 아닌 억제 (Non-maximum Suppression)"를 계산하는 것인데, 이는 특정 이웃이 더 작지 않은 한 3x3 영역에서 중심 요소를 제로화하는 것입니다. 더 자세한 내용 here.인접 요소와 관련된 텐서의 조건 값

Tensorflow를 사용하여이 작업을 수행하려면 어떻게해야합니까?

내가 실제로 Keras를 사용하고 있지만, Tensorflow 솔루션은 참조를 위해 잘 작동합니다, 내 코드는 지금까지 다음과 같습니다

def canny(img): 
    '''Canny border detection. The input should be a grayscale image.''' 
    gauss_kernel = np.array([[2, 4, 5, 4, 2], 
          [4, 9, 12, 9, 4], 
          [5, 12, 15, 12, 5], 
          [4, 9, 12, 9, 4], 
          [2, 4, 5, 4, 2]]).reshape(5, 5, 1, 1) 
    gauss_kernel = K.variable(1./159 * gauss_kernel) 

    Gx = K.variable(np.array([[-1., 0. ,1.], 
           [-2., 0., 2.], 
           [-1., 0., 1.]]).reshape(3, 3, 1, 1)) 

    Gy = K.variable(np.array([[-1., -2., -1.], 
           [ 0., 0., 0.], 
           [ 1., 2., 1.]]).reshape(3, 3, 1, 1)) 
    # Smooth image 
    smoothed = K.conv2d(img, gauss_kernel, padding='same') 
    # Derivative in x 
    Dx = K.conv2d(smoothed, Gx, padding='same') 
    # Derivative in y 
    Dy = K.conv2d(smoothed, Gy, padding='same') 
    # Take gradient strength 
    G = K.sqrt(K.square(Dx) + K.square(Dy)) 

    # TODO: Non-maximum Suppression & Hysteresis Thresholding 

    return G 

답변

1

당신은이 개 목표 픽셀을 분리하고 만드는 길쌈 필터를 사용할 수 있습니다 그것들은 중앙 픽셀과 "동심"이다.

예를 들어 두 개의 대상 픽셀과 비교할 때이 필터는 (3, 3, 1, 2) - 1 개의 입력 채널, 2 개의 출력 채널로 구성 할 수 있습니다. 각 채널은 대상 픽셀 중 하나를 반환합니다.

필터의 대상 픽셀에 1이 있어야합니다. 나머지는 0입니다.

#taking two diagonal pixels 
filter = np.zeros((3,3,1,2)) 
filter[0,0,0,0] = 1 #first pixel is top/left, passed to the first channel 
filter[2,2,0,1] = 1 #second pixel is bottom/right, passed to the second channel  
    #which ones are really bottom or top, left or right depend on your preprocessing, 
    #but they should be consistent with the rest of your modeling 

filter = K.variable(filter) 

위쪽 및 아래쪽 또는 왼쪽 및 오른쪽으로 가져 가면 더 작은 필터를 만들 수 있습니다.

filter1 = np.zeros((1,3,1,2)) #horizontal filter 
filter2 = np.zeros((3,1,1,2)) #vertical filter 

filter1[0,0,0,0] = 1 #left pixel - if filter is 3x3: [1,0,0,0] 
filter1[0,2,0,1] = 1 #right pixel - if filter is 3x3: [1,2,0,1] 
filter1 = K.variable(filter1) 

filter2[0,0,0,0] = 1 #top pixel - if filter is 3x3: [0,1,0,0] 
filter2[2,0,0,1] = 1 #bottom pxl - if filter is 3x3: [2,1,0,1] 
filter2 = K.variable(filter2) 

는 그런 다음 회선으로 다음을 적용 필요가 3 × 3 (아무 문제 중 하나) 만 × 3 또는 3 × 수 없습니다. 한 픽셀에 대해 하나의 채널을 가져오고 다른 픽셀에 대해서는 다른 채널을 가져옵니다. 그런 다음 서로 다른 채널에있는 것처럼 동일한 장소에있는 것처럼 모두 비교할 수 있습니다.

targetPixels = K.conv2d(originalImages, kernel=filter, padding='same') 

#two channels telling if the center pixel is greater than the pixel in the channel 
isGreater = K.greater(originalImages,targetPixels) 

#merging the two channels, considering they're 0 for false and 1 for true 
isGreater = K.cast(isGreater,K.floatx()) 
isGreater = isGreater[:,:,:,:1] * isGreater[:,:,:,1:] 

#now, the center pixel will remain if isGreater = 1 at that position: 
result = originalImages * isGreater 
+0

다른 접근 방식으로 시도했지만이 아이디어는 완벽했습니다. 고맙습니다! –