OpenPoseEstimationComponent.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of ArmarX.
3  *
4  * ArmarX is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation.
7  *
8  * ArmarX is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program. If not, see <http://www.gnu.org/licenses/>.
15  *
16  * @package VisionX::ArmarXObjects::OpenPoseEstimation
17  * @author Stefan Reither ( stef dot reither at web dot de )
18  * @date 2018
19  * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
20  * GNU General Public License
21  */
22 
24 
26 #include <SimoxUtility/algorithm/string.h>
29 
30 namespace armarx
31 {
33  {
34  def->topic(listener2DPrx, "OpenPoseEstimation2D", "OpenPoseEstimation2DTopicName");
35 
36  def->optional(op_settings.net_resolution, "OP_net_resolution", "Multiples of 16. If it is increased, the accuracy potentially increases. If it is "
37  "decreased, the speed increases. For maximum speed-accuracy balance, it should keep the "
38  "closest aspect ratio possible to the images or videos to be processed.\n Using `-1` in "
39  "any of the dimensions, OP will choose the optimal aspect ratio depending on the user's "
40  "input value.\n E.g. the default `-1x368` is equivalent to `656x368` in 16:9 resolutions, "
41  "e.g. full HD (1980x1080) and HD (1280x720) resolutions.");
42  def->optional(op_settings.output_resolution, "OP_output_resolution", "The image resolution (display and output). Use \"-1x-1\" to force the program to use the"
43  " input image resolution.");
44  def->optional(op_settings.scale_gap, "OP_scale_gap", "Scale gap between scales. No effect unless scale_number > 1. Initial scale is always 1. "
45  "If you want to change the initial calib->get scale, you actually want to multiply the "
46  "`net_resolution` by your desired initial scale.");
47  def->optional(op_settings.scale_number, "OP_scale_number", "Number of scales to average.");
48  def->optional(op_settings.model_pose, "OP_model_pose", "Model to be used. E.g. `BODY_25` (25 keypoints, best model), `COCO` (18 keypoints), `MPI` (15 keypoints, ~10% faster), "
49  "MPI_4_layers` (15 keypoints, even faster but less accurate).");
50  def->optional(op_settings.model_folder, "OP_model_folder", "Folder path (absolute or relative) where the models (pose, face, ...) are located.");
51  def->optional(op_settings.num_gpu_start, "OP_num_gpu_start", "GPU device start number.");
52  def->optional(op_settings.minimum_number_of_valid_keypoints_per_entitiy, "MinimalAmountKeypoints", "Minimal amount of keypoints per person. Detected persons with less valid keypoints will be discarded.");
53 
54  def->optional(op_render_threshold, "OP_render_threshold", "Only estimated keypoints whose score confidences are higher than this threshold will be"
55  " rendered.\n Generally, a high threshold (> 0.5) will only render very clear body parts;"
56  " while small thresholds (~0.1) will also output guessed and occluded keypoints, but also"
57  " more false positives (i.e. wrong detections).");
58 
59  def->optional(active_upon_startup, "ActivateOnStartup", "If true, poseEstimation-tasks are started after starting the component. If false, the component idles.");
60  }
61 
63  {
65  {
66  start();
67  }
68  }
69 
71  {
72 
73  }
74 
76  {
77 
78  }
79 
81  {
82 
83  }
84 
86  {
87 
88  stop();
89  running2D = false;
90 
91  delete openposeResultImage;
92  }
93 
95  {
96  }
97 
98  void OpenPoseEstimationComponentPluginUser::renderOutputImage(const op::Array<float>& op_keypoints)
99  {
100  openposePtr->render2DResultImage(*rgbImageBuffer, op_keypoints, *openposeResultImage[0], op_render_threshold);
101  }
102 
104  {
105  ARMARX_DEBUG << deactivateSpam(0.5) << "Reporting 2Dkeypoints for " << openposeResult.size() << " entities";
106  listener2DPrx->report2DKeypoints(openposeResult, timestamp_of_update);
107  }
108 
110  {
111  // nothing to visualize since no 3d info available
112  openposeResult.clear(); // last step in pipeline
113 
114  }
115 
117  {
118  // Check if openpose is setup
119  if (!openposePtr)
120  {
121  std::lock_guard l(openpose_initializing_mutex);
122  ARMARX_INFO << "Initialize OpenPose...";
124  }
125 
126  while (running2D && openposeTask->isRunning())
127  {
128  if (!update_ready)
129  {
130  usleep(100);
131  continue;
132  }
133 
134  update_ready = false;
135 
136  // 0. An update is ready.
137  // The new input image is already stored in rgbImageBuffer
138  // We use this image to get the openpose data
139  // After that the openpose image is stored in openPoseResultImage and the
140  // OpenPose values are stored in openposeResult
141 
142  // 1. create 2D-Keypoints from images
143  std::lock_guard rgbImage_lock(rgbImageBufferMutex);
144  auto op_array = openposePtr->getOpenposeKeypoints(rgbImageBuffer);
145  openposeResult = openposePtr->convert2DKeypointsToIce(op_array, rgbImageBuffer);
146 
147  if (openposeResult.empty())
148  {
149  continue;
150  }
151 
152  // 2. renderOutputImage
153  {
154  std::lock_guard output_lock(openposeResultImageMutex);
155  renderOutputImage(op_array);
156  }
157 
158  // 3. send keypoints via topic
159  reportEntities();
160 
161  // 4. visualize
162  visualize();
163 
164  result_image_ready = true;
165  }
166  }
167 
169  {
170  if (running2D)
171  {
172  return;
173  }
174  else
175  {
176  ARMARX_INFO << "Starting OpenposeEstimation";
178  running2D = true;
179  openposeTask->start();
180  }
181  }
182 
184  {
185  if (running2D)
186  {
187  ARMARX_INFO << "Stopping OpenposeEstimation";
188  running2D = false;
189  openposeTask->stop(true);
190  }
191 
192  // free memory
193  openposePtr.reset();
194  }
195 
197  {
198  ARMARX_WARNING << "Could not start 3D pose estimation in 2D component.";
199  }
200 
202  {
203 
204  }
205 
206  void OpenPoseEstimationComponentPluginUser::enableHumanPoseEstimation(const EnableHumanPoseEstimationInput &input, const Ice::Current&)
207  {
208  if (input.enable2d)
209  {
210  start();
211  }
212  else
213  {
214  stop();
215  }
216  }
217 }
armarx::OpenPoseAdapter::OpenPoseSettings::model_pose
std::string model_pose
Definition: OpenPoseAdapter.h:70
RemoteRobot.h
armarx::OpenPoseEstimationComponentPluginUser::openpose_initializing_mutex
std::mutex openpose_initializing_mutex
Definition: OpenPoseEstimationComponent.h:121
armarx::OpenPoseEstimationComponentPluginUser::OpenPoseEstimationComponentPluginUser
OpenPoseEstimationComponentPluginUser()
Definition: OpenPoseEstimationComponent.cpp:94
armarx::OpenPoseEstimationComponentPluginUser::update_ready
std::atomic_bool update_ready
Definition: OpenPoseEstimationComponent.h:130
armarx::OpenPoseEstimationComponentPluginUser::rgbImageBuffer
CByteImage * rgbImageBuffer
Definition: OpenPoseEstimationComponent.h:97
armarx::OpenPoseEstimationComponentPluginUser::active_upon_startup
bool active_upon_startup
Definition: OpenPoseEstimationComponent.h:87
armarx::OpenPoseAdapter::OpenPoseSettings::scale_number
int scale_number
Definition: OpenPoseAdapter.h:73
armarx::OpenPoseEstimationComponentPluginUser::preOnDisconnectImageProcessor
virtual void preOnDisconnectImageProcessor()
Definition: OpenPoseEstimationComponent.cpp:85
armarx::OpenPoseAdapter::OpenPoseSettings::model_folder
std::string model_folder
Definition: OpenPoseAdapter.h:71
armarx::MonocularOpenPoseEstimationPtr
std::shared_ptr< OpenPoseAdapter > MonocularOpenPoseEstimationPtr
Definition: OpenPoseAdapter.h:60
armarx::OpenPoseEstimationComponentPluginUser::result_image_ready
std::atomic_bool result_image_ready
Definition: OpenPoseEstimationComponent.h:114
armarx::OpenPoseEstimationComponentPluginUser::listener2DPrx
OpenPose2DListenerPrx listener2DPrx
Definition: OpenPoseEstimationComponent.h:106
armarx::OpenPoseEstimationComponentPluginUser::op_render_threshold
float op_render_threshold
Definition: OpenPoseEstimationComponent.h:118
armarx::OpenPoseEstimationComponentPluginUser::preOnInitImageProcessor
virtual void preOnInitImageProcessor()
Definition: OpenPoseEstimationComponent.cpp:70
armarx::OpenPoseEstimationComponentPluginUser::openposeResultImage
CByteImage ** openposeResultImage
Definition: OpenPoseEstimationComponent.h:113
armarx::RunningTask
Definition: ArmarXMultipleObjectsScheduler.h:35
armarx::OpenPoseEstimationComponentPluginUser::start
void start(const Ice::Current &=Ice::emptyCurrent) override
Definition: OpenPoseEstimationComponent.cpp:168
armarx::OpenPoseEstimationComponentPluginUser::start3DPoseEstimation
void start3DPoseEstimation(const Ice::Current &=Ice::emptyCurrent) override
Definition: OpenPoseEstimationComponent.cpp:196
armarx::OpenPoseEstimationComponentPluginUser::loop
void loop()
Definition: OpenPoseEstimationComponent.cpp:116
ImageProcessor.h
armarx::OpenPoseEstimationComponentPluginUser::stop
void stop(const Ice::Current &=Ice::emptyCurrent) override
Definition: OpenPoseEstimationComponent.cpp:183
armarx::OpenPoseEstimationComponentPluginUser::timestamp_of_update
std::atomic_long timestamp_of_update
Definition: OpenPoseEstimationComponent.h:131
armarx::OpenPoseEstimationComponentPluginUser::openposeTask
armarx::RunningTask< OpenPoseEstimationComponentPluginUser >::pointer_type openposeTask
Definition: OpenPoseEstimationComponent.h:128
armarx::OpenPoseAdapter::OpenPoseSettings::scale_gap
double scale_gap
Definition: OpenPoseAdapter.h:72
ARMARX_DEBUG
#define ARMARX_DEBUG
Definition: Logging.h:177
armarx::aron::input
ReaderT::InputType & input
Definition: rw.h:19
armarx::OpenPoseEstimationComponentPluginUser::postOnConnectImageProcessor
virtual void postOnConnectImageProcessor()
Definition: OpenPoseEstimationComponent.cpp:62
armarx::OpenPoseAdapter
Definition: OpenPoseAdapter.h:63
armarx::OpenPoseEstimationComponentPluginUser::running2D
std::atomic_bool running2D
Definition: OpenPoseEstimationComponent.h:129
armarx::OpenPoseEstimationComponentPluginUser::openposeResultImageMutex
std::mutex openposeResultImageMutex
Definition: OpenPoseEstimationComponent.h:112
armarx::OpenPoseAdapter::OpenPoseSettings::output_resolution
std::string output_resolution
Definition: OpenPoseAdapter.h:69
armarx::OpenPoseEstimationComponentPluginUser::rgbImageBufferMutex
std::mutex rgbImageBufferMutex
Definition: OpenPoseEstimationComponent.h:98
armarx::OpenPoseAdapter::OpenPoseSettings::minimum_number_of_valid_keypoints_per_entitiy
unsigned int minimum_number_of_valid_keypoints_per_entitiy
Definition: OpenPoseAdapter.h:75
armarx::OpenPoseAdapter::OpenPoseSettings::net_resolution
std::string net_resolution
Definition: OpenPoseAdapter.h:68
armarx::OpenPoseEstimationComponentPluginUser::stop3DPoseEstimation
void stop3DPoseEstimation(const Ice::Current &=Ice::emptyCurrent) override
Definition: OpenPoseEstimationComponent.cpp:201
Component.h
armarx::OpenPoseEstimationComponentPluginUser::postOnDisconnectImageProcessor
virtual void postOnDisconnectImageProcessor()
Definition: OpenPoseEstimationComponent.cpp:80
armarx::OpenPoseEstimationComponentPluginUser::renderOutputImage
virtual void renderOutputImage(const op::Array< float > &)
Definition: OpenPoseEstimationComponent.cpp:98
armarx::OpenPoseEstimationComponentPluginUser::openposeResult
HumanPose2DMap openposeResult
Definition: OpenPoseEstimationComponent.h:109
armarx::OpenPoseEstimationComponentPluginUser::reportEntities
virtual void reportEntities()
Definition: OpenPoseEstimationComponent.cpp:103
armarx::OpenPoseEstimationComponentPluginUser::visualize
virtual void visualize()
Definition: OpenPoseEstimationComponent.cpp:109
armarx::OpenPoseAdapter::OpenPoseSettings::num_gpu_start
int num_gpu_start
Definition: OpenPoseAdapter.h:74
ARMARX_INFO
#define ARMARX_INFO
Definition: Logging.h:174
armarx::OpenPoseEstimationComponentPluginUser::preOnConnectImageProcessor
virtual void preOnConnectImageProcessor()
Definition: OpenPoseEstimationComponent.cpp:75
IceUtil::Handle< class PropertyDefinitionContainer >
armarx::Logging::deactivateSpam
SpamFilterDataPtr deactivateSpam(float deactivationDurationSec=10.0f, const std::string &identifier="", bool deactivate=true) const
disables the logging for the current line for the given amount of seconds.
Definition: Logging.cpp:92
armarx::OpenPoseEstimationComponentPluginUser::openposePtr
MonocularOpenPoseEstimationPtr openposePtr
Definition: OpenPoseEstimationComponent.h:122
armarx::OpenPoseEstimationComponentPluginUser::enableHumanPoseEstimation
void enableHumanPoseEstimation(const EnableHumanPoseEstimationInput &input, const Ice::Current &=Ice::emptyCurrent) override
Definition: OpenPoseEstimationComponent.cpp:206
armarx::OpenPoseEstimationComponentPluginUser::op_settings
OpenPoseAdapter::OpenPoseSettings op_settings
Definition: OpenPoseEstimationComponent.h:117
ARMARX_WARNING
#define ARMARX_WARNING
Definition: Logging.h:186
OpenPoseEstimationComponent.h
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:28
armarx::OpenPoseEstimationComponentPluginUser::postCreatePropertyDefinitions
virtual void postCreatePropertyDefinitions(PropertyDefinitionsPtr &properties)
Definition: OpenPoseEstimationComponent.cpp:32