-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathhuman_detection.py
More file actions
executable file
·130 lines (104 loc) · 3.77 KB
/
Copy pathhuman_detection.py
File metadata and controls
executable file
·130 lines (104 loc) · 3.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#!/usr/bin/env python2
"""
Human Detector
A test version of the human detector, integrating it into ROS
"""
import os
import cv2
import time
import argparse
import numpy as np
from imutils.object_detection import non_max_suppression
from collections import deque
# ROS
import rospy
from sensor_msgs.msg import Image
from cv_bridge import CvBridge, CvBridgeError
from darknet_ros_msgs.msg import BoundingBoxes, BoundingBox
def msg(image, boxes):
"""
Create the Darknet BoundingBox[es] messages
"""
msg = BoundingBoxes()
msg.header = image.header
for (x, y, w, h) in boxes:
detection = BoundingBox()
detection.Class = "human"
detection.probability = 1 # Not really...
detection.xmin = x
detection.ymin = y
detection.xmax = x+w
detection.ymax = y+h
msg.boundingBoxes.append(detection)
return msg
class HumanDetectorNode:
"""
Subscribe to the images and publish human detectionresults with ROS
Usage:
node = HumanDetectorNode()
rospy.spin()
"""
def __init__(self, averageFPS=60):
# We'll publish the results
self.pub = rospy.Publisher('human_detector', BoundingBoxes,
queue_size=10)
# Name this node
rospy.init_node('human_detector')
# Parameters
camera_namespace = rospy.get_param("~camera_namespace",
"/camera/rgb/image_rect_color")
# Not sure if there are any other parameters we really want, e.g.
#threshold = rospy.get_param("~scale", 1.1)
# For processing images
self.bridge = CvBridge()
# For computing average FPS over so many frames
self.fps = deque(maxlen=averageFPS)
# Only create the subscriber after we're done loading everything
self.sub = rospy.Subscriber(camera_namespace, Image, self.rgb_callback,
queue_size=1, buff_size=2**24)
# initialize the HOG constructor
self.hog = cv2.HOGDescriptor()
# use the default pre trained people detector algorithm for HOG + SVM
self.hog.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector())
def avgFPS(self):
"""
Return average FPS over last so many frames (specified in constructor)
"""
return sum(list(self.fps))/len(self.fps)
def rgb_callback(self, data):
fps = time.time()
error = ""
try:
image_np = self.bridge.imgmsg_to_cv2(data, "bgr8")
boxes = self.processImage(image_np)
self.pub.publish(msg(data, boxes))
except CvBridgeError as e:
rospy.logerr(e)
error = "(error)"
# Print FPS
fps = 1/(time.time() - fps)
self.fps.append(fps)
print "Human Detection FPS", "{:<5}".format("%.2f"%fps), \
"Average", "{:<5}".format("%.2f"%self.avgFPS()), error
def processImage(self, frame):
# convert the RGB image to grayscale
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# detect people in each frame
rects, weights = self.hog.detectMultiScale(gray, winStride = (4, 4), padding = (16, 16), scale = 1.1)
# apply non maxima supression
# to make one bounding box over each human
# diminish the effect of overlapping bounding boxes
rects = np.array([[x, y, x+w, y+h] for (x, y, w, h) in rects])
pick = non_max_suppression(rects, probs = None, overlapThresh = 0.65)
# create bounding boxes over the detected humans
for (x, y, w, h) in pick:
cv2.rectangle(frame, (x, y), (w, h), (0, 255, 0), 2)
coordinates = [(x, y), (x+w, y), (x+w, y+h), (x, y+h)]
print "No of people detected {}".format(len(pick))
return pick
if __name__ == '__main__':
try:
node = HumanDetectorNode()
rospy.spin()
except rospy.ROSInterruptException:
pass