25 from sensor_msgs.msg
import Image
26 from cv_bridge
import CvBridge, CvBridgeError
27 from geometry_msgs.msg
import Point
31 from control_msgs.msg
import (
32 FollowJointTrajectoryAction,
33 FollowJointTrajectoryGoal,
34 JointTrajectoryControllerState
36 from trajectory_msgs.msg
import JointTrajectoryPoint
42 self.
_image_pub = rospy.Publisher(
"~output_image", Image, queue_size=1)
60 input_image = self.
_bridge.imgmsg_to_cv2(ros_image,
"bgr8")
61 except CvBridgeError
as e:
84 object_center = Point(
91 translated_point = Point()
92 translated_point.x = object_center.x - self.
_image_shape.x * 0.5
93 translated_point.y = -(object_center.y - self.
_image_shape.y * 0.5)
97 normalized_point = Point()
99 normalized_point.x = translated_point.x / (self.
_image_shape.x * 0.5)
100 normalized_point.y = translated_point.y / (self.
_image_shape.y * 0.5)
102 return normalized_point
113 MIN_OBJECT_SIZE = 1000
117 hsv = cv2.cvtColor(bgr_image, cv2.COLOR_BGR2HSV)
121 mask = cv2.inRange(hsv, lower_color, upper_color)
126 contours, _ = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
128 _, contours, _ = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
133 for contour
in contours:
134 approx = cv2.convexHull(contour)
135 rect = cv2.boundingRect(approx)
142 rect = max(rects, key=(
lambda x: x[2] * x[3]))
146 if rect[2] * rect[3] > MIN_OBJECT_SIZE:
149 cv2.rectangle(bgr_image,
151 (rect[0] + rect[2], rect[1] + rect[3]),
152 (0, 0, 255), thickness=2)
164 lower_orange = np.array([5,127,127])
165 upper_orange = np.array([20,255,255])
174 lower_blue = np.array([100,127,127])
175 upper_blue = np.array([110,255,255])
189 rospy.logerr(
"cascade file does not set")
194 gray = cv2.cvtColor(bgr_image, cv2.COLOR_BGR2GRAY)
198 height, width = gray.shape[:2]
199 small_gray = cv2.resize(gray, (width/SCALE, height/SCALE))
203 small_faces = self.
_face_cascade.detectMultiScale(small_gray)
206 for small_face
in small_faces:
209 face = small_face*SCALE
214 face[1]:face[1]+face[3],
215 face[0]:face[0]+face[2]]
224 cv2.rectangle(bgr_image,
226 (face[0]+face[2], face[1]+face[3]),
239 FollowJointTrajectoryAction)
240 self.
__client.wait_for_server(rospy.Duration(5.0))
241 if not self.
__client.wait_for_server(rospy.Duration(5.0)):
242 rospy.logerr(
"Action Server Not Found")
243 rospy.signal_shutdown(
"Action Server not found")
246 self.
_state_sub = rospy.Subscriber(
"/sciurus17/controller3/neck_controller/state",
259 yaw_radian = state.actual.positions[0]
260 pitch_radian = state.actual.positions[1]
278 def set_angle(self, yaw_angle, pitch_angle, goal_secs=1.0e-9):
281 goal = FollowJointTrajectoryGoal()
282 goal.trajectory.joint_names = [
"neck_yaw_joint",
"neck_pitch_joint"]
284 yawpoint = JointTrajectoryPoint()
285 yawpoint.positions.append(yaw_angle)
286 yawpoint.positions.append(pitch_angle)
287 yawpoint.time_from_start = rospy.Duration(goal_secs)
288 goal.trajectory.points.append(yawpoint)
291 self.
__client.wait_for_result(rospy.Duration(0.1))
298 neck.set_angle(math.radians(0), math.radians(0), 3.0)
304 rospy.on_shutdown(hook_shutdown)
315 INITIAL_YAW_ANGLE = 0
316 INITIAL_PITCH_ANGLE = 0
323 MIN_PITCH_ANGLE = -70
329 OPERATION_GAIN_X = 5.0
330 OPERATION_GAIN_Y = 5.0
334 RESET_OPERATION_ANGLE = 3
340 while not neck.state_received():
342 yaw_angle = neck.get_current_yaw()
343 pitch_angle = neck.get_current_pitch()
346 detection_timestamp = rospy.Time.now()
348 while not rospy.is_shutdown():
351 object_position = object_tracker.get_object_position()
353 if object_tracker.object_detected():
354 detection_timestamp = rospy.Time.now()
357 lost_time = rospy.Time.now() - detection_timestamp
361 if lost_time.to_sec() > 1.0:
367 if math.fabs(object_position.x) > THRESH_X:
368 yaw_angle += -object_position.x * OPERATION_GAIN_X
370 if math.fabs(object_position.y) > THRESH_Y:
371 pitch_angle += object_position.y * OPERATION_GAIN_Y
375 if yaw_angle > MAX_YAW_ANGLE:
376 yaw_angle = MAX_YAW_ANGLE
377 if yaw_angle < MIN_YAW_ANGLE:
378 yaw_angle = MIN_YAW_ANGLE
380 if pitch_angle > MAX_PITCH_ANGLE:
381 pitch_angle = MAX_PITCH_ANGLE
382 if pitch_angle < MIN_PITCH_ANGLE:
383 pitch_angle = MIN_PITCH_ANGLE
388 diff_yaw_angle = yaw_angle - INITIAL_YAW_ANGLE
389 if math.fabs(diff_yaw_angle) > RESET_OPERATION_ANGLE:
390 yaw_angle -= math.copysign(RESET_OPERATION_ANGLE, diff_yaw_angle)
392 yaw_angle = INITIAL_YAW_ANGLE
394 diff_pitch_angle = pitch_angle - INITIAL_PITCH_ANGLE
395 if math.fabs(diff_pitch_angle) > RESET_OPERATION_ANGLE:
396 pitch_angle -= math.copysign(RESET_OPERATION_ANGLE, diff_pitch_angle)
398 pitch_angle = INITIAL_PITCH_ANGLE
400 neck.set_angle(math.radians(yaw_angle), math.radians(pitch_angle))
405 if __name__ ==
'__main__':
406 rospy.init_node(
"head_camera_tracking")