[英]Chamfer distance between two point clouds in tensorflow
I am trying to implement chamfer distance in tensorflow.我正在尝试在张量流中实现倒角距离。
But, my code is taking input as numpy array.但是,我的代码将输入作为 numpy 数组。 To convert a numpy into a tensor, we need to run a session, but the process is already in another session.
要将 numpy 转换为张量,我们需要运行一个会话,但该进程已经在另一个会话中。 I think two sessions can't run in parallel.
我认为两个会话不能并行运行。
So, can anyone help me with the implementation of chamfer distance in tensorflow or help me with this problem of two simultaneous sessions?那么,任何人都可以帮助我在 tensorflow 中实现倒角距离或帮助我解决两个同时会话的问题吗?
my code is:我的代码是:
def chamfer_distance(array1,array2):
# final = 0
# final = tf.cast(final,tf.float32)
batch_size = array1.get_shape()[0].value
num_point = array1.get_shape()[1].value
sess = tf.Session()
arr1,arr2 = sess.run([array1,array2])
del sess
dist = 0
for i in range(batch_size):
tree1 = KDTree(arr1[i], leafsize=num_point+1)
tree2 = KDTree(arr2[i], leafsize=num_point+1)
distances1, _ = tree1.query(arr2[i])
distances2, _ = tree2.query(arr1[i])
distances1 = tf.convert_to_tensor(distances1)
distances2 = tf.convert_to_tensor(distances2)
av_dist1 = tf.reduce_mean(distances1)
av_dist2 = tf.reduce_mean(distances2)
dist = dist + (av_dist1+av_dist2)/batch_size
return dist
I've implemented TF version of chamfer distance:我已经实现了倒角距离的 TF 版本:
def distance_matrix(array1, array2):
"""
arguments:
array1: the array, size: (num_point, num_feature)
array2: the samples, size: (num_point, num_feature)
returns:
distances: each entry is the distance from a sample to array1
, it's size: (num_point, num_point)
"""
num_point, num_features = array1.shape
expanded_array1 = tf.tile(array1, (num_point, 1))
expanded_array2 = tf.reshape(
tf.tile(tf.expand_dims(array2, 1),
(1, num_point, 1)),
(-1, num_features))
distances = tf.norm(expanded_array1-expanded_array2, axis=1)
distances = tf.reshape(distances, (num_point, num_point))
return distances
def av_dist(array1, array2):
"""
arguments:
array1, array2: both size: (num_points, num_feature)
returns:
distances: size: (1,)
"""
distances = distance_matrix(array1, array2)
distances = tf.reduce_min(distances, axis=1)
distances = tf.reduce_mean(distances)
return distances
def av_dist_sum(arrays):
"""
arguments:
arrays: array1, array2
returns:
sum of av_dist(array1, array2) and av_dist(array2, array1)
"""
array1, array2 = arrays
av_dist1 = av_dist(array1, array2)
av_dist2 = av_dist(array2, array1)
return av_dist1+av_dist2
def chamfer_distance_tf(array1, array2):
batch_size, num_point, num_features = array1.shape
dist = tf.reduce_mean(
tf.map_fn(av_dist_sum, elems=(array1, array2), dtype=tf.float64)
)
return dist
And for validation purpose, I also implemented a sklearn version:为了验证目的,我还实现了一个 sklearn 版本:
def chamfer_distance_sklearn(array1,array2):
batch_size, num_point = array1.shape[:2]
dist = 0
for i in range(batch_size):
tree1 = KDTree(array1[i], leaf_size=num_point+1)
tree2 = KDTree(array2[i], leaf_size=num_point+1)
distances1, _ = tree1.query(array2[i])
distances2, _ = tree2.query(array1[i])
av_dist1 = np.mean(distances1)
av_dist2 = np.mean(distances2)
dist = dist + (av_dist1+av_dist2)/batch_size
return dist
Also a numpy version:还有一个 numpy 版本:
def array2samples_distance(array1, array2):
"""
arguments:
array1: the array, size: (num_point, num_feature)
array2: the samples, size: (num_point, num_feature)
returns:
distances: each entry is the distance from a sample to array1
"""
num_point, num_features = array1.shape
expanded_array1 = np.tile(array1, (num_point, 1))
expanded_array2 = np.reshape(
np.tile(np.expand_dims(array2, 1),
(1, num_point, 1)),
(-1, num_features))
distances = LA.norm(expanded_array1-expanded_array2, axis=1)
distances = np.reshape(distances, (num_point, num_point))
distances = np.min(distances, axis=1)
distances = np.mean(distances)
return distances
def chamfer_distance_numpy(array1, array2):
batch_size, num_point, num_features = array1.shape
dist = 0
for i in range(batch_size):
av_dist1 = array2samples_distance(array1[i], array2[i])
av_dist2 = array2samples_distance(array2[i], array1[i])
dist = dist + (av_dist1+av_dist2)/batch_size
return dist
You can validate the result using following script:您可以使用以下脚本验证结果:
batch_size = 8
num_point = 20
num_features = 4
np.random.seed(1)
array1 = np.random.randint(0, high=4, size=(batch_size, num_point, num_features))
array2 = np.random.randint(0, high=4, size=(batch_size, num_point, num_features))
print('sklearn: ', chamfer_distance_sklearn(array1, array2))
print('numpy: ', chamfer_distance_numpy(array1, array2))
array1_tf = tf.constant(array1, dtype=tf.float64)
array2_tf = tf.constant(array2, dtype=tf.float64)
dist_tf = chamfer_distance_tf(array1_tf, array2_tf)
with tf.Session() as sess:
print('tf: ', sess.run(dist_tf))
It's really helpful. 真的很有帮助。 Thanks :)
谢谢 :)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.