0

Rosanswers logo

Hello.

I am trying to create a node for image classification using ROS and Tensorflow.

If I run this script with python, everything works perfectly with some differents networks:

import pyrealsense2 as rs
import numpy as np
import cv2
import tensorflow as tf

Configure depth and color streams

pipeline = rs.pipeline() config = rs.config() config.enable_stream(rs.stream.color, 640, 480, rs.format.bgr8, 30)

print("[INFO] Starting streaming...") pipeline.start(config) print("[INFO] Camera ready.")

download model from: https://github.com/opencv/opencv/wiki/TensorFlow-Object-Detection-API#run-network-in-opencv

print("[INFO] Loading model...") PATH_TO_CKPT = "frozen_inference_graph.pb"

Load the Tensorflow model into memory.

detection_graph = tf.Graph() with detection_graph.as_default(): od_graph_def = tf.compat.v1.GraphDef() with tf.compat.v1.gfile.GFile(PATH_TO_CKPT, 'rb') as fid: serialized_graph = fid.read() od_graph_def.ParseFromString(serialized_graph) tf.compat.v1.import_graph_def(od_graph_def, name='') sess = tf.compat.v1.Session(graph=detection_graph)

Input tensor is the image

image_tensor = detection_graph.get_tensor_by_name('image_tensor:0')

Output tensors are the detection boxes, scores, and classes

Each box represents a part of the image where a particular object was detected

detection_boxes = detection_graph.get_tensor_by_name('detection_boxes:0')

Each score represents level of confidence for each of the objects.

The score is shown on the result image, together with the class label.

detection_scores = detection_graph.get_tensor_by_name('detection_scores:0') detection_classes = detection_graph.get_tensor_by_name('detection_classes:0')

Number of objects detected

num_detections = detection_graph.get_tensor_by_name('num_detections:0')

code source of tensorflow model loading: https://www.geeksforgeeks.org/ml-training-image-classifier-using-tensorflow-object-detection-api/

print("[INFO] Model loaded.") colors_hash = {} while True: frames = pipeline.wait_for_frames() color_frame = frames.get_color_frame()

# Convert images to numpy arrays
color_image = np.asanyarray(color_frame.get_data())
scaled_size = (color_frame.width, color_frame.height)
# expand image dimensions to have shape: [1, None, None, 3]
# i.e. a single-column array, where each item in the column has the pixel RGB value
image_expanded = np.expand_dims(color_image, axis=0)
# Perform the actual detection by running the model with the image as input
(boxes, scores, classes, num) = sess.run([detection_boxes, detection_scores, detection_classes, num_detections],
                                            feed_dict={image_tensor: image_expanded})

boxes = np.squeeze(boxes)
classes = np.squeeze(classes).astype(np.int32)
scores = np.squeeze(scores)

for idx in range(int(num)):
    class_ = classes[idx]
    score = scores[idx]
    box = boxes[idx]

    if class_ not in colors_hash:
        colors_hash[class_] = tuple(np.random.choice(range(256), size=3))

    if score > 0.6:
        left = int(box[1] * color_frame.width)
        top = int(box[0] * color_frame.height)
        right = int(box[3] * color_frame.width)
        bottom = int(box[2] * color_frame.height)

        p1 = (left, top)
        p2 = (right, bottom)
        # draw box
        r, g, b = colors_hash[class_]

        cv2.rectangle(color_image, p1, p2, (int(r), int(g), int(b)), 2, 1)
        cv2.putText(color_image, str(class_)+" "+str(score), p1, cv2.FONT_HERSHEY_SIMPLEX, 0.75, (int(r), int(g), int(b)))

cv2.namedWindow('RealSense', cv2.WINDOW_AUTOSIZE)
cv2.imshow('RealSense', color_image)
cv2.waitKey(1)

print("[INFO] stop streaming ...") pipeline.stop()

In the other hand, I have created a ROS package where I launch the following script:

#!/usr/bin/env python3

#Creador: AMC 2021 #Funcion: Nodo de clasificacion de imagen con TensorFlow #Recibe: RealSense [Image(/camera/color/image_raw)] #Envia: Realsense [Image(/image_classified)] import rospy from sensor_msgs.msg import Image from std_msgs.msg import String import pyrealsense2 as rs import numpy as np import cv2 import tensorflow as tf import struct

class TENSORFLOW_ROS_CLASS:

Function: init

Comments

----------

Define neural network

Parameters

----------

Returns

-------

