#!/usr/bin/env python # Using netvlad tensorflow-v1 implementation from https://github.com/uzh-rpg/netvlad_tf_open/ # For ROS melodic, follow the following instructions to rebuild cv_bridge with Python3 # https://medium.com/@beta_b0t/how-to-setup-ros-with-python-3-44a69ca36674 # On Jetpack 4.4 (18.04 and OpenCV4), use vision_opencv's noetic branch. In cv_bridge/CMakeLists.txt, # apply this patch: # -find_package(Boost REQUIRED python37) # +find_package(Boost REQUIRED python3) from __future__ import print_function import roslib import sys import rospy import cv2 import numpy as np import tensorflow as tf import time import netvlad_tf.net_from_mat as nfm import netvlad_tf.nets as nets from std_msgs.msg import String from sensor_msgs.msg import Image from cv_bridge import CvBridge, CvBridgeError from rtabmap_ros import compression as cp from rtabmap_ros.msg import GlobalDescriptor class netvlad_ros: def __init__(self): self.dim = rospy.get_param('~dim', 4096) self.scale = rospy.get_param('~scale', 1.0) rospy.loginfo("Parameter dim=%d", self.dim) rospy.loginfo("Parameter scale=%d", self.scale) tf.reset_default_graph() self.image_batch = tf.placeholder( dtype=tf.float32, shape=[None, None, None, 3]) self.net_out = nets.vgg16NetvladPca(self.image_batch) self.saver = tf.train.Saver() self.sess = tf.Session() self.saver.restore(self.sess, nets.defaultCheckpoint()) self.pub = rospy.Publisher('netvlad_descriptor', GlobalDescriptor, queue_size=1) self.bridge = CvBridge() self.image_sub = rospy.Subscriber("image",Image,self.callback, queue_size=1) def callback(self,data): start = time.time() try: cv_image = self.bridge.imgmsg_to_cv2(data, "rgb8") except CvBridgeError as e: print(e) if self.scale != 1.0: width = int(cv_image.shape[1] * self.scale) height = int(cv_image.shape[0] * self.scale) cv_image = cv2.resize(cv_image, (width, height), interpolation = cv2.INTER_AREA) batch = np.expand_dims(cv_image, axis=0) result = self.sess.run(self.net_out, feed_dict={self.image_batch: batch}) result = result[:,:self.dim] descriptor = GlobalDescriptor() descriptor.type = 0 descriptor.header = data.header descriptor.data = cp.compress(result) self.pub.publish(descriptor) end = time.time() rospy.loginfo("Extracting descriptor (img=%dx%d, dim=%d): %fs", cv_image.shape[1], cv_image.shape[0], self.dim, end-start) def main(args): rospy.init_node('netvlad', anonymous=True) n = netvlad_ros() try: rospy.spin() except KeyboardInterrupt: print("Shutting down") if __name__ == '__main__': main(sys.argv)