3 import roslib; roslib.load_manifest(
'jsk_perception')
7 from sensor_msgs.msg
import Image
9 from jsk_recognition_msgs.msg
import Rect
11 from cv_bridge
import CvBridge, CvBridgeError
13 from dynamic_reconfigure.server
import Server
as DynamicReconfigureServer
14 from dynamic_reconfigure.msg
import SensorLevels
15 from jsk_perception.cfg
import matchtemplateConfig
as ConfigType
39 status = cv2.minMaxLoc(arr)
40 pt1 = (max(status[2+idx][0]-ex_size[0]/2,0),
41 max(status[2+idx][1]-ex_size[1]/2,0))
42 pt2 = (min(status[2+idx][0]+ex_size[0]/2,arr.shape[1]),
43 min(status[2+idx][1]+ex_size[1]/2,arr.shape[0]))
44 mask = np.ones((arr.shape[0], arr.shape[1]), dtype=np.uint8) * 255
45 mask[pt1[0]:pt2[0], pt1[1]:pt2[1]] = 0
46 status2 = cv2.minMaxLoc(arr, mask)
47 return (status[0+idx],status2[0+idx],status[2+idx],status2[2+idx])
67 "current_template", Image, queue_size=1)
69 "result", TransformStamped, queue_size=1)
70 self.
debug_pub = rospy.Publisher(
"debug_image", Image, queue_size=1)
78 rospy.resolve_name(
"set_reference_point"),
80 self.
search_sub = rospy.Subscriber(rospy.resolve_name(
"set_search_rect"),
86 def set_template (self, ref_id='', ref_image=None, ref_rect=None,
87 ser_frame=
None, ser_rect=
None, color=
None, method=
None):
88 if not self.templates.has_key(ref_id):
89 self.
templates[ref_id] = {
'ref_orig':
None,
'ref_point':
None,
'ref_image':
None,
90 'ser_frame':
None,
'ser_rect':
None,
91 'color':
'mono8',
'method':cv2.TM_SQDIFF_NORMED}
94 color_changed = (self.
templates[ref_id][
'color'] != color)
and (color !=
None)
96 something_changed = (ref_image
is not None)
or \
97 (ref_rect
is not None)
or color_changed
100 if ref_image
is not None:
101 self.
templates[ref_id][
'ref_orig'] = ref_image.copy()
103 ref_image = self.
templates[ref_id][
'ref_orig']
106 if ref_image
is not None and ref_image.ndim == 2:
113 if (ref_rect
is not None)
and (ref_image
is not None)
and \
115 ref_rect = (min(max(0,ref_rect[0]),ref_image.shape[1]-ref_rect[2]),
116 min(max(0,ref_rect[1]),ref_image.shape[0]-ref_rect[3]),
117 ref_rect[2],ref_rect[3])
118 ref_image_rect = ref_image[
119 ref_rect[1]:ref_rect[1] + ref_rect[3],
120 ref_rect[0]:ref_rect[0] + ref_rect[2]].copy()
121 if color ==
'bgr8' or (color ==
'mono8' and ref_image.ndim == 2):
122 template_image = ref_image_rect
123 elif color ==
'mono8':
124 template_image = cv2.cvtColor(
125 ref_image_rect, cv2.COLOR_BGR2GRAY)
126 elif color ==
'hsv8':
127 template_image = cv2.cvtColor(
128 ref_image_rect, cv2.COLOR_BGR2HSV)
130 self.
templates[ref_id][
'ref_point'] = (ref_rect[0]+ref_rect[2]/2,
131 ref_rect[1]+ref_rect[3]/2)
132 self.
templates[ref_id][
'ref_image'] = template_image
133 rospy.loginfo(
"set ref_image id=%s, rect=%s", ref_id, ref_rect);
136 if ser_frame !=
None:
137 self.
templates[ref_id][
'ser_frame'] = ser_frame
138 rospy.loginfo(
"set ser_frame id=%s frame=%s", ref_id, ser_frame);
140 self.
templates[ref_id][
'ser_rect'] = ser_rect
143 self.
templates[ref_id][
'method'] = method
144 rospy.loginfo(
"set method id=%s method=%s", ref_id, method);
149 cv_image = self.bridge.imgmsg_to_cv2(
152 except CvBridgeError
as e:
161 self.lockobj.acquire()
162 pt = (
int(msg.point.x),
int(msg.point.y))
171 self.
set_template(
'',ser_frame=
None, ser_rect=search_rect)
172 self.lockobj.release()
176 self.lockobj.acquire()
177 self.
set_template(ser_rect=(msg.x,msg.y,msg.width,msg.height))
178 self.lockobj.release()
182 self.lockobj.acquire()
184 self.lockobj.release()
188 self.lockobj.acquire()
191 config[
'default_template_height'])
193 config[
'default_search_height'])
197 if config[
'current_template_id']
in self.templates.keys():
199 template = self.
templates[config[
'current_template_id']]
201 cv2.TM_SQDIFF, cv2.TM_SQDIFF_NORMED, cv2.TM_CCORR,
202 cv2.TM_CCORR_NORMED, cv2.TM_CCOEFF, cv2.TM_CCOEFF_NORMED]
203 if (template[
'ref_point']
is not None)
and \
204 (template[
'ref_image']
is not None):
205 ref_pt = template[
'ref_point']
206 ref_size = template[
'ref_image'].shape
207 ref_rect = (ref_pt[0]-ref_size[0]/2,ref_pt[1]-ref_size[1]/2,ref_size[0],ref_size[1])
209 color=config[
'template_color_space'],
211 method=method_enum[config[
'match_method']])
213 config[
'template_color_method'] = template[
'color']
214 self.lockobj.release()
220 debug_image = self.bridge.imgmsg_to_cv2(msg,
"bgr8")
222 self.lockobj.acquire()
225 for template_id
in self.templates.keys():
226 reference_image = self.
templates[template_id][
'ref_image']
227 search_rect = self.
templates[template_id][
'ser_rect']
228 matchmethod = self.
templates[template_id][
'method']
229 color_space = self.
templates[template_id][
'color']
230 if reference_image
is None:
232 if search_rect ==
None:
continue 233 if (self.
templates[template_id][
'ser_frame'] !=
None and 234 self.
templates[template_id][
'ser_frame'] != msg.header.frame_id):
continue 237 search_rect = (max(0,search_rect[0]),
238 max(0,search_rect[1]),
239 min(msg.width,search_rect[0]+search_rect[2])- max(0,search_rect[0]),
240 min(msg.height,search_rect[1]+search_rect[3])- max(0,search_rect[1]))
242 result = TransformStamped(header=msg.header)
245 if color_space ==
'mono8':
246 search_image = self.bridge.imgmsg_to_cv2(msg,
'mono8')
248 search_image = self.bridge.imgmsg_to_cv2(msg,
'bgr8')
249 if color_space !=
'bgr8':
250 search_image = cv2.cvtColor(
251 search_image, cv2.COLOR_BGR2HSV)
253 image_size = search_image.shape
255 reference_image.shape[1], reference_image.shape[0])
258 if (search_rect[2] < reference_size[0])
or (search_rect[3] < reference_size[1]):
261 results = cv2.matchTemplate(
263 search_rect[1]:search_rect[1] + search_rect[3],
264 search_rect[0]:search_rect[0] + search_rect[2]],
265 reference_image, matchmethod)
267 if matchmethod
in [cv2.TM_SQDIFF, cv2.TM_SQDIFF_NORMED]:
271 status = (1 - status[0], 1 - status[1], status[2], status[3])
273 result_pt = (status[2][0]+search_rect[0]+reference_size[0]/2,
274 status[2][1]+search_rect[1]+reference_size[1]/2)
277 result.child_frame_id = template_id
278 result.transform.translation.x = result_pt[0]
279 result.transform.translation.y = result_pt[1]
280 result.transform.rotation.w = 1
281 self.result_pub.publish(result)
283 if reference_image.ndim == 2
and \
284 reference_image.dtype == np.uint8:
285 ref_msg = self.bridge.cv2_to_imgmsg(
286 reference_image,
"mono8")
288 ref_msg = self.bridge.cv2_to_imgmsg(
289 reference_image,
"bgr8")
290 self.reference_pub.publish(ref_msg)
294 val_x = result_pt[0]-search_rect[2]/2
295 val_y = result_pt[1]-search_rect[3]/2
296 ser_scale = max(2,5+np.log(status[0]))
298 min(max(val_x,0),image_size[0]-search_rect[2]),
299 min(max(val_y,0),image_size[1]-search_rect[3]),
300 reference_size[0]*ser_scale,reference_size[1]*ser_scale)
305 cv2.rectangle(debug_image,
306 (result_pt[0] - reference_size[0]/2,
307 result_pt[1] - reference_size[1]/2),
308 (result_pt[0] + reference_size[0]/2,
309 result_pt[1] + reference_size[1]/2),
311 cv2.rectangle(debug_image,
312 (search_rect[0], search_rect[1]),
313 (search_rect[0] + search_rect[2],
314 search_rect[1] + search_rect[3]),
317 debug_image, str(status[0]),
318 (search_rect[0], search_rect[1] + search_rect[3]),
319 fontFace=cv2.FONT_HERSHEY_SIMPLEX, fontScale=1,
320 color=(0, 255, 0), thickness=2,
323 if reference_image.ndim == 2:
324 reference_color_image = cv2.cvtColor(
325 reference_image, cv2.COLOR_GRAY2BGR)
327 :reference_size[1], :reference_size[0], :] = \
328 reference_color_image.copy()
331 :reference_size[1], :reference_size[0], :] = \
332 reference_image.copy()
334 except CvBridgeError
as e:
337 self.lockobj.release()
341 self.
clock += [rospy.Time.now()]
342 if 30 <= len(self.
clock):
343 fps = 30.0 / (self.
clock[29]-self.
clock[0]).to_sec()
345 debug_image,
'%.1f fps' % fps, (msg.width - 150, 40),
346 fontFace=cv2.FONT_HERSHEY_SIMPLEX, fontScale=1,
348 thickness=2, lineType=16)
351 debug_msg = self.bridge.cv2_to_imgmsg(debug_image,
"bgr8")
352 self.debug_pub.publish(debug_msg)
356 if __name__==
'__main__':
357 rospy.init_node(
'match_template')
362 rospy.loginfo(
"reference image %s, size %s", obj.reference_image_sub.resolved_name, obj.default_template_size)
363 rospy.loginfo(
" search_image %s, size %s", obj.search_image_sub.resolved_name, obj.default_search_size)
def set_reference_point_callback(self, msg)
def MinLock2nd(arr, ex_size)
def reconfigure(self, config, level)
def set_search_callback(self, msg)
def ref_image_callback(self, msg)
def set_reference(self, rect)
def ser_image_callback(self, msg)
def _MinMaxLock2nd(arr, ex_size, is_min)
def set_template(self, ref_id='', ref_image=None, ref_rect=None, ser_frame=None, ser_rect=None, color=None, method=None)
def MaxLock2nd(arr, ex_size)