张量相对于元素邻居的条件值
Conditional value on tensor relative to element neighbors
我正在使用 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
您可以使用卷积滤波器来分离两个目标像素并使它们 "concentric" 与中心像素。
例如,为了与两个目标像素进行比较,我们可以使用此过滤器,其形状为 (3, 3, 1, 2)
-- 一个输入通道,两个输出通道。每个通道将return一个目标像素。
过滤器应该在目标像素处有 1 个。其余为零:
#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)
如果您选择顶部和底部,或左侧和右侧,您可以制作更小的过滤器。不必是 3x3(也没问题),但只需 1x3 或 3x1:
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)
然后将它们应用为卷积。您将获得一个像素的一个通道,另一个像素的另一个通道。然后你可以比较它们,就好像它们都在同一个地方,只是在不同的频道:
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
我正在使用 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
您可以使用卷积滤波器来分离两个目标像素并使它们 "concentric" 与中心像素。
例如,为了与两个目标像素进行比较,我们可以使用此过滤器,其形状为 (3, 3, 1, 2)
-- 一个输入通道,两个输出通道。每个通道将return一个目标像素。
过滤器应该在目标像素处有 1 个。其余为零:
#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)
如果您选择顶部和底部,或左侧和右侧,您可以制作更小的过滤器。不必是 3x3(也没问题),但只需 1x3 或 3x1:
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)
然后将它们应用为卷积。您将获得一个像素的一个通道,另一个像素的另一个通道。然后你可以比较它们,就好像它们都在同一个地方,只是在不同的频道:
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