Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 import rospy
00022 from sensor_msgs.msg import Image
00023 import struct
00024
00025
00026
00027
00028
00029 def get_pixels_depth(ini_x, ini_y, end_x, end_y, depth_image=None):
00030 rospy.loginfo(
00031 "Getting average depth at: " + str((ini_x, ini_y, end_x, end_y)))
00032 if depth_image is None:
00033 rospy.loginfo("Waiting for a depth image...")
00034 img = rospy.wait_for_message('/xtion/depth/image_raw',
00035 Image)
00036 else:
00037 img = depth_image
00038 rospy.loginfo("The image has size: " + str(img.width) +
00039 " width, " + str(img.height) + " height")
00040 if ini_x < 0:
00041 rospy.logerr("Can't ask for a pixel depth out of image (ini_x < 0)")
00042 return None
00043 if ini_y < 0:
00044 rospy.logerr("Can't ask for a pixel depth out of image (ini_y < 0)")
00045 return None
00046 if end_x > img.width:
00047 rospy.logerr("Can't ask for a pixel depth out of image (end_x > img.width [%s])" % (
00048 str(img.width)))
00049 return None
00050 if end_y > img.height:
00051 rospy.logerr("Can't ask for a pixel depth out of image (end_x > img.height [%s])" % (
00052 str(img.height)))
00053 return None
00054
00055 if (img.step / img.width) == 4:
00056 rospy.loginfo("Got a rectified depth image (4 byte floats)")
00057 else:
00058 rospy.loginfo("Got a raw depth image (2 byte integers)")
00059
00060
00061 sum_depth = 0
00062 pixel_count = 0
00063 nan_count = 0
00064 for x in range(ini_x, end_x):
00065 for y in range(ini_y, end_y):
00066 pixel = get_pixel_depth(x, y, img)
00067
00068
00069 if pixel != pixel:
00070 nan_count += 1
00071 else:
00072 sum_depth += pixel
00073 pixel_count += 1
00074
00075 if pixel_count > 0:
00076 avg = sum_depth / float(pixel_count)
00077 rospy.loginfo("Average is: " + str(avg) + " (with " + str(pixel_count) +
00078 " valid pixels, " + str(nan_count) + " NaNs)")
00079
00080 return avg
00081 else:
00082 rospy.logwarn("No pixels that are not NaN, can't return an average")
00083 return None
00084
00085
00086 def get_pixel_depth(x, y, depth_image=None):
00087 if depth_image is None:
00088 rospy.loginfo("Waiting for a depth image...")
00089 img = rospy.wait_for_message('/xtion/depth/image_raw',
00090 Image)
00091 else:
00092 img = depth_image
00093
00094 if x < 0:
00095 rospy.logerr("Can't ask for a pixel depth out of image (x < 0)")
00096 return None
00097 if y < 0:
00098 rospy.logerr("Can't ask for a pixel depth out of image (y < 0)")
00099 return None
00100 if x > img.width:
00101 rospy.logerr("Can't ask for a pixel depth out of image (x > img.width [%s])" % (
00102 str(img.width)))
00103 return None
00104 if y > img.height:
00105 rospy.logerr("Can't ask for a pixel depth out of image (x > img.height [%s])" % (
00106 str(img.height)))
00107 return None
00108
00109 index = (y * img.step) + (x * (img.step / img.width))
00110
00111 if (img.step / img.width) == 4:
00112
00113 byte_data = ""
00114 for i in range(0, 4):
00115 byte_data += img.data[index + i]
00116
00117 distance = struct.unpack('f', byte_data)[0]
00118 return distance
00119 else:
00120 rospy.logwarn("Got a raw depth image (2 byte integers) (UNTESTED) it will probably fail.")
00121
00122 if img.is_bigendian:
00123 distance = (img.data[index] << 8) + img.data[index + 1]
00124 else:
00125 distance = int(img.data[index]) + (int(img.data[index + 1]) << 8)
00126 return distance
00127
00128
00129 class RGBDPlay(object):
00130 def __init__(self):
00131 self.last_msg = None
00132
00133 if rospy.get_param('/use_sim_time', False):
00134 depth_32FC1_topic = '/xtion/depth/image_raw'
00135 else:
00136 depth_32FC1_topic = '/xtion/depth/image'
00137 self.rgbd_sub = rospy.Subscriber(depth_32FC1_topic,
00138 Image,
00139 self.depth_img_cb,
00140 queue_size=1)
00141 rospy.loginfo(
00142 "Subscribed to: '" + str(self.rgbd_sub.resolved_name) + "' topic.")
00143 self.run()
00144
00145 def depth_img_cb(self, msg):
00146 """
00147 :type msg: Image
00148 """
00149 self.last_msg = msg
00150
00151 def run(self):
00152 """Show information on what was found in the rgbD image"""
00153 rospy.loginfo("Waiting for first Image message...")
00154 while not rospy.is_shutdown() and self.last_msg is None:
00155 rospy.sleep(0.2)
00156
00157
00158 r = rospy.Rate(1)
00159 while not rospy.is_shutdown():
00160 self.do_stuff_with_last_msg()
00161 r.sleep()
00162
00163 def do_stuff_with_last_msg(self):
00164 """Print funny sentences about what we can guess of our status thanks to the depth image"""
00165 avg_center_depth = self.get_center_image_depth()
00166 if avg_center_depth is None:
00167 rospy.loginfo(
00168 "You are so close or so far I can't see you with my depth camera!")
00169 elif avg_center_depth > 1.5:
00170 rospy.loginfo("I see you, get closer to me!")
00171 else:
00172 rospy.loginfo("I see you, I like having people close to me :)")
00173
00174 def get_center_image_depth(self):
00175 x1 = self.last_msg.width / 2 - 10
00176 x2 = self.last_msg.width / 2 + 10
00177 y1 = self.last_msg.height / 2 - 10
00178 y2 = self.last_msg.height / 2 + 10
00179
00180 avg_depth = get_pixels_depth(x1, y1, x2, y2, self.last_msg)
00181 return avg_depth
00182
00183
00184 if __name__ == '__main__':
00185 rospy.init_node('rgbd_play')
00186 lp = RGBDPlay()
00187 rospy.spin()