Astra SDK  v2.1.3
Body.hpp
1 // This file is part of the Orbbec Astra SDK [https://orbbec3d.com]
2 // Copyright (c) 2015-2017 Orbbec 3D
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 // Be excellent to each other.
17 #ifndef ASTRA_BODY_HPP
18 #define ASTRA_BODY_HPP
19 
20 #include <stdexcept>
21 #include <cstdint>
22 #include <astra_core/astra_core.hpp>
23 #include <astra/capi/astra_ctypes.h>
24 #include <astra/capi/streams/body_capi.h>
25 #include <astra/capi/streams/stream_types.h>
26 #include <astra/Array.hpp>
27 #include <astra/Vector.hpp>
28 #include <astra/Matrix3x3.hpp>
29 
30 namespace astra {
31 
32  using std::uint8_t;
33  using std::uint16_t;
34  using std::int16_t;
35  using std::int32_t;
36  using std::uint64_t;
37 
51  {
52  public:
55  {
56  // ::astra_bitmapmask_t::data = nullptr;
59  }
60 
62  int32_t width() const { return ::astra_bitmapmask_t::width; }
64  int32_t height() const { return ::astra_bitmapmask_t::height; }
66  int32_t bpp() const { return sizeof(uint8_t); }
68  int32_t length() const
69  {
70  return ::astra_bitmapmask_t::width *
72  }
73 
75  int32_t byte_length() const
76  {
77  return ::astra_bitmapmask_t::width *
79  bpp();
80  }
81 
83  const uint8_t* data() const { return ::astra_bitmapmask_t::data; }
84 
85  friend class FloorInfo;
86  friend class BodyFrame;
87  };
88 
99 
105  enum class BodyTrackingFeatureFlags : ::astra_body_tracking_feature_flags_t
106  {
108  Segmentation = 0,
110  Joints = 1,
112  HandPoses = 3
113  };
114 
118  enum class SkeletonProfile : ::astra_skeleton_profile_t {
120  Full = 0,
122  UpperBody = 1,
124  Basic = 2
125  };
126 
131  enum class SkeletonOptimization : ::astra_skeleton_optimization_t {
132  Optimization1 = 1,
134  MinimizeMemory = 2,
135  Optimization2 = 2,
136  Optimization3 = 3,
137  Optimization4 = 4,
139  Balanced = 5,
140  Optimization5 = 5,
141  Optimization6 = 6,
142  Optimization7 = 7,
143  Optimization8 = 8,
144  Optimization9 = 9,
146  BestAccuracy = 9,
147  };
148 
152  enum class BodyOrientation : ::astra_body_orientation_t {
153  TOP = 0,
154  LEFT = 1,
155  RIGHT = 2
156  };
157 
161  enum class JointStatus : ::astra_joint_status_t
162  {
164  NotTracked = 0,
169  LowConfidence = 1,
171  Tracked = 2
172  };
173 
177  enum class JointType : ::astra_joint_type_t
178  {
179  Head = 0,
180  ShoulderSpine = 1,
181  LeftShoulder = 2,
182  LeftElbow = 3,
183  LeftHand = 4,
184  RightShoulder = 5,
185  RightElbow = 6,
186  RightHand = 7,
187  MidSpine = 8,
188  BaseSpine = 9,
189  LeftHip = 10,
190  LeftKnee = 11,
191  LeftFoot = 12,
192  RightHip = 13,
193  RightKnee = 14,
194  RightFoot = 15,
195  LeftWrist = 16,
196  RightWrist = 17,
197  Neck = 18,
198  Unknown = 255,
199  };
200 
210  class Joint : private ::astra_joint_t
211  {
212  public:
214  JointType type() const
215  {
216  return static_cast<JointType>(::astra_joint_t::type);
217  }
218 
221  {
222  return static_cast<JointStatus>(::astra_joint_t::status);
223  }
224 
232  const Vector2f& depth_position() const
233  {
234  return *static_cast<const Vector2f*>(&(::astra_joint_t::depthPosition));
235  }
236 
238  const Vector3f& world_position() const
239  {
240  return *static_cast<const Vector3f*>(&(::astra_joint_t::worldPosition));
241  }
242 
244  const Matrix3x3& orientation() const
245  {
246  return *static_cast<const Matrix3x3*>(&(::astra_joint_t::orientation));
247  }
248 
249  friend class Body;
250  };
251 
256  enum class HandPose : ::astra_handpose_t
257  {
259  Unknown = 0,
261  Grip = 1,
262  };
263 
265  {
266  private:
267  using ::astra_handpose_info_t::leftHand;
268  using ::astra_handpose_info_t::rightHand;
269  public:
270  HandPose left_hand() const { return static_cast<HandPose>(this->leftHand); }
271  HandPose right_hand() const { return static_cast<HandPose>(this->rightHand); }
272 
273  friend class Body;
274  };
275 
279  enum class BodyStatus : ::astra_body_status_t
280  {
282  NotTracking = 0,
284  TrackingLost = 1,
286  TrackingStarted = 2,
288  Tracking = 3,
289  };
290 
295 
299  using BodyId = astra_body_id_t;
300 
311  class Body : private ::astra_body_t
312  {
313  public:
321  BodyId id() const { return ::astra_body_t::id; }
322 
325  {
326  return static_cast<BodyStatus>(::astra_body_t::status);
327  }
328 
330  const Vector3f& center_of_mass() const
331  {
332  return *static_cast<const Vector3f*>(&(::astra_body_t::centerOfMass));
333  }
334 
335  bool joints_enabled() const
336  {
337  return (::astra_body_t::features & ASTRA_BODY_TRACKING_JOINTS) == ASTRA_BODY_TRACKING_JOINTS;
338  }
339 
340  bool hand_poses_enabled() const
341  {
342  return (::astra_body_t::features & ASTRA_BODY_TRACKING_HAND_POSES) == ASTRA_BODY_TRACKING_HAND_POSES;
343  }
344 
347  {
348  return make_array(
349  static_cast<const Joint*>(&(::astra_body_t::joints[0])), ASTRA_MAX_JOINTS);
350  }
351 
352  const HandPoseInfo& hand_poses() const
353  {
354  return *static_cast<const HandPoseInfo*>(&(::astra_body_t::handPoses));
355  }
356 
357  friend class BodyFrame;
358  };
359 
375  class Plane : private ::astra_plane_t
376  {
377  public:
381  {
382  ::astra_plane_t::a = 0.f;
383  ::astra_plane_t::b = 0.f;
384  ::astra_plane_t::c = 0.f;
385  ::astra_plane_t::d = 0.f;
386  }
387 
389  float a() const { return ::astra_plane_t::a; }
391  float b() const { return ::astra_plane_t::b; }
393  float c() const { return ::astra_plane_t::c; }
395  float d() const { return ::astra_plane_t::d; }
396 
398  const Vector3f& normal() const
399  {
400  // a, b, c are the normal x, y, z. Use address of 'a'
401  // for transmutation of a Vector3f from thin air.
402  return *reinterpret_cast<const Vector3f*>(&(::astra_plane_t::a));
403  }
404 
406  bool is_degenerate() const
407  {
408  return ::astra_plane_t::a == 0.f &&
409  ::astra_plane_t::b == 0.f &&
410  ::astra_plane_t::c == 0.f;
411  }
412 
413  friend class FloorInfo;
414  };
415 
416 
418  {
419  private:
420  using ::astra_floor_info_t::floorMask;
421  using ::astra_floor_info_t::floorPlane;
422  using ::astra_floor_info_t::floorDetected;
423  public:
424  const FloorMask& floor_mask() const
425  {
426  return *static_cast<const FloorMask*>(&this->floorMask);
427  }
428  const Plane& floor_plane() const
429  {
430  return *static_cast<const Plane*>(&this->floorPlane);
431  }
432  bool floor_detected() const { return this->floorDetected != ASTRA_FALSE; }
433 
434  friend class BodyFrame;
435  };
436 
438  {
439  public:
440  std::int32_t width() const { return ::astra_bodyframe_info_t::width; }
441  std::int32_t height() const { return ::astra_bodyframe_info_t::height; }
442  bool is_estimated() const { return ::astra_bodyframe_info_t::isEstimated != 0; }
443  friend class BodyFrame;
444  };
445 
451 
455  class BodyFrame
456  {
457  private:
458  ::astra_bodyframe_t handle_;
459  astra_frame_index_t frameIndex_;
460 
461  public:
463  BodyFrame(const BodyFrame&) = delete;
465  BodyFrame& operator=(const BodyFrame&) = delete;
466 
469  : handle_(other.handle_),
470  frameIndex_(other.frameIndex_)
471  {}
472 
475  {
476  handle_ = other.handle_;
477  frameIndex_ = other.frameIndex_;
478 
479  return *this;
480  }
481 
482  template<typename TFrameType>
483  static TFrameType acquire(astra_reader_frame_t readerFrame,
484  astra_stream_subtype_t subtype)
485  {
486  if (readerFrame != nullptr)
487  {
488  astra_bodyframe_t bodyFrame;
489  astra_frame_get_bodyframe(readerFrame, &bodyFrame);
490  return TFrameType(bodyFrame);
491  }
492 
493  return TFrameType(nullptr);
494  }
495 
501  bool is_valid() const { return handle_ != nullptr; }
502 
508  astra_frame_index_t frame_index() const
509  {
510  throw_if_invalid_frame();
511  return frameIndex_;
512  }
513 
519  const BodyFrameInfo& info() const
520  {
521  throw_if_invalid_frame();
522  return *static_cast<const BodyFrameInfo*>(&handle_->info);
523  }
524 
526  const BodyMask& body_mask() const
527  {
528  throw_if_invalid_frame();
529  return *static_cast<const BodyMask*>(&handle_->bodyMask);
530  }
531 
532  const FloorInfo& floor_info() const
533  {
534  throw_if_invalid_frame();
535  return *static_cast<const FloorInfo*>(&handle_->floorInfo);
536  }
537 
544  BodyList bodies() const
545  {
546  throw_if_invalid_frame();
547  const auto& bodyList = handle_->bodyList;
548  return make_array(
549  static_cast<const Body*>(&bodyList.bodies[0]), bodyList.count);
550  }
551 
556  void rotate(int angle)
557  {
558  throw_if_invalid_frame();
559  astra_bodyframe_rotate(handle_,angle);
560  }
561 
562  private:
564  : handle_(handle)
565  {
566  if (handle_)
567  {
568  astra_bodyframe_get_frameindex(handle, &frameIndex_);
569  }
570  }
571 
572  void throw_if_invalid_frame() const
573  {
574  if (!is_valid())
575  {
576  throw std::logic_error("Cannot operate on an invalid frame");
577  }
578  }
579  };
580 
581 
587  class BodyStream : public DataStream
588  {
589  public:
596  : DataStream(connection),
597  bodyStream_(reinterpret_cast<astra_bodystream_t>(connection))
598  { }
599 
606  {
607  astra_body_tracking_feature_flags_t features = ASTRA_BODY_TRACKING_SEGMENTATION;
608  astra_bodystream_get_body_features(bodyStream_, id, &features);
609  return static_cast<BodyTrackingFeatureFlags>(features);
610  }
611 
617  void set_body_features(astra_body_id_t id, BodyTrackingFeatureFlags features)
618  {
619  astra_bodystream_set_body_features(bodyStream_,
620  id,
621  static_cast<astra_body_tracking_feature_flags_t>(features));
622  }
623 
630  {
631  astra_body_tracking_feature_flags_t features = ASTRA_BODY_TRACKING_SEGMENTATION;
632  astra_bodystream_get_default_body_features(bodyStream_, &features);
633  return static_cast<BodyTrackingFeatureFlags>(features);
634  }
635 
642  {
643  astra_bodystream_set_default_body_features(bodyStream_,
644  static_cast<astra_body_tracking_feature_flags_t>(features));
645  }
646 
653  {
654  astra_skeleton_profile_t skeletonProfileState = ASTRA_SKELETON_PROFILE_FULL;
655  astra_bodystream_get_skeleton_profile(bodyStream_, &skeletonProfileState);
656  return static_cast<SkeletonProfile>(skeletonProfileState);
657  }
658 
664  void set_skeleton_profile(SkeletonProfile skeletonProfile)
665  {
666  astra_bodystream_set_skeleton_profile(bodyStream_,
667  static_cast<astra_skeleton_profile_t>(skeletonProfile));
668  }
669 
676  {
677  astra_skeleton_optimization_t skeletonOptimization = ASTRA_SKELETON_OPTIMIZATION_BEST_ACCURACY;
678  astra_bodystream_get_skeleton_optimization(bodyStream_, &skeletonOptimization);
679  return static_cast<SkeletonOptimization>(skeletonOptimization);
680  }
681 
688  {
689  astra_bodystream_set_skeleton_optimization(bodyStream_,
690  static_cast<astra_skeleton_optimization_t>(skeletonOptimization));
691  }
692 
699  {
700  astra_body_orientation_t bodyOrientation = ASTRA_BODY_ORIENTATION_TOP;
701  astra_bodystream_get_body_orientation(bodyStream_, &bodyOrientation);
702  return static_cast<BodyOrientation>(bodyOrientation);
703  }
704 
710  void set_body_orientation(BodyOrientation bodyOrientation)
711  {
712  astra_bodystream_set_body_orientation(bodyStream_,
713  static_cast<astra_body_orientation_t>(bodyOrientation));
714  }
715 
716  static const astra_stream_type_t id = ASTRA_STREAM_BODY;
717 
718  private:
719  astra_bodystream_t bodyStream_{nullptr};
720  };
722 }
723 
724 #endif /* ASTRA_BODY_HPP */
Simple wrapper around primitive arrays
Definition: Array.hpp:31
Bitmap representing a 2d mask
Definition: Body.hpp:51
int32_t height() const
Gets the height of the mask
Definition: Body.hpp:64
BitmapMask()
Default constructs an empty zero-sized BitmapMask
Definition: Body.hpp:54
int32_t width() const
Gets the width of the mask
Definition: Body.hpp:62
int32_t byte_length() const
Gets the length of the mask in bytes
Definition: Body.hpp:75
const uint8_t * data() const
Gets an immutable raw pointer to mask data
Definition: Body.hpp:83
int32_t bpp() const
Gets the bytes per pixel
Definition: Body.hpp:66
int32_t length() const
Gets the length of the mask in pixels
Definition: Body.hpp:68
Body tracking information produced by a BodyTracker instance
Definition: Body.hpp:456
void rotate(int angle)
Definition: Body.hpp:556
astra_frame_index_t frame_index() const
get body frame index
Definition: Body.hpp:508
BodyFrame(const BodyFrame &)=delete
BodyFrame is not copy constructible
BodyFrame(BodyFrame &&other)
BodyFrame is move constructible
Definition: Body.hpp:468
const BodyFrameInfo & info() const
get body frame info
Definition: Body.hpp:519
BodyFrame & operator=(BodyFrame &&other)
BodyFrame is move assignable
Definition: Body.hpp:474
BodyList bodies() const
Gets the current tracked bodies associated with the current BodyFrame
Definition: Body.hpp:544
BodyFrame & operator=(const BodyFrame &)=delete
BodyFrame is not copy assignable
const BodyMask & body_mask() const
Gets the BodyMask of the current tracked bodies
Definition: Body.hpp:526
bool is_valid() const
get body frame is vaild
Definition: Body.hpp:501
Definition: Body.hpp:438
Human body
Definition: Body.hpp:312
BodyId id() const
Gets BodyId associated with the Body
Definition: Body.hpp:321
const Vector3f & center_of_mass() const
Gets the real world center of mass estimate
Definition: Body.hpp:330
BodyStatus status() const
Gets the tracking status of the body
Definition: Body.hpp:324
JointList joints() const
Gets the current list of joints (Joint) being currently tracked
Definition: Body.hpp:346
A Body Data Stream
Definition: Body.hpp:588
BodyTrackingFeatureFlags get_default_body_features()
get default body features
Definition: Body.hpp:629
void set_body_features(astra_body_id_t id, BodyTrackingFeatureFlags features)
set body features
Definition: Body.hpp:617
void set_body_orientation(BodyOrientation bodyOrientation)
set body orientation
Definition: Body.hpp:710
BodyOrientation get_body_orientation()
get body orientation, default value is BodyOrientation::TOP.
Definition: Body.hpp:698
void set_skeleton_optimization(SkeletonOptimization skeletonOptimization)
set skeleton optimization
Definition: Body.hpp:687
SkeletonProfile get_skeleton_profile()
get skeleton profile
Definition: Body.hpp:652
void set_skeleton_profile(SkeletonProfile skeletonProfile)
set skeleton profile
Definition: Body.hpp:664
BodyTrackingFeatureFlags get_body_features(astra_body_id_t id)
get body features
Definition: Body.hpp:605
BodyStream(astra_streamconnection_t connection)
default constructs
Definition: Body.hpp:595
SkeletonOptimization get_skeleton_optimization()
get skeleton optimization
Definition: Body.hpp:675
void set_default_body_features(BodyTrackingFeatureFlags features)
set default body features
Definition: Body.hpp:641
Data Stream
Definition: DataStream.hpp:33
Definition: Body.hpp:418
Definition: Body.hpp:265
Body joint
Definition: Body.hpp:211
const Matrix3x3 & orientation() const
Gets the 3x3 Rotation matrix representing the rotation of this joint.
Definition: Body.hpp:244
const Vector3f & world_position() const
Gets the real world position of the Joint
Definition: Body.hpp:238
JointType type() const
Gets the type of joint
Definition: Body.hpp:214
const Vector2f & depth_position() const
Gets the depth ("projective") position of the Joint
Definition: Body.hpp:232
JointStatus status() const
Gets the current status of the Joint
Definition: Body.hpp:220
3D geometric plane
Definition: Body.hpp:376
bool is_degenerate() const
Returns whether than plane is considered degenerate (invalid)
Definition: Body.hpp:406
float a() const
Gets the A coefficient
Definition: Body.hpp:389
float c() const
Gets the C coefficient
Definition: Body.hpp:393
float d() const
Gets the D coefficent (signed distance)
Definition: Body.hpp:395
const Vector3f & normal() const
Gets the plane normal
Definition: Body.hpp:398
Plane()
Default constructs a plane that passes though origin, has a zero-length normal, and is considered deg...
Definition: Body.hpp:380
float b() const
Gets the B coefficient
Definition: Body.hpp:391
ASTRA_API_EX astra_status_t astra_bodyframe_rotate(astra_bodyframe_t bodyFrame, int angle)
Array< T > make_array(T *ptr, std::size_t size)
Simplifies Array construction by leveraging function template type deduction
Definition: Array.hpp:132
HandPose
Hand pose enum. Enumeration of the hand poses that can be detected.
Definition: Body.hpp:257
JointStatus
Joint status enumeration
Definition: Body.hpp:162
astra_body_id_t BodyId
Identifier type for bodies
Definition: Body.hpp:299
BodyOrientation
the orientation of people's heads in depth image.
Definition: Body.hpp:152
SkeletonOptimization
Represents the body tracking configuration that trades-off tracking accuracy, memory,...
Definition: Body.hpp:131
SkeletonProfile
Skeleton profile representing the set of joints to be tracked.
Definition: Body.hpp:118
BodyStatus
Enumeration of possible tracking status of a orbbec::bodytracking::Body
Definition: Body.hpp:280
BodyTrackingFeatureFlags
Bitmask of body features Represents the possible features that body tracking can produce on a body....
Definition: Body.hpp:106
JointType
Joint type enumeration
Definition: Body.hpp:178
Struct representing a 2-dimensional bitmask
Definition: body_types.h:344
int32_t height
height in pixels
Definition: body_types.h:351
int32_t width
width in pixels
Definition: body_types.h:349
Struct containing body tracking information
Definition: body_types.h:293
astra_body_status_t status
Tracking status
Definition: body_types.h:321
astra_body_tracking_feature_flags_t features
Bitmask of features that are enabled.
Definition: body_types.h:298
astra_joint_t joints[ASTRA_MAX_JOINTS]
Array of tracked joints
Definition: body_types.h:306
astra_vector3f_t centerOfMass
Single point describing the center of mass of a body.
Definition: body_types.h:304
astra_handpose_info_t handPoses
Hand poses
Definition: body_types.h:308
Struct containing general body frame information
Definition: body_types.h:401
Definition: stream_types.h:62
Struct containing floor information about the scene
Definition: body_types.h:414
astra_floormask_t floorMask
Floor mask
Definition: body_types.h:416
astra_bool_t floorDetected
If the floor is detected, ASTRA_TRUE. Otherwise, ASTRA_FALSE.
Definition: body_types.h:424
astra_plane_t floorPlane
Floor plane
Definition: body_types.h:418
Definition: body_types.h:187
Joint information
Definition: body_types.h:123
astra_vector2f_t depthPosition
Depth ("projective") position of joint
Definition: body_types.h:135
astra_joint_status_t status
Joint status
Definition: body_types.h:133
astra_matrix3x3_t orientation
3x3 Rotation matrix representing the rotation of this joint.
Definition: body_types.h:140
astra_vector3f_t worldPosition
Real world position of joint
Definition: body_types.h:137
astra_joint_type_t type
Joint type
Definition: body_types.h:128
Struct representing a geometric 3-dimensional plane
Definition: body_types.h:386
float d
D coefficient
Definition: body_types.h:394
float c
C coefficient
Definition: body_types.h:392
float a
A coefficient
Definition: body_types.h:388
float b
B coefficient
Definition: body_types.h:390
Definition: astra_plugin.h:24
Represents a 3x3 rotation matrix
Definition: Matrix3x3.hpp:31
Represents a float 2d vector
Definition: Vector2f.hpp:30
Represents a float 3d vector
Definition: Vector3f.hpp:30