def __init__(self):

    # download model from: https://github.com/opencv/opencv/wiki/TensorFlow-Object-Detection-API#run-network-in-opencv
    print("[INFO] Loading model...")
    PATH_TO_CKPT ="frozen_inference_graph.pb"

    # Load the Tensorflow model into memory.
    detection_graph = tf.Graph()
    with detection_graph.as_default():
        od_graph_def = tf.compat.v1.GraphDef()
        with tf.compat.v1.gfile.GFile(PATH_TO_CKPT, 'rb') as fid:
            serialized_graph = fid.read()
            od_graph_def.ParseFromString(serialized_graph)
            tf.compat.v1.import_graph_def(od_graph_def, name='')
        sess = tf.compat.v1.Session(graph=detection_graph)

    # Input tensor is the image
    image_tensor = detection_graph.get_tensor_by_name('image_tensor:0')
    # Output tensors are the detection boxes, scores, and classes
    # Each box represents a part of the image where a particular object was detected
    detection_boxes = detection_graph.get_tensor_by_name('detection_boxes:0')
    # Each score represents level of confidence for each of the objects.
    # The score is shown on the result image, together with the class label.
    detection_scores = detection_graph.get_tensor_by_name('detection_scores:0')
    detection_classes = detection_graph.get_tensor_by_name('detection_classes:0')
    # Number of objects detected
    num_detections = detection_graph.get_tensor_by_name('num_detections:0')
    # code source of tensorflow model loading: https://www.geeksforgeeks.org/ml-training-image-classifier-using-tensorflow-object-detection-api/
    print("[INFO] Model loaded.")
    colors_hash = {}

Function: main

Comments

----------

Set up the node, the publications and subsciptions.

Parameters

----------

Returns

-------

def main(self):

    rospy.init_node('tensorflow_ros')
    rospy.loginfo("Iniciado nodo tensorflow_ros")

    #Publications
    self.classification_pub = rospy.Publisher("image_classified", Image, queue_size=100)

    #Subscriber
    rospy.Subscriber("/camera/color/image_raw", Image, self.callback_image)

    rospy.spin()

Function: callback_image

Comments

----------

Parameters

----------

msg: Data of the topic

Returns

-------

def callback_image(self,msg):
    color_image=Image()
    color_image=msg

    #Publish topic
    self.classification_pub.publish(color_image)

if name == 'main':

detector=TENSORFLOW_ROS_CLASS()
detector.main()

And the error is this one:

[INFO] Loading model...
Traceback (most recent call last):
  File "/home/sara/catkin_ws/src/tensorflow_ros/script/tensorflow_ros.py", line 106, in <module>
    detector=TENSORFLOW_ROS_CLASS()
  File "/home/sara/catkin_ws/src/tensorflow_ros/script/tensorflow_ros.py", line 40, in __init__
    serialized_graph = fid.read()
  File "/home/sara/.local/lib/python3.8/site-packages/tensorflow/python/lib/io/file_io.py", line 117, in read
    self._preread_check()
  File "/home/sara/.local/lib/python3.8/site-packages/tensorflow/python/lib/io/file_io.py", line 79, in _preread_check
    self._read_buf = _pywrap_file_io.BufferedInputStream(
tensorflow.python.framework.errors_impl.NotFoundError: frozen_inference_graph.pb; No such file or directory

Actually the frozen_inference_graph.pb file is in the same directory of the script, so I don't know what is different respect the python execution.

Any ideas or other example to run a DNN in ROS using tensorflow?

Best regards. Alessandro


Originally posted by Alessandro Melino on ROS Answers with karma: 113 on 2021-03-22

Post score: 0

1 Answers1

0

Rosanswers logo

Actually the frozen_inference_graph.pb file is in the same directory of the script, so I don't know what is different respect the python execution.

I believe this is similar/a duplicate of #q235337.

Summarising: the CWD (current working directory) when running a node with rosrun or roslaunch is not the same as when you start a script yourself.

The CWD for all nodes is $HOME/.ros. So unless there is a file called frozen_inference_graph.pb in $HOME/.ros, the error you mention is expected.


Originally posted by gvdhoorn with karma: 86574 on 2021-03-22

This answer was ACCEPTED on the original site

Post score: 0


Original comments

Comment by Alessandro Melino on 2021-03-23:
Yes, that was the problem, I must use the whole path of the file to reference it. Thank you.

gvdhoorn-rse
  • 39,013
  • 1
  • 1
  • 4