draw_rects.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 
3 import os.path as osp
4 
5 import cv2
6 import cv_bridge
7 import dynamic_reconfigure.server
8 from jsk_recognition_msgs.msg import ClassificationResult
9 from jsk_recognition_msgs.msg import RectArray
10 from jsk_recognition_utils.color import labelcolormap
11 from jsk_recognition_utils.put_text import put_text_to_image
12 from jsk_topic_tools import ConnectionBasedTransport
13 from jsk_topic_tools import warn_no_remap
14 import message_filters
15 import numpy as np
16 import rospy
17 import sensor_msgs.msg
18 
19 from jsk_perception.cfg import DrawRectsConfig
20 
21 
22 class DrawRects(ConnectionBasedTransport):
23 
24  def __init__(self):
25  super(DrawRects, self).__init__()
26 
27  self.colors = np.array(np.clip(
28  labelcolormap() * 255, 0, 255), dtype=np.uint8)
29  self.subs = []
30  self.use_classification_result = rospy.get_param('~use_classification_result', DrawRectsConfig.defaults[
31  'use_classification_result'])
32  self.approximate_sync = rospy.get_param('~approximate_sync', DrawRectsConfig.defaults['approximate_sync'])
33  self.queue_size = rospy.get_param('~queue_size', DrawRectsConfig.defaults['queue_size'])
34  self.transport_hint = rospy.get_param('~image_transport', 'raw')
35  rospy.loginfo("Using transport {}".format(self.transport_hint))
36  #
37  # To process latest message, we need to set buff_size must be large enough.
38  # we need to set buff_size larger than message size to use latest message for callback
39  # 640*480(image size) / 5 (expected compressed rate) *
40  # 70 (number of message need to be drop 70 x 30msec = 2100msec processing time)
41  #
42  # c.f. https://answers.ros.org/question/220502/image-subscriber-lag-despite-queue-1/
43  #
44  self.buff_size = rospy.get_param('~buff_size', 640 * 480 * 3 // 5 * 70)
45  rospy.loginfo("rospy.Subscriber buffer size : {}".format(self.buff_size))
46 
47  self.bridge = cv_bridge.CvBridge()
48 
49  self._srv_dynparam = dynamic_reconfigure.server.Server(
50  DrawRectsConfig, self._config_callback)
51 
52  if self.transport_hint == 'compressed':
53  self.pub_viz = self.advertise(
54  '{}/compressed'.format(rospy.resolve_name('~output')), sensor_msgs.msg.CompressedImage, queue_size=1)
55  else:
56  self.pub_viz = self.advertise(
57  '~output', sensor_msgs.msg.Image, queue_size=1)
58 
59  def _config_callback(self, config, level):
60  need_resubscribe = False
61  if self.use_classification_result != config.use_classification_result \
62  or self.approximate_sync != config.approximate_sync \
63  or self.queue_size != config.queue_size:
64  need_resubscribe = True
65 
66  self.approximate_sync = config.approximate_sync
67  self.queue_size = config.queue_size
68  self.use_classification_result = config.use_classification_result
69  self.show_proba = config.show_proba
70  self.rect_boldness = config.rect_boldness
71 
72  self.font_path = config.font_path
73  if self.use_classification_result and not osp.exists(self.font_path):
74  rospy.logwarn('Not valid font_path: {}'.format(self.font_path))
75  self.label_size = int(np.ceil(config.label_size))
76  self.label_boldness = config.label_boldness
77  self.label_font = config.label_font
78  self.label_margin_factor = config.label_margin_factor
79 
80  self.resolution_factor = config.resolution_factor
81  self.interpolation_method = config.interpolation_method
82 
83  if need_resubscribe and self.is_subscribed():
84  self.unsubscribe()
85  self.subscribe()
86  return config
87 
88  def subscribe(self):
89  if self.transport_hint == 'compressed':
90  sub_image = message_filters.Subscriber('{}/compressed'.format(rospy.resolve_name('~input')), sensor_msgs.msg.CompressedImage, buff_size=self.buff_size)
91  else:
92  sub_image = message_filters.Subscriber('~input', sensor_msgs.msg.Image, buff_size=self.buff_size)
93  sub_rects = message_filters.Subscriber('~input/rects', RectArray)
94  warn_no_remap('~input', '~input/rects')
95 
96  subs = [sub_image, sub_rects]
98  sub_class = message_filters.Subscriber(
99  '~input/class', ClassificationResult)
100  subs.append(sub_class)
101 
102  if self.approximate_sync:
103  slop = rospy.get_param('~slop', 1.0)
104  self.sync = message_filters.ApproximateTimeSynchronizer(
105  subs,
106  queue_size=self.queue_size, slop=slop)
107  self.sync.registerCallback(self.draw_rects_callback)
108  else:
110  subs, queue_size=self.queue_size)
111  self.sync.registerCallback(self.draw_rects_callback)
112  self.subs = subs
113  rospy.loginfo(" approximate_sync : {}".format(self.approximate_sync))
114  rospy.loginfo(" queue_size : {}".format(self.queue_size))
115 
116  def unsubscribe(self):
117  for sub in self.subs:
118  sub.sub.unregister()
119 
120  def draw_rects_callback(self, img_msg, rects_msg, class_msg=None):
121  start_time = rospy.Time.now()
122  if self.transport_hint == 'compressed':
123  # decode compressed image
124  np_arr = np.fromstring(img_msg.data, np.uint8)
125  cv_img = cv2.imdecode(np_arr, cv2.IMREAD_COLOR)
126  if img_msg.format.find("compressed rgb") > -1:
127  cv_img = cv_img[:, :, ::-1]
128  else:
129  cv_img = self.bridge.imgmsg_to_cv2(img_msg, desired_encoding='bgr8')
130 
131  img = cv2.resize(cv_img, None,
132  fx=self.resolution_factor,
133  fy=self.resolution_factor,
134  interpolation=self.interpolation_method)
135  for i, rect in enumerate(rects_msg.rects):
137  label_idx = class_msg.labels[i]
138  else:
139  label_idx = i
140 
141  color = self.colors[label_idx % len(self.colors)]
142 
143  pt1 = (int(rect.x * self.resolution_factor),
144  int(rect.y * self.resolution_factor))
145  pt2 = (int((rect.x + rect.width) * self.resolution_factor),
146  int((rect.y + rect.height) * self.resolution_factor))
147  cv2.rectangle(img, pt1=pt1, pt2=pt2,
148  color=color.tolist(),
149  thickness=self.rect_boldness,
150  lineType=cv2.LINE_AA)
152  text = class_msg.label_names[i]
153  if self.show_proba and len(class_msg.label_proba) > i:
154  text += ' ({0:.2f})'.format(class_msg.label_proba[i])
155  pos_x = int(rect.x * self.resolution_factor)
156  pos_y = int(rect.y * self.resolution_factor)
157  pos = (pos_x, pos_y)
158  if osp.exists(self.font_path):
159  img = put_text_to_image(
160  img, text, pos, self.font_path,
161  self.label_size,
162  color=(255, 255, 255),
163  background_color=tuple(color),
164  offset_x=self.rect_boldness / 2.0)
165  else:
166  pt1=(int(pos_x), int(pos_y - 16))
167  pt2=(int(pos_x + rect.width * self.resolution_factor)-10, int(pos_y))
168  cv2.rectangle(img, pt1, pt2,
169  color.tolist(), -1)
170  cv2.putText(img, text, (pos_x, pos_y - 4),
171  cv2.FONT_HERSHEY_PLAIN,
172  fontScale=1, color=(255, 255, 255),
173  thickness=1, lineType=cv2.LINE_AA)
174  if self.transport_hint == 'compressed':
175  viz_msg = sensor_msgs.msg.CompressedImage()
176  viz_msg.format = "jpeg"
177  viz_msg.data = np.array(cv2.imencode('.jpg', img)[1]).tostring()
178  else:
179  viz_msg = self.bridge.cv2_to_imgmsg(img, encoding='bgr8')
180  viz_msg.header = img_msg.header
181  self.pub_viz.publish(viz_msg)
182 
183  rospy.loginfo("processing time {} on message taken at {} sec ago".format(
184  (rospy.Time.now() - start_time).to_sec(),
185  (rospy.Time.now() - img_msg.header.stamp).to_sec()))
186 
187 
188 if __name__ == '__main__':
189  rospy.init_node('draw_rects')
190  dr = DrawRects()
191  rospy.spin()
node_scripts.draw_rects.DrawRects.resolution_factor
resolution_factor
Definition: draw_rects.py:80
node_scripts.draw_rects.DrawRects.pub_viz
pub_viz
Definition: draw_rects.py:53
node_scripts.draw_rects.DrawRects.draw_rects_callback
def draw_rects_callback(self, img_msg, rects_msg, class_msg=None)
Definition: draw_rects.py:120
node_scripts.draw_rects.DrawRects.subscribe
def subscribe(self)
Definition: draw_rects.py:88
node_scripts.draw_rects.DrawRects.queue_size
queue_size
Definition: draw_rects.py:33
node_scripts.draw_rects.DrawRects._srv_dynparam
_srv_dynparam
Definition: draw_rects.py:49
node_scripts.draw_rects.DrawRects._config_callback
def _config_callback(self, config, level)
Definition: draw_rects.py:59
ssd_train_dataset.int
int
Definition: ssd_train_dataset.py:175
node_scripts.draw_rects.DrawRects.interpolation_method
interpolation_method
Definition: draw_rects.py:81
node_scripts.draw_rects.DrawRects.buff_size
buff_size
Definition: draw_rects.py:44
node_scripts.draw_rects.DrawRects
Definition: draw_rects.py:22
node_scripts.draw_rects.DrawRects.unsubscribe
def unsubscribe(self)
Definition: draw_rects.py:116
node_scripts.draw_rects.DrawRects.colors
colors
Definition: draw_rects.py:27
jsk_recognition_utils::color
node_scripts.draw_rects.DrawRects.show_proba
show_proba
Definition: draw_rects.py:69
node_scripts.draw_rects.DrawRects.sync
sync
Definition: draw_rects.py:104
message_filters::Subscriber
node_scripts.draw_rects.DrawRects.font_path
font_path
Definition: draw_rects.py:72
node_scripts.draw_rects.DrawRects.bridge
bridge
Definition: draw_rects.py:47
node_scripts.draw_rects.DrawRects.subs
subs
Definition: draw_rects.py:29
node_scripts.draw_rects.DrawRects.label_font
label_font
Definition: draw_rects.py:77
node_scripts.draw_rects.DrawRects.rect_boldness
rect_boldness
Definition: draw_rects.py:70
node_scripts.draw_rects.DrawRects.label_size
label_size
Definition: draw_rects.py:75
node_scripts.draw_rects.DrawRects.__init__
def __init__(self)
Definition: draw_rects.py:24
node_scripts.draw_rects.DrawRects.label_margin_factor
label_margin_factor
Definition: draw_rects.py:78
node_scripts.draw_rects.DrawRects.transport_hint
transport_hint
Definition: draw_rects.py:34
jsk_recognition_utils::put_text
message_filters::TimeSynchronizer
node_scripts.draw_rects.DrawRects.label_boldness
label_boldness
Definition: draw_rects.py:76
node_scripts.draw_rects.DrawRects.approximate_sync
approximate_sync
Definition: draw_rects.py:32
node_scripts.draw_rects.DrawRects.use_classification_result
use_classification_result
Definition: draw_rects.py:30


jsk_perception
Author(s): Manabu Saito, Ryohei Ueda
autogenerated on Fri May 16 2025 03:11:16