RAPP Platform  v0.6.0
RAPP Platform is a collection of ROS nodes and back-end processes that aim to deliver ready-to-use generic services to robots
 All Classes Namespaces Files Functions Variables Macros
image_classification.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 
3 #Copyright 2015 RAPP
4 
5 #Licensed under the Apache License, Version 2.0 (the "License");
6 #you may not use this file except in compliance with the License.
7 #You may obtain a copy of the License at
8 
9  #http://www.apache.org/licenses/LICENSE-2.0
10 
11 #Unless required by applicable law or agreed to in writing, software
12 #distributed under the License is distributed on an "AS IS" BASIS,
13 #WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 #See the License for the specific language governing permissions and
15 #limitations under the License.
16 
17 # Author: Athanassios Kintsakis, Manos Tsardoulias
18 # contact: akintsakis@issel.ee.auth.gr, etsardou@eng.auth.gr
19 
20 import rospy
21 import sys
22 import numpy as np
23 import matplotlib.pyplot as plt
24 import time
25 from os.path import expanduser
26 from app_error_exception import AppError
27 import os
28 import sys
29 
30 import caffe
31 
32 from rapp_platform_ros_communications.srv import (
33  imageClassificationSrv,
34  imageClassificationSrvResponse,
35  registerImageToOntologySrv,
36  registerImageToOntologySrvResponse,
37  registerImageToOntologySrvRequest,
38  ontologyClassBridgeSrv,
39  ontologyClassBridgeSrvResponse,
40  ontologyClassBridgeSrvRequest
41  )
42 
43 
44 ## @class ImageClassification
45 # @brief Contains the necessary functions for classifying an images and requesting registration to the ontology
47 
48  ## Initializes Caffe
49  def __init__(self):
50  self.caffe_root = expanduser("~")+'/rapp_platform/caffe/'
51 
52  if not os.path.isfile(self.caffe_root + \
53  'models/bvlc_reference_caffenet/bvlc_reference_caffenet.caffemodel'):
54  print("Downloading pre-trained CaffeNet model...")
55  os.system(self.caffe_root+"scripts/download_model_binary.py \
56  ../models/bvlc_reference_caffenet")
57 
58  caffe.set_mode_cpu()
59 
60  self.net = caffe.Net(self.caffe_root + \
61  'models/bvlc_reference_caffenet/deploy.prototxt',\
62  self.caffe_root + \
63  'models/bvlc_reference_caffenet/bvlc_reference_caffenet.caffemodel',\
64  caffe.TEST)
65 
66  self.transformer = \
67  caffe.io.Transformer({'data': self.net.blobs['data'].data.shape})
68  self.transformer.set_transpose('data', (2, 0, 1))
69  self.transformer.set_mean('data', \
70  np.load(self.caffe_root + \
71  'python/caffe/imagenet/ilsvrc_2012_mean.npy').mean(1).mean(1))
72  self.transformer.set_raw_scale('data', 255)
73  self.transformer.set_channel_swap('data', (2, 1, 0))
74  self.net.blobs['data'].reshape(1, 3, 227, 227)
75  imagenet_labels_filename = self.caffe_root + 'data/ilsvrc12/synset_words.txt'
76  self.labels = np.loadtxt(imagenet_labels_filename, str, delimiter='\t')
77 
78  ## @brief Implements the imageClassificationSrv service main function
79  # @param req [rapp_platform_ros_communications::imageClassificationSrvRequest::Request&] The ROS service request
80  #
81  # @return res [rapp_platform_ros_communications::imageClassificationSrvResponse::Response&] The ROS service response
82  # @exception Exception IndexError
83  # @exception Exception IOError
84  # @exception Exception AppError
85  # @exception Exception KeyError
86  def classifyImage(self, req):
87  try:
88  res = imageClassificationSrvResponse()
89  start_time = time.time()
90  caffeObjectClass = self.getImageClass(req)
91  res.objectClass = caffeObjectClass
92 
93  if(req.registerToOntology):
94  ontologyClass = self.getOntologyClass(caffeObjectClass)
95  ontologyNameOfImage = self.registerToOntology(req, \
96  caffeObjectClass, ontologyClass, req.objectFileUrl)
97  res.ontologyNameOfImage = ontologyNameOfImage
98 
99  res.success = True
100  return res
101  except IndexError, e:
102  res.trace.append("IndexError: " + str(e))
103  res.error = "IndexError: "+ str(e)
104  res.success = False
105  except IOError, e:
106  res.success = False
107  res.trace.append("IOError: " + str(e))
108  res.error = "IOError: " + str(e)
109  except KeyError, e:
110  res.success = False
111  res.trace.append('"KeyError (probably invalid cfg/.yaml parameter) \
112  "%s"' % str(e))
113  res.error = '"KeyError (probably invalid cfg/.yaml parameter) "%s"' \
114  % str(e)
115  except AppError as e:
116  AppError.passErrorToRosSrv(e,res)
117  return res
118 
119  ## @brief Calls the caffe wrapper service that registers the image to the ontology
120  # @param caffeObjectClass [string] The caffe object class
121  #
122  # @return ontologyClassBridgeResponse.ontologyClass [string] The ontology class of the image
123  # @exception Exception AppError
124  def getOntologyClass(self, caffeObjectClass):
125  serv_topic = rospy.get_param(\
126  'rapp_caffe_wrapper_get_ontology_class_equivalent')
127  knowrob_service = rospy.ServiceProxy(serv_topic, ontologyClassBridgeSrv)
128  ontologyClassBridgeReq = ontologyClassBridgeSrvRequest()
129  ontologyClassBridgeReq.caffeClass = caffeObjectClass
130  ontologyClassBridgeResponse = knowrob_service(ontologyClassBridgeReq)
131  if(ontologyClassBridgeResponse.success != True):
132  raise AppError(ontologyClassBridgeResponse.error, \
133  ontologyClassBridgeResponse.trace)
134  return ontologyClassBridgeResponse.ontologyClass
135 
136  ## @brief Calls the caffe wrapper service that registers the image to the ontology
137  # @param req [rapp_platform_ros_communications::ontologyClassBridgeSrvRequest::Request&] The ROS service request
138  # @param caffeObjectClass [string] The caffe object class
139  # @param ontologyClass [string] The ontology object class
140  # @param currentImagePath [string] The path of the image file
141  #
142  # @return registerImageToOntologyResponse.object_entry [string] The ontology entry of the image
143  # @exception Exception AppError
144  def registerToOntology(self, req, caffeObjectClass, ontologyClass, \
145  currentImagePath):
146  serv_topic = rospy.get_param('rapp_caffe_wrapper_register_image_to_ontology')
147  knowrob_service = rospy.ServiceProxy(serv_topic, registerImageToOntologySrv)
148  registerImageToOntologyReq = registerImageToOntologySrvRequest()
149  registerImageToOntologyReq.username = req.username
150  registerImageToOntologyReq.ontologyClass = ontologyClass
151  registerImageToOntologyReq.caffeClass = caffeObjectClass
152  registerImageToOntologyReq.imagePath = currentImagePath
153  registerImageToOntologyResponse = knowrob_service(registerImageToOntologyReq)
154  if(registerImageToOntologyResponse.success != True):
155  raise AppError(registerImageToOntologyResponse.error, \
156  registerImageToOntologyResponse.trace)
157  return registerImageToOntologyResponse.object_entry
158 
159  ## @brief Obtains the name of the class of the image from the caffe image classes file
160  # @param req [rapp_platform_ros_communications::ontologyClassBridgeSrvRequest::Request&] The ROS service request
161  #
162  # @return res [string] The class of the image
163  def getImageClass(self,req):
164  self.net.blobs['data'].data[...] = \
165  self.transformer.preprocess('data', \
166  caffe.io.load_image(req.objectFileUrl))
167  out = self.net.forward()
168  top_k = self.net.blobs['prob'].data[0].flatten().argsort()[-1:-6:-1]
169  objectClass = self.labels[top_k][0]
170  return objectClass
171 
172 
173 
174 
Exception compliant with the ros error and trace srvs.
def getImageClass
Obtains the name of the class of the image from the caffe image classes file.
Contains the necessary functions for classifying an images and requesting registration to the ontolog...
def classifyImage
Implements the imageClassificationSrv service main function.
def getOntologyClass
Calls the caffe wrapper service that registers the image to the ontology.
def registerToOntology
Calls the caffe wrapper service that registers the image to the ontology.