JeVois  1.22
JeVois Smart Embedded Machine Vision Toolkit
Share this page:
Loading...
Searching...
No Matches
PoseSkeleton.C
Go to the documentation of this file.
1// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2//
3// JeVois Smart Embedded Machine Vision Toolkit - Copyright (C) 2024 by Laurent Itti, the University of Southern
4// California (USC), and iLab at USC. See http://iLab.usc.edu and http://jevois.org for information about this project.
5//
6// This file is part of the JeVois Smart Embedded Machine Vision Toolkit. This program is free software; you can
7// redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software
8// Foundation, version 2. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
9// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
10// License for more details. You should have received a copy of the GNU General Public License along with this program;
11// if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
12//
13// Contact information: Laurent Itti - 3641 Watt Way, HNB-07A - Los Angeles, CA 90089-2520 - USA.
14// Tel: +1 213 740 3527 - itti@pollux.usc.edu - http://iLab.usc.edu - http://jevois.org
15// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
16/*! \file */
17
19#include <jevois/Debug/Log.H>
20#include <jevois/Util/Utils.H> // for absolutePath()
21#include <opencv2/core.hpp> // for cv::fileStorage()
22
23/*
24namespace jevois
25{
26 static PoseSkeletonDefinition const COCO17definition
27 {
28 17, // number of nodes
29 16, // number of links
30 { // node names
31 "nose", "left eye", "right eye", "left ear", "right ear", "left shoulder", "right shoulder", "left elbow",
32 "right elbow", "left wrist", "right wrist", "left hip", "right hip", "left knee", "right knee", "left ankle",
33 "right ankle"
34 },
35 { // node colors for display, 0xAABBGGRR
36 0xFFFF0000, 0xFFFF0000, 0xFFFF0000, 0xFFFF0000, 0xFFFF0000, 0xFFFF0000, 0xFFFF0000, 0xFFFF0000, 0xFFFF0000,
37 0xFFFF0000, 0xFFFF0000, 0xFFFF0000, 0xFFFF0000, 0xFFFF0000, 0xFFFF0000, 0xFFFF0000, 0xFFFF0000
38 },
39 { // link definitions, each is a pair of node IDs; this is mainly for display
40 {0, 1}, {1, 3}, {0, 2}, {2, 4}, {5, 6}, {5, 7}, {7, 9}, {6, 8}, {8, 10}, {5, 11}, {6, 12}, {11, 12},
41 {11, 13}, {12, 14}, {13, 15}, {14, 16}
42 },
43 { // link colors for display, 0xAABBGGRR
44 0xFFFF0000, 0xFFFF0000, 0xFFFF0000, 0xFFFF0000, 0xFFFF0000, 0xFFFF0000, 0xFFFF0000, 0xFFFF0000, 0xFFFF0000,
45 0xFFFF0000, 0xFFFF0000, 0xFFFF0000, 0xFFFF0000, 0xFFFF0000, 0xFFFF0000, 0xFFFF0000
46 }
47 };
48}
49*/
50 /*
51const std::vector<std::vector<unsigned int>> KPS_COLORS =
52 { {0, 255, 0}, {0, 255, 0}, {0, 255, 0}, {0, 255, 0},
53 {0, 255, 0}, {255, 128, 0}, {255, 128, 0}, {255, 128, 0},
54 {255, 128, 0}, {255, 128, 0}, {255, 128, 0}, {51, 153, 255},
55 {51, 153, 255},{51, 153, 255},{51, 153, 255},{51, 153, 255},
56 {51, 153, 255}};
57
58const std::vector<std::vector<unsigned int>> SKELETON =
59 { {16, 14}, {14, 12}, {17, 15}, {15, 13}, {12, 13}, {6, 12},
60 {7, 13}, {6, 7}, {6, 8}, {7, 9}, {8, 10}, {9, 11},
61 {2, 3}, {1, 2}, {1, 3}, {2, 4}, {3, 5}, {4, 6}, {5, 7} };
62
63const std::vector<std::vector<unsigned int>> LIMB_COLORS =
64 { {51, 153, 255}, {51, 153, 255}, {51, 153, 255},
65 {51, 153, 255}, {255, 51, 255}, {255, 51, 255},
66 {255, 51, 255}, {255, 128, 0}, {255, 128, 0},
67 {255, 128, 0}, {255, 128, 0}, {255, 128, 0},
68 {0, 255, 0}, {0, 255, 0}, {0, 255, 0},
69 {0, 255, 0}, {0, 255, 0}, {0, 255, 0},
70 {0, 255, 0} };
71 */
72
73
74// ####################################################################################################
76{
77 std::string const fname = jevois::absolutePath(JEVOIS_SHARE_PATH, filename);
78 cv::FileStorage fs(fname, cv::FileStorage::READ);
79 if (fs.isOpened() == false) LFATAL("Cannot read " << fname);
80
81 cv::FileNode node; cv::FileNodeIterator it;
82 try
83 {
84 node = fs["nodeNames"];
85 if (node.isSeq() == false) LTHROW("Required nodeNames array missing or not an array");
86 for (it = node.begin(); it != node.end(); ++it)
87 { cv::FileNode item = *it; nodeNames.emplace_back((std::string)(item)); }
88
89 node = fs["nodeColors"];
90 if (node.isSeq() == false) LTHROW("Required nodeColors array missing or not an array");
91 for (it = node.begin(); it != node.end(); ++it)
92 { cv::FileNode item = *it; nodeColors.emplace_back(std::stoul((std::string)(item), nullptr, 0)); }
93
94 if (nodeNames.size() != nodeColors.size())
95 LTHROW("Found " << nodeNames.size() << " node names vs. " << nodeColors.size() << " node colors");
96
97 int nn = nodeNames.size();
98 node = fs["links"];
99 if (node.isSeq() == false) LTHROW("Required links array missing or not an array");
100 for (it = node.begin(); it != node.end(); ++it)
101 {
102 cv::FileNode item = *it; cv::Point p; item >> p;
103 if (p.x < 0 || p.x >= nn || p.y < 0 || p.y >= nn)
104 LTHROW("Link [" << p.x << ", " << p.y <<"] node ID out of range [0 .. " << nn-1 << ']');
105 links.emplace_back(std::make_pair<unsigned int, unsigned int>(p.x, p.y));
106 }
107
108 node = fs["linkColors"];
109 if (node.isSeq() == false) LTHROW("Required linkColors array missing or not an array");
110 for (it = node.begin(); it != node.end(); ++it)
111 { cv::FileNode item = *it; linkColors.emplace_back(std::stoul((std::string)(item), nullptr, 0)); }
112
113 if (links.size() != linkColors.size())
114 LTHROW("Found " << links.size() << " links vs. " << linkColors.size() << " link colors");
115 }
116 catch (...)
117 { LFATAL("Error parsing [" << fname << "], node [" << node.name() << "]:" << jevois::warnAndIgnoreException()); }
118
119 LINFO("Loaded Pose Skeleton definition with " << nodeNames.size() << " nodes, " << links.size() << " links.");
120}
121
122// ####################################################################################################
123jevois::PoseSkeleton::PoseSkeleton(std::shared_ptr<jevois::PoseSkeletonDefinition> def) :
124 nodes(), links(), psd(def)
125{
126 // Internal checks for malformed definition:
127 if (psd->nodeNames.size() != psd->nodeColors.size() || psd->links.size() != psd->linkColors.size())
128 LFATAL("Internal error - malformed skeleton definition");
129}
130
131// ####################################################################################################
133{ return psd->nodeNames.size(); }
134
135// ####################################################################################################
137{ return psd->links.size(); }
138
139// ####################################################################################################
140char const * jevois::PoseSkeleton::nodeName(unsigned int id) const
141{
142 if (id < psd->nodeNames.size()) return psd->nodeNames[id].c_str();
143 LFATAL("Given ID " << id << " too large for skeleton with " << psd->nodeNames.size() << " nodes");
144}
145
146// ####################################################################################################
147unsigned int jevois::PoseSkeleton::nodeColor(unsigned int id) const
148{
149 if (id < psd->nodeNames.size()) return psd->nodeColors[id];
150 LFATAL("Given ID " << id << " too large for skeleton with " << psd->nodeNames.size() << " nodes");
151}
152
153// ####################################################################################################
154unsigned int jevois::PoseSkeleton::linkColor(unsigned int id) const
155{
156 if (id < psd->links.size()) return psd->linkColors[id];
157 LFATAL("Given ID " << id << " too large for skeleton with " << psd->links.size() << " links");
158}
159
160// ####################################################################################################
161std::vector<std::pair<unsigned int, unsigned int>> const & jevois::PoseSkeleton::linkDefinitions() const
162{ return psd->links; }
#define JEVOIS_SHARE_PATH
Base path for shared files (e.g., neural network weights, etc)
Definition Config.H:82
#define LTHROW(msg)
Definition Log.H:251
#define LFATAL(msg)
Convenience macro for users to print out console or syslog messages, FATAL level.
Definition Log.H:230
std::string warnAndIgnoreException(std::string const &prefix="")
Convenience function to catch an exception, issue some LERROR (depending on type),...
Definition Log.C:236
#define LINFO(msg)
Convenience macro for users to print out console or syslog messages, INFO level.
Definition Log.H:194
std::filesystem::path absolutePath(std::filesystem::path const &root, std::filesystem::path const &path)
Compute an absolute path from two paths.
Definition Utils.C:386
std::vector< unsigned int > nodeColors
colors of nodes (size nn)
std::vector< std::pair< unsigned int, unsigned int > > links
link definitions, each is pair of node IDs (size nl)
PoseSkeletonDefinition(std::string const &filename)
Create from a YAML file.
std::vector< std::string > nodeNames
names of nodes (size nn)
std::vector< unsigned int > linkColors
link colors (size nl)
unsigned int linkColor(unsigned int id) const
Get draw color of a node from its ID, as 0xAABBGGRR (note: returned unsigned int is the same as ImU32...
PoseSkeleton(std::shared_ptr< PoseSkeletonDefinition > def)
Constructor from a previously loaded definition.
unsigned int numSkeletonNodes() const
Get the total number of nodes in the skeleton. Node ID is from 0 to that total - 1.
std::vector< std::pair< unsigned int, unsigned int > > const & linkDefinitions() const
Get a const ref to our link definitions, useful to iterate over. Each link is <node_id_1,...
unsigned int numSkeletonLinks() const
Get the total number of links in the skeleton. Link ID is from 0 to that total - 1.
unsigned int nodeColor(unsigned int id) const
Get draw color of a node from its ID, as 0xAABBGGRR (note: returned unsigned int is the same as ImU32...
char const * nodeName(unsigned int id) const
Get the name of a node from its ID.