Skip to content

Commit 11b9f66

Browse files
committed
Initial Folder Creation
1 parent 749f43a commit 11b9f66

File tree

9 files changed

+708
-0
lines changed

9 files changed

+708
-0
lines changed

people_tracking_v2/CMakeLists.txt

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
cmake_minimum_required(VERSION 3.0.2)
2+
project(people_tracking)
3+
4+
find_package(catkin REQUIRED COMPONENTS
5+
message_generation
6+
people_recognition_msgs
7+
rgbd
8+
rgbd_image_buffer
9+
roscpp
10+
sensor_msgs
11+
visualization_msgs
12+
)
13+
14+
catkin_python_setup()
15+
16+
add_message_files(
17+
FILES
18+
FaceTarget.msg
19+
ColourTarget.msg
20+
DetectPerson.msg
21+
DetectedPerson.msg
22+
)
23+
24+
add_service_files(
25+
FILES
26+
Depth.srv
27+
)
28+
29+
generate_messages(
30+
DEPENDENCIES
31+
sensor_msgs
32+
)
33+
34+
catkin_package(
35+
CATKIN_DEPENDS message_runtime sensor_msgs
36+
)
37+
38+
include_directories(
39+
# include
40+
SYSTEM
41+
${catkin_INCLUDE_DIRS}
42+
)
43+
44+
add_executable(people_tracker test/experiments/people_tracker.cpp)
45+
target_link_libraries(people_tracker ${catkin_LIBRARIES})
46+
47+
install(
48+
TARGETS people_tracker
49+
DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
50+
)
51+
52+
if (CATKIN_ENABLE_TESTING)
53+
find_package(catkin_lint_cmake REQUIRED)
54+
catkin_add_catkin_lint_test(-W2)
55+
endif()

people_tracking_v2/package.xml

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?xml version="1.0"?>
2+
<?xml-model
3+
href="http://download.ros.org/schema/package_format3.xsd"
4+
schematypens="http://www.w3.org/2001/XMLSchema"?>
5+
<package format="3">
6+
<name>people_tracking</name>
7+
<version>0.0.1</version>
8+
<description>The people_tracking package</description>
9+
10+
<maintainer email="[email protected]">Arpit Aggarwal</maintainer>
11+
12+
<license>MIT</license>
13+
14+
<url type="bugtracker">https://github.com/tue-robotics/people_recognition/issues</url>
15+
<url type="repository">https://github.com/tue-robotics/people_recognition/tree/master/people_recognition_2d</url>
16+
17+
<author email="[email protected]">Arpit Aggarwal</author>
18+
19+
<buildtool_depend>catkin</buildtool_depend>
20+
21+
<buildtool_depend>python3-setuptools</buildtool_depend>
22+
23+
<depend>sensor_msgs</depend>
24+
25+
<build_depend>people_recognition_msgs</build_depend>
26+
<build_depend>rgbd</build_depend>
27+
<build_depend>rgbd_image_buffer</build_depend>
28+
<build_depend>roscpp</build_depend>
29+
<build_depend>visualization_msgs</build_depend>
30+
31+
<build_depend>message_generation</build_depend>
32+
33+
<exec_depend>cv_bridge</exec_depend>
34+
<exec_depend>image_recognition_util</exec_depend>
35+
<exec_depend>message_runtime</exec_depend>
36+
<exec_depend>people_recognition_msgs</exec_depend>
37+
<exec_depend>rgbd</exec_depend>
38+
<exec_depend>rgbd_image_buffer</exec_depend>
39+
<exec_depend>roscpp</exec_depend>
40+
<exec_depend>rospy</exec_depend>
41+
<exec_depend>std_msgs</exec_depend>
42+
<exec_depend>visualization_msgs</exec_depend>
43+
44+
<test_depend>catkin_lint_cmake</test_depend>
45+
46+
<doc_depend>python3-sphinx</doc_depend>
47+
<doc_depend>python-sphinx-autoapi-pip</doc_depend>
48+
<doc_depend>python-sphinx-rtd-theme-pip</doc_depend>
49+
<doc_depend>python3-yaml</doc_depend>
50+
51+
<export>
52+
<rosdoc config="rosdoc.yaml" />
53+
</export>
54+
55+
</package>

people_tracking_v2/rosdoc.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
- builder: sphinx
2+
sphinx_root_dir: docs
3+
name: Python API

