non_maximum_suppression.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 
3 from jsk_perception.srv import NonMaximumSuppression
4 from jsk_perception.srv import NonMaximumSuppressionResponse
5 from jsk_recognition_msgs.msg import Rect
6 from jsk_recognition_msgs.msg import RectArray
7 from jsk_topic_tools import ConnectionBasedTransport
8 import rospy
9 from std_msgs.msg import Int64
10 import numpy as np
11 
12 
13 class NonMaximumSuppressionServer(ConnectionBasedTransport):
14 
15  def __init__(self):
16  super(self.__class__, self).__init__()
17  self.thre = rospy.get_param('~threshold', 0.0)
18  self.pub_rects = self.advertise('~output', RectArray, queue_size=1)
19  self.pub_count = self.advertise('~output/count', Int64, queue_size=1)
20  self.srv_server = rospy.Service(
21  'non_maximum_suppression',
22  NonMaximumSuppression, self._req_cb)
23 
24  def subscribe(self):
25  self.sub = rospy.Subscriber(
26  '~input', RectArray, self._msg_cb, queue_size=1)
27 
28  def unsubscribe(self):
29  self.sub.unregister()
30 
31  def _msg_cb(self, msg):
32  rects, count = self.non_max_suppression_handler(msg.rects, self.thre)
33 
34  rects_msg = RectArray()
35  rects_msg.header = msg.header
36  rects_msg.rects = rects
37  self.pub_rects.publish(rects_msg)
38 
39  count_msg = Int64()
40  count_msg.data = count
41  self.pub_count.publish(count_msg)
42 
43  def _req_cb(self, req):
44  rects, count = self.non_max_suppression_handler(
45  req.rect, req.threshold)
46  return NonMaximumSuppressionResponse(rects, count)
47 
48  # Malisiewicz et al.
49  def non_max_suppression_fast(self, boxes, overlapThresh):
50  if len(boxes) == 0:
51  return []
52  if boxes.dtype.kind == "i":
53  boxes = boxes.astype("float")
54  pick = []
55  x1 = boxes[:,0]
56  y1 = boxes[:,1]
57  x2 = boxes[:,2]
58  y2 = boxes[:,3]
59  area = (x2 - x1 + 1) * (y2 - y1 + 1)
60  idxs = np.argsort(y2)
61  while len(idxs) > 0:
62  last = len(idxs) - 1
63  i = idxs[last]
64  pick.append(i)
65  xx1 = np.maximum(x1[i], x1[idxs[:last]])
66  yy1 = np.maximum(y1[i], y1[idxs[:last]])
67  xx2 = np.minimum(x2[i], x2[idxs[:last]])
68  yy2 = np.minimum(y2[i], y2[idxs[:last]])
69  w = np.maximum(0, xx2 - xx1 + 1)
70  h = np.maximum(0, yy2 - yy1 + 1)
71  overlap = (w * h) / area[idxs[:last]]
72  idxs = np.delete(idxs, np.concatenate(([last],
73  np.where(overlap > overlapThresh)[0])))
74  return boxes[pick].astype("int")
75 
76  def non_max_suppression_equator(self, rect, threshold):
77  _box = []
78  for box in rect:
79  x1 = box.x
80  x2 = x1 + box.width
81  y1 = box.y
82  y2 = y1 + box.height
83  r = (x1, y1, x2, y2)
84  _box.append(r)
85  bbox = np.array(_box)
86  return self.non_max_suppression_fast(bbox, threshold)
87 
88  def non_max_suppression_handler(self, rects, threshold):
89  pick = self.non_max_suppression_equator(rects, threshold)
90  bbox = []
91  i = 0
92  while i < len(pick):
93  bx = pick[i][0]
94  by = pick[i][1]
95  bw = pick[i][2] - bx
96  bh = pick[i][3] - by
97  bbox.append(Rect(bx, by, bw, bh))
98  #print Rect(bx, by, bw, bh)
99  i+=1
100  return bbox, len(pick)
101 
102 
103 if __name__ == "__main__":
104  rospy.init_node('non_maximum_suppression_server')
106  rospy.spin()


jsk_perception
Author(s): Manabu Saito, Ryohei Ueda
autogenerated on Mon May 3 2021 03:03:27