Go to the documentation of this file.00001
00002
00003
00004
00005 import rospy
00006 from docomo_perception.msg import ImageRecognitionCandidate
00007 from docomo_perception.srv import (
00008 ImageRecognition,
00009 ImageRecognitionRequest,
00010 ImageRecognitionResponse
00011 )
00012 from cv_bridge import CvBridge, CvBridgeError
00013 import cv2
00014
00015 import json
00016 import requests
00017 import yaml
00018 import threading
00019 import tempfile
00020
00021 global APIHOST, APIKEY
00022 settings_path = "/var/lib/robot/docomo_image_recognition_settings.yaml"
00023
00024
00025 class DocomoImageRecognitionNode(object):
00026 def __init__(self):
00027 self.srv = rospy.Service("image_recognition", ImageRecognition, self.serviceCallback)
00028 self.lock = threading.Lock()
00029 self.bridge = CvBridge()
00030
00031 def _save_jpg_from_imgmsg(self, msg):
00032 mat = self.bridge.imgmsg_to_cv2(msg)
00033 img_path = tempfile.mktemp(prefix='docomo_img_recog_',suffix='.jpg')
00034 cv2.imwrite(img_path, mat)
00035 return img_path
00036
00037 def _type(self, t):
00038 if t == ImageRecognitionRequest.ALL:
00039 return "product-all"
00040 elif t == ImageRecognitionRequest.BOOK:
00041 return "book"
00042 elif t == ImageRecognitionRequest.CD:
00043 return "cd"
00044 elif t == ImageRecognitionRequest.DVD:
00045 return "dvd"
00046 elif t == ImageRecognitionRequest.GAME:
00047 return "game"
00048 elif t == ImageRecognitionRequest.SOFTWARE:
00049 return "software"
00050 elif t == ImageRecognitionRequest.FOOD:
00051 return "food"
00052 else:
00053 rospy.logerr("invalid type error")
00054 return "product-all"
00055
00056 def serviceCallback(self, req):
00057 jpg_path = self._save_jpg_from_imgmsg(req.image)
00058 jpg_data = None
00059 with open(jpg_path, 'rb') as f:
00060 jpg_data = f.read()
00061
00062 params = {
00063 "APIKEY": APIKEY,
00064 "recog": self._type(req.type),
00065 "numOfCandidates": str(req.numOfCandidates)
00066 }
00067 headers = {
00068 "Content-type": "application/octet-stream"
00069 }
00070 self.lock.acquire()
00071 urlres = requests.post(APIHOST,
00072 data=jpg_data,
00073 headers=headers,
00074 params=params)
00075 self.lock.release()
00076 rospy.loginfo("sent request: %d", urlres.status_code)
00077 if urlres.status_code is not requests.codes.ok:
00078 rospy.logerr("failed to send request: %d", urlres.status_code)
00079 return ImageRecognitionResponse()
00080
00081 resdic = json.loads(urlres.content)
00082
00083 res = ImageRecognitionResponse()
00084 candidates = []
00085 if resdic.has_key('candidates') and len(resdic["candidates"]) > 0:
00086 res.candidates = [ ImageRecognitionCandidate(float(c["score"]),
00087 c["category"],
00088 c["detail"]["itemName"],
00089 c["imageUrl"]) for c in resdic["candidates"] ]
00090 return res
00091
00092 def load_image_recognition_settings():
00093 global APIHOST, APIKEY
00094
00095 try:
00096 with open(settings_path) as f:
00097 key = yaml.load(f)
00098 APIHOST = key['APIHOST']
00099 APIKEY = key['APIKEY']
00100 rospy.loginfo("loaded settings")
00101 except IOError as e:
00102 rospy.logerr('"%s" not found : %s' % (settings_path, e))
00103 exit(-1)
00104 except Exception as e:
00105 rospy.logerr("failed to load settings: %s", e)
00106 rospy.logerr("check if exists valid setting file in %s", settings_path)
00107 exit(-1)
00108
00109 if __name__ == '__main__':
00110 rospy.init_node("docomo_image_recognition_node")
00111 n = DocomoImageRecognitionNode()
00112 load_image_recognition_settings()
00113 rospy.spin()