people_tracking_v2/setup.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#!/usr/bin/env python
2+
3+
from setuptools import setup
4+
from catkin_pkg.python_setup import generate_distutils_setup
5+
6+
d = generate_distutils_setup(
7+
packages=['people_tracking'],
8+
package_dir={'': 'src'},
9+
)
10+
11+
setup(**d)
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import numpy as np
2+
from filterpy.kalman import MerweScaledSigmaPoints
3+
from filterpy.kalman import UnscentedKalmanFilter
4+
5+
6+
class UKF:
7+
def __init__(self):
8+
self.current_time = 0.0
9+
10+
dt = 0.1 # standard dt
11+
12+
# Create sigma points
13+
self.points = MerweScaledSigmaPoints(6, alpha=0.1, beta=2.0, kappa=-1)
14+
15+
self.kf = UnscentedKalmanFilter(dim_x=6, dim_z=3, dt=dt, fx=self.fx, hx=self.hx, points=self.points)
16+
17+
# Initial state: [x, vx, y, vy, z, vz]
18+
self.kf.x = np.array([1., 0, 300., 0, 1., 0])
19+
20+
# Initial uncertainty
21+
self.kf.P *= 1
22+
23+
# Measurement noise covariance matrix
24+
z_std = 0.2
25+
self.kf.R = np.diag([z_std ** 2, z_std ** 2, z_std ** 2])
26+
27+
# Process noise covariance matrix
28+
process_noise_stds = [3.0 ** 2, 0.1 ** 2, 3 ** 2, 0.1 ** 2, 0.1 ** 2, 0.1 ** 2]
29+
30+
self.kf.Q = np.diag(process_noise_stds)
31+
32+
def fx(self, x, dt):
33+
""" State transition function """
34+
F = np.array([[1, dt, 0, 0, 0, 0],
35+
[0, 1, 0, 0, 0, 0],
36+
[0, 0, 1, dt, 0, 0],
37+
[0, 0, 0, 1, 0, 0],
38+
[0, 0, 0, 0, 1, dt],
39+
[0, 0, 0, 0, 0, 1]], dtype=float)
40+
return np.dot(F, x)
41+
42+
def hx(self, x):
43+
""" Measurement function [x, y, z] """
44+
return np.array([x[0], x[2], x[4]])
45+
46+
def predict(self, time):
47+
""" Predict the next state """
48+
delta_t = time - self.current_time
49+
self.kf.predict(dt=delta_t)
50+
self.current_time = time
51+
52+
def update(self, time, z):
53+
""" Update filter with measurements z. """
54+
self.predict(time)
55+
self.kf.update(z)
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
#!/usr/bin/env python
2+
import rospy
3+
import cv2
4+
import numpy as np
5+
from cv_bridge import CvBridge
6+
from typing import List
7+
8+
from people_tracking.msg import ColourTarget, DetectedPerson
9+
from std_srvs.srv import Empty, EmptyResponse
10+
11+
NODE_NAME = 'HoC'
12+
TOPIC_PREFIX = '/hero/'
13+
14+
15+
class HOC:
16+
"""Class for the histogram of colour node."""
17+
def __init__(self) -> None:
18+
# ROS Initialize
19+
rospy.init_node(NODE_NAME, anonymous=True)
20+
self.subscriber = rospy.Subscriber(TOPIC_PREFIX + 'person_detections', DetectedPerson, self.callback,
21+
queue_size=1)
22+
self.publisher = rospy.Publisher(TOPIC_PREFIX + 'HoC', ColourTarget, queue_size=2)
23+
self.reset_service = rospy.Service(TOPIC_PREFIX + NODE_NAME + '/reset', Empty, self.reset)
24+
25+
# Variables
26+
self.HoC_detections = []
27+
self.last_batch_processed = 0
28+
29+
def reset(self, request):
30+
""" Reset all stored variables in Class to their default values."""
31+
self.HoC_detections = []
32+
self.last_batch_processed = 0
33+
return EmptyResponse()
34+
35+
@staticmethod
36+
def get_vector(image, bins: int = 32) -> List[float]:
37+
""" Return HSV-colour histogram vector from image.
38+
39+
:param image: cv2 image to turn into vector.
40+
:param bins: amount of bins in histogram.
41+
:return: HSV-colour histogram vector from image.
42+
"""
43+
hsv_image = cv2.cvtColor(image, cv2.COLOR_RGB2HSV) # Convert image to HSV
44+
45+
histograms = [cv2.calcHist([hsv_image], [i], None, [bins], [1, 256])
46+
for i in range(3)] # Get color histograms
47+
48+
histograms = [hist / hist.sum() for hist in histograms] # Normalize histograms
49+
50+
vector = np.concatenate(histograms, axis=0).reshape(-1) # Create colour histogram vector
51+
return vector.tolist()
52+
53+
def callback(self, data: DetectedPerson) -> None:
54+
""" Get the colour vectors for each detected person and publish this."""
55+
time = data.time
56+
nr_batch = data.nr_batch
57+
nr_persons = data.nr_persons
58+
detected_persons = data.detected_persons
59+
x_positions = data.x_positions
60+
y_positions = data.y_positions
61+
z_positions = data.z_positions
62+
63+
if nr_batch <= self.last_batch_processed:
64+
return
65+
if nr_persons < 1:
66+
return
67+
68+
bridge = CvBridge()
69+
colour_vectors = [self.get_vector(bridge.imgmsg_to_cv2(person, desired_encoding='passthrough')) for person in
70+
detected_persons]
71+
72+
msg = ColourTarget()
73+
msg.time = time
74+
msg.nr_batch = nr_batch
75+
msg.nr_persons = nr_persons
76+
msg.x_positions = x_positions
77+
msg.y_positions = y_positions
78+
msg.z_positions = z_positions
79+
msg.colour_vectors = [item for sublist in colour_vectors for item in sublist]
80+
81+
self.publisher.publish(msg)
82+
self.last_batch_processed = nr_batch
83+
84+
85+
if __name__ == '__main__':
86+
try:
87+
node_hoc = HOC()
88+
rospy.spin()
89+
except rospy.exceptions.ROSInterruptException:
90+
rospy.loginfo("Failed to launch HoC Node")
91+
pass

0 commit comments

Comments
 (0)