AI Watch A1
Multi-person 3D skeleton detection using Intel RealSense and OpenPose with Kafka support.
Skeleton.cpp
Go to the documentation of this file.
1//
2// Skeleton.cpp
3// AI Watch A1
4//
5// Created by Denny Caruso on 17/07/22.
6//
7
8// License: Apache 2.0. See LICENSE file in root directory.
9// Copyright(c) 2022. All Rights Reserved.
10
11#include "Skeleton.hpp"
12
13
14
15void Skeleton::setRGB_Image (cv::Mat & myImage) {
16 this->rgb_Image = myImage;
17}
18
19void Skeleton::setDistance_Image (cv::Mat & myImage) {
20 this->distance_Image = myImage;
21}
22
23void Skeleton::setSkeleton_Image (cv::Mat & myImage) {
24 this->skeleton_Image = myImage;
25}
26
27void Skeleton::setBodyKeyPoints (std::vector <BodyKeyPoint> & bodyKeyPoints) {
28 this->bodyKeyPoints = bodyKeyPoints;
29}
30
31void Skeleton::setBodyKeyPointsMap (std::vector <bool> & bodyKeyPointsMap) {
32 this->bodyKeyPointsMap = bodyKeyPointsMap;
33}
34
35void Skeleton::setSkeletonData (Json::Value skeletonData) {
36 this->skeletonData = skeletonData;
37}
38
39void Skeleton::setSkeletonPoints3D_RS (std::vector <Point3D *> skeletonPoints3D_RS) {
40 this->skeletonPoints3D_RS = skeletonPoints3D_RS;
41}
42
43void Skeleton::setSkeletonPoints3D (std::vector <Point3D *> * skeletonPoints3D) {
44 this->skeletonPoints3D = skeletonPoints3D;
45}
46
47void Skeleton::setConsistency (float consistency) {
48 this->consistency = consistency;
49}
50
51
52
54 return this->rgb_Image;
55}
56
58 return this->distance_Image;
59}
60
62 return this->skeleton_Image;
63}
64
65std::vector <BodyKeyPoint> Skeleton::getBodyKeyPoints (void) {
66 return this->bodyKeyPoints;
67}
68
69std::vector <bool> Skeleton::getBodyKeyPointsMap (void) {
70 return this->bodyKeyPointsMap;
71}
72
73Json::Value Skeleton::getSkeletonData (void) {
74 return this->skeletonData;
75}
76
77// Don't change following method, otherwise error
79 int j = 0;
80 FacadeSingleton * facadeSingletonInstance = FacadeSingleton::getInstance();
81 if (facadeSingletonInstance == nullptr) CV_Error(FACADE_SINGLETON_NULLPTR_ERROR, FACADE_SINGLETON_NULLPTR_SCOPE);
82 OutputManagerJSON * outputManagerJSON = (OutputManagerJSON *) facadeSingletonInstance->getOutputManager();
83 for (Json::Value::ArrayIndex i = 0; i < skeletonData.size(); i++) {
85 outputManagerJSON->getValueAt((unsigned int) i, getSkeletonData()).asInt(),
86 outputManagerJSON->getValueAt((unsigned int) i + 1, getSkeletonData()).asInt(),
87 outputManagerJSON->getValueAt((unsigned int) i + 2, getSkeletonData()).asFloat())
88 );
89
90 bodyKeyPointsMap.push_back(bodyKeyPoints.at(j).getX() > 0 && bodyKeyPoints.at(j).getY() > 0 && bodyKeyPoints.at(j).getConfidence() > 0.00);
91 setConsistency(getConsistency() + bodyKeyPoints.at(j).getConfidence());
92 i += 2;
93 j += 1;
94 }
95
97}
98
100 for (unsigned char i = 0; i < getBodyKeyPoints().size(); i++) {
101 if (i >= openPoseBodyKeyPointsNumber || (!getBodyKeyPointsMap().at(i))) continue;
102 drawCircle(cv::Point(getBodyKeyPoints().at(i).getX(), getBodyKeyPoints().at(i).getY()));
103
104 switch (i) {
105 case Nose ... RElbow:
106 case LShoulder ... LElbow:
107 case MidHip ... RKnee:
108 case LHip ... LKnee:
109 case LBigToe:
110 case RBigToe:
111 drawLine(i, i + 1);
112 break;
113 default:
114 break;
115 }
116 }
117
129}
130
131void Skeleton::drawLine (unsigned char start, unsigned char end) {
132 if (getBodyKeyPointsMap().at(start) && getBodyKeyPointsMap().at(end)) {
133 cv::line(getRGB_Image(), cv::Point(getBodyKeyPoints().at(start).getX(), getBodyKeyPoints().at(start).getY()),
134 cv::Point(getBodyKeyPoints().at(end).getX(), getBodyKeyPoints().at(end).getY()), cv::Scalar(0, 255, 0), 3, cv::LINE_8, 0);
135 cv::line(getSkeleton_Image(), cv::Point(getBodyKeyPoints().at(start).getX(), getBodyKeyPoints().at(start).getY()),
136 cv::Point(getBodyKeyPoints().at(end).getX(), getBodyKeyPoints().at(end).getY()), cv::Scalar(0, 255, 0), 3, cv::LINE_8, 0); // remove in future
137 }
138}
139
140void Skeleton::drawCircle (cv::Point center) {
141 cv::circle(getRGB_Image(), center, 4, cv::Scalar(0, 0, 255), 8, cv::LINE_8, 0);
142 cv::circle(getSkeleton_Image(), center, 4, cv::Scalar(0, 0, 255), 8, cv::LINE_8, 0); // remove
143}
144
146 FacadeSingleton * facadeSingletonInstance = FacadeSingleton::getInstance();
147 if (facadeSingletonInstance == nullptr) CV_Error(FACADE_SINGLETON_NULLPTR_ERROR, FACADE_SINGLETON_NULLPTR_SCOPE);
148 struct rs2_intrinsics color_intrin = facadeSingletonInstance->getCameraManager()->get_color_intrin();
149 for (unsigned char i = 0; i < getBodyKeyPoints().size(); i++) {
150 float * pixel = new (std::nothrow) float [2], * point = new (std::nothrow) float [3], distance = 0;
151 if (!pixel || !point) CV_Error(NEW_ALLOC_ERROR, NEW_ALLOC_SCOPE);
152
153 if (!getBodyKeyPointsMap().at(i)) {
154 point[0] = point[1] = point[2] = pixel[0] = pixel[1] = 0;
155 } else {
156 pixel[0] = getBodyKeyPoints().at(i).getX();
157 pixel[1] = getBodyKeyPoints().at(i).getY();
158 distance = getDistance_Image().at<float>(pixel[1], pixel[0]);
159 rs2_deproject_pixel_to_point(point, & color_intrin, pixel, distance);
160 }
161
162 Point3D * point3D = new Point3D(point[0], point[1], point[2], new BodyKeyPoint(0, 0, getBodyKeyPoints().at(i).getConfidence()));
163 skeletonPoints3D_RS.push_back(point3D);
164 delete [] pixel;
165 delete [] point;
166 }
167}
168
170 for (unsigned char i = 0; i < getSkeletonPoints3D()->size(); i++) {
171 std::stringstream labelTextX, labelTextY, labelTextZ, labelTextConfidence;
172 labelTextX << getSkeletonPoints3D()->at(i)->getX();
173 labelTextY << getSkeletonPoints3D()->at(i)->getY();
174 labelTextZ << getSkeletonPoints3D()->at(i)->getZ();
175 labelTextConfidence << ((BodyKeyPoint *) getSkeletonPoints3D()->at(i)->getDecorated())->getConfidence();
176
177 if (i == 0 || i == 12 || i == 14) {
178 cv::putText(getRGB_Image(), labelTextX.str(), cv::Point(getBodyKeyPoints().at(i).getX() + 10, getBodyKeyPoints().at(i).getY() + 10), cv::FONT_HERSHEY_SIMPLEX, 0.4, cv::Scalar(255, 0, 0), 1, cv::LINE_8);
179 cv::putText(getRGB_Image(), labelTextY.str(), cv::Point(getBodyKeyPoints().at(i).getX() + 10, getBodyKeyPoints().at(i).getY() + 25), cv::FONT_HERSHEY_SIMPLEX, 0.4, cv::Scalar(255, 0, 0), 1, cv::LINE_8);
180 cv::putText(getRGB_Image(), labelTextZ.str(), cv::Point(getBodyKeyPoints().at(i).getX() + 10, getBodyKeyPoints().at(i).getY() + 40), cv::FONT_HERSHEY_SIMPLEX, 0.4, cv::Scalar(255, 0, 0), 1, cv::LINE_8);
181 }
182 }
183}
184
185
186
187Skeleton::Skeleton (cv::Mat & rgbImage, cv::Mat & dImage, cv::Mat & skeleton_Image, Json::Value skeletonData) {
188 setRGB_Image(rgbImage);
189 setDistance_Image(dImage);
192 setConsistency(0.0);
193}
194
196 for (auto & point: * getSkeletonPoints3D()) delete point;
197 for (auto & point: getSkeletonPoints3D_RS()) delete point;
198 getSkeletonPoints3D()->clear();
199 if (getSkeletonPoints3D() != nullptr) delete getSkeletonPoints3D();
200 getSkeletonPoints3D_RS().clear();
201}
202
207 FacadeSingleton * facadeSingletonInstance = FacadeSingleton::getInstance();
208 if (facadeSingletonInstance == nullptr) CV_Error(FACADE_SINGLETON_NULLPTR_ERROR, FACADE_SINGLETON_NULLPTR_SCOPE);
209 // xOrigin and zOrigin parameters are inverted as the built Unity world requires.
212}
213
214std::vector <Point3D *> Skeleton::getSkeletonPoints3D_RS (void) {
215 return this->skeletonPoints3D_RS;
216}
217
218std::vector <Point3D *> * Skeleton::getSkeletonPoints3D (void) {
219 return this->skeletonPoints3D;
220}
221
223 return this->consistency;
224}
static const float zOriginUnity
Definition: Room.hpp:30
static const float xOriginUnity
Definition: Room.hpp:29
@ LHeel
Definition: Skeleton.hpp:26
@ LEar
Definition: Skeleton.hpp:25
@ LAnkle
Definition: Skeleton.hpp:24
@ REar
Definition: Skeleton.hpp:25
@ Nose
Definition: Skeleton.hpp:22
@ RHeel
Definition: Skeleton.hpp:26
@ MidHip
Definition: Skeleton.hpp:23
@ RElbow
Definition: Skeleton.hpp:22
@ LBigToe
Definition: Skeleton.hpp:25
@ LKnee
Definition: Skeleton.hpp:24
@ Neck
Definition: Skeleton.hpp:22
@ LHip
Definition: Skeleton.hpp:24
@ REye
Definition: Skeleton.hpp:25
@ RAnkle
Definition: Skeleton.hpp:24
@ RKnee
Definition: Skeleton.hpp:24
@ LElbow
Definition: Skeleton.hpp:23
@ LEye
Definition: Skeleton.hpp:25
@ LShoulder
Definition: Skeleton.hpp:23
@ RBigToe
Definition: Skeleton.hpp:26
BodyKeyPoint class is used for body keypoint creations and manipulations.
virtual std::vector< Point3D * > * mapToMeters(std::vector< Point3D * > pointsToMap, std::vector< bool > bodyKeyPointsMap, float xOrigin, float zOrigin)
This method requires pointers' Point3D's vector, the related vector map, and the original coordinates...
FacadeSingleton class is used as a single access point to a simplified interface.
CoordinateMappingManager * getCoordinateMappingManager(void)
Get the CoordinateMappingManager pointer.
OutputManager * getOutputManager(void)
Get the OutputManager pointer.
RealSenseManager * getCameraManager(void)
Get the RealSenseManager pointer.
static FacadeSingleton * getInstance(void)
Get the unique class instance. This methods should be called in the following scenario: when we just ...
OutputManagerJSON class is a class that abstracts final JSON output-producing operations.
Json::Value getValueAt(std::string key, Json::Value currentJSON)
Utility method to get the value at a given key in a given JSON node.
Point3D class is used for Point3D creations and manipulations.
Definition: Point3D.hpp:23
struct rs2_intrinsics & get_color_intrin(void)
Get the color intrinsics object.
cv::Mat getRGB_Image(void)
Get the RGB Image object.
Definition: Skeleton.cpp:53
void setSkeletonPoints3D_RS(std::vector< Point3D * > skeletonPoints3D_RS)
Set the SkeletonPoints3D RS vector.
Definition: Skeleton.cpp:39
std::vector< BodyKeyPoint > getBodyKeyPoints(void)
Get the Body Key Points vector.
Definition: Skeleton.cpp:65
std::vector< BodyKeyPoint > bodyKeyPoints
A vector that contains each body joint retrieved from OpenPose.
Definition: Skeleton.hpp:55
float getConsistency(void)
Get the Consistency float value.
Definition: Skeleton.cpp:222
void setSkeleton_Image(cv::Mat &skeleton_Image)
Set the Skeleton-only Image object.
Definition: Skeleton.cpp:23
cv::Mat skeleton_Image
A frame that contains only skeleton information such as green legs and red dots, representing connect...
Definition: Skeleton.hpp:50
void setRGB_Image(cv::Mat &rgbImage)
Set the RGB Image object.
Definition: Skeleton.cpp:15
void setBodyKeyPoints(std::vector< BodyKeyPoint > &bodyKeyPoints)
Set the Body Key Points vector.
Definition: Skeleton.cpp:27
~Skeleton(void)
Destroy the Skeleton object.
Definition: Skeleton.cpp:195
std::vector< Point3D * > * getSkeletonPoints3D(void)
Get the Skeleton Points3D vector's pointer.
Definition: Skeleton.cpp:218
void setBodyKeyPointsMap(std::vector< bool > &bodyKeyPointsMap)
Set the Body Key Points Map vector.
Definition: Skeleton.cpp:31
void setDistance_Image(cv::Mat &distanceImage)
Set the Distance Image object.
Definition: Skeleton.cpp:19
void drawCircle(cv::Point center)
Draw a circle at the specified point as a parameter.
Definition: Skeleton.cpp:140
void setConsistency(float consistency)
Set the Consistency float value.
Definition: Skeleton.cpp:47
std::vector< bool > bodyKeyPointsMap
A vector that contains for each body joint retrieved from OpenPose a corresponding boolean that means...
Definition: Skeleton.hpp:62
std::vector< bool > getBodyKeyPointsMap(void)
Get the BodyKeyPoints Map vector.
Definition: Skeleton.cpp:69
void calcBodyEdges(void)
Calculate Skeleton and invoke methods to draw it on the image according to OpenPose skeleton structur...
Definition: Skeleton.cpp:99
Json::Value getSkeletonData(void)
Get the Skeleton Data JSON object.
Definition: Skeleton.cpp:73
void deprojectSkeletonPoints3D(void)
Deprojection operation takes a 2D pixel location on a stream's images, as well as a depth,...
Definition: Skeleton.cpp:145
void writeCoordinates(void)
Write specific joint points' coordinates on the RGB image.
Definition: Skeleton.cpp:169
std::vector< Point3D * > skeletonPoints3D_RS
A vector that contains a set of pointers to Point3D. These points have coordinates whose domain is de...
Definition: Skeleton.hpp:85
void calcBodyKeypoints(void)
Retrieve BodyKeyPoints vector and the BodyKeyPoints Map bool vector from OpenPose output,...
Definition: Skeleton.cpp:78
std::vector< Point3D * > * skeletonPoints3D
A pointer to a vector that contains a set of pointers to Point3D. These points have coordinates in wh...
Definition: Skeleton.hpp:93
Skeleton(cv::Mat &rgbImage, cv::Mat &distanceImage, cv::Mat &skeletonImage, Json::Value skeletonData)
Construct a new Skeleton object.
Definition: Skeleton.cpp:187
cv::Mat rgb_Image
RGB frame related to the frame in which the skeleton may appears.
Definition: Skeleton.hpp:42
void setSkeletonPoints3D(std::vector< Point3D * > *skeletonPoints3D)
Set the Skeleton Points3D pointer to vector.
Definition: Skeleton.cpp:43
Json::Value skeletonData
Represents a Skeleton JSON value. This class is a discriminated union wrapper that can represent a:
Definition: Skeleton.hpp:78
void drawLine(unsigned char start, unsigned char end)
Draw a line that starts from a point and ends at another point. The points are specified as unsigned ...
Definition: Skeleton.cpp:131
void setSkeletonData(Json::Value skeletonData)
Set the Skeleton Data JSON object.
Definition: Skeleton.cpp:35
cv::Mat distance_Image
Distance frame related to the frame in which the skeleton may appears.
Definition: Skeleton.hpp:46
float consistency
Consistency is a value that represents how accurate is the OpenPose detection for this skeleton....
Definition: Skeleton.hpp:99
void generateSkeleton(void)
A high-level method that abstracts all the internal structure and operations of the Skeleton class....
Definition: Skeleton.cpp:203
cv::Mat getSkeleton_Image(void)
Get the Skeleton-only Image object.
Definition: Skeleton.cpp:61
cv::Mat getDistance_Image(void)
Get the Distance Image object.
Definition: Skeleton.cpp:57
std::vector< Point3D * > getSkeletonPoints3D_RS(void)
Get the SkeletonPoints3D RS vector.
Definition: Skeleton.cpp:214
static const short int FACADE_SINGLETON_NULLPTR_ERROR
Definition: constants.hpp:32
static const short int NEW_ALLOC_ERROR
Definition: constants.hpp:47
static const char * FACADE_SINGLETON_NULLPTR_SCOPE
Definition: constants.hpp:33
static const short int openPoseBodyKeyPointsNumber
Definition: constants.hpp:68
static const char * NEW_ALLOC_SCOPE
Definition: constants.hpp:48