#ifndef OPENPOSE_CORE_DATUM_HPP #define OPENPOSE_CORE_DATUM_HPP #ifdef USE_3D_ADAM_MODEL #ifdef USE_EIGEN #include #endif #endif #include namespace op { /** * Datum: The OpenPose Basic Piece of Information Between Threads * Datum is one the main OpenPose classes/structs. The workers and threads share by default a * std::shared_ptr>. It contains all the parameters that the different workers and threads need * to exchange. */ struct OP_API Datum { // ---------------------------------------- ID parameters ---------------------------------------- // unsigned long long id; /**< Datum ID. Internally used to sort the Datums if multi-threading is used. */ unsigned long long subId; /**< Datum sub-ID. Internally used to sort the Datums if multi-threading is used. */ unsigned long long subIdMax; /**< Datum maximum sub-ID. Used to sort the Datums if multi-threading is used. */ /** * Name used when saving the data to disk (e.g., `write_images` or `write_keypoint` flags in the demo). */ std::string name; /** * Corresponding frame number. * If the producer (e.g., video) starts from frame 0 and does not repeat any frame, then frameNumber should * match the field id. */ unsigned long long frameNumber; // ------------------------------ Input image and rendered version parameters ------------------------------ // /** * Original image to be processed in cv::Mat uchar format. * Size: (input_width x input_height) x 3 channels */ Matrix cvInputData; /** * Original image to be processed in Array format. * It has been resized to the net input resolution, as well as reformatted Array format to be compatible * with the net. * If >1 scales, each scale is right- and bottom-padded to fill the greatest resolution. The * scales are sorted from bigger to smaller. * Vector size: #scales * Each array size: 3 x input_net_height x input_net_width */ std::vector> inputNetData; /** * Rendered image in Array format. * It consists of a blending of the cvInputData and the pose/body part(s) heatmap/PAF(s). * If rendering is disabled (e.g., `no_render_pose` flag in the demo), outputData will be empty. * Size: 3 x output_net_height x output_net_width */ Array outputData; /** * Rendered image in cv::Mat uchar format. * It has been resized to the desired output resolution (e.g., `resolution` flag in the demo). * If outputData is empty, cvOutputData will also be empty. * Size: (output_height x output_width) x 3 channels */ Matrix cvOutputData; /** * Rendered 3D image in cv::Mat uchar format. */ Matrix cvOutputData3D; // ------------------------------ Resulting Array data parameters ------------------------------ // /** * Body pose (x,y,score) locations for each person in the image. * It has been resized to the desired output resolution (e.g., `resolution` flag in the demo). * Size: #people x #body parts (e.g., 18 for COCO or 15 for MPI) x 3 ((x,y) coordinates + score) */ Array poseKeypoints; /** * People ID * It returns a person ID for each body pose, providing temporal consistency. The ID will be the same one * for a person across frames. I.e. this ID allows to keep track of the same person in time. * If either person identification is disabled or poseKeypoints is empty, poseIds will also be empty. * Size: #people */ Array poseIds; /** * Body pose global confidence/score for each person in the image. * It does not only consider the score of each body keypoint, but also the score of each PAF association. * Optimized for COCO evaluation metric. * It will highly penalyze people with missing body parts (e.g., cropped people on the borders of the image). * If poseKeypoints is empty, poseScores will also be empty. * Size: #people */ Array poseScores; /** * Body pose heatmaps (body parts, background and/or PAFs) for the whole image. * This parameter is by default empty and disabled for performance. Each group (body parts, background and * PAFs) can be individually enabled. * #heatmaps = #body parts (if enabled) + 1 (if background enabled) + 2 x #PAFs (if enabled). Each PAF has 2 * consecutive channels, one for x- and one for y-coordinates. * Order heatmaps: body parts + background (as appears in POSE_BODY_PART_MAPPING) + (x,y) channel of each PAF * (sorted as appears in POSE_BODY_PART_PAIRS). See `pose/poseParameters.hpp`. * The user can choose the heatmaps normalization: ranges [0, 1], [-1, 1] or [0, 255]. Check the * `heatmaps_scale` flag in {OpenPose_path}/doc/advanced/demo_advanced.md for more details. * Size: #heatmaps x output_net_height x output_net_width */ Array poseHeatMaps; /** * Body pose candidates for the whole image. * This parameter is by default empty and disabled for performance. It can be enabled with `candidates_body`. * Candidates refer to all the detected body parts, before being assembled into people. Note that the number * of candidates is equal or higher than the number of body parts after being assembled into people. * Size: #body parts x min(part candidates, POSE_MAX_PEOPLE) x 3 (x,y,score). * Rather than vector, it should ideally be: * std::array>, #BP> poseCandidates; */ std::vector>> poseCandidates; /** * Face detection locations (x,y,width,height) for each person in the image. * It is resized to cvInputData.size(). * Size: #people */ std::vector> faceRectangles; /** * Face keypoints (x,y,score) locations for each person in the image. * It has been resized to the same resolution as `poseKeypoints`. * Size: #people x #face parts (70) x 3 ((x,y) coordinates + score) */ Array faceKeypoints; /** * Face pose heatmaps (face parts and/or background) for the whole image. * Analogous of bodyHeatMaps applied to face. However, there is no PAFs and the size is different. * Size: #people x #face parts (70) x output_net_height x output_net_width */ Array faceHeatMaps; /** * Hand detection locations (x,y,width,height) for each person in the image. * It is resized to cvInputData.size(). * Size: #people */ std::vector, 2>> handRectangles; /** * Hand keypoints (x,y,score) locations for each person in the image. * It has been resized to the same resolution as `poseKeypoints`. * handKeypoints[0] corresponds to left hands, and handKeypoints[1] to right ones. * Size each Array: #people x #hand parts (21) x 3 ((x,y) coordinates + score) */ std::array, 2> handKeypoints; /** * Hand pose heatmaps (hand parts and/or background) for the whole image. * Analogous of faceHeatMaps applied to face. * Size each Array: #people x #hand parts (21) x output_net_height x output_net_width */ std::array, 2> handHeatMaps; // ---------------------------------------- 3-D Reconstruction parameters ---------------------------------------- // /** * Body pose (x,y,z,score) locations for each person in the image. * Size: #people x #body parts (e.g., 18 for COCO or 15 for MPI) x 4 ((x,y,z) coordinates + score) */ Array poseKeypoints3D; /** * Face keypoints (x,y,z,score) locations for each person in the image. * It has been resized to the same resolution as `poseKeypoints3D`. * Size: #people x #face parts (70) x 4 ((x,y,z) coordinates + score) */ Array faceKeypoints3D; /** * Hand keypoints (x,y,z,score) locations for each person in the image. * It has been resized to the same resolution as `poseKeypoints3D`. * handKeypoints[0] corresponds to left hands, and handKeypoints[1] to right ones. * Size each Array: #people x #hand parts (21) x 4 ((x,y,z) coordinates + score) */ std::array, 2> handKeypoints3D; /** * 3x4 camera matrix of the camera (equivalent to cameraIntrinsics * cameraExtrinsics). */ Matrix cameraMatrix; /** * 3x4 extrinsic parameters of the camera. */ Matrix cameraExtrinsics; /** * 3x3 intrinsic parameters of the camera. */ Matrix cameraIntrinsics; /** * If it is not empty, OpenPose will not run its internal body pose estimation network and will instead use * this data as the substitute of its network. The size of this element must match the size of the output of * its internal network, or it will lead to core dumped (segmentation) errors. You can modify the pose * estimation flags to match the dimension of both elements (e.g., `--net_resolution`, `--scale_number`, etc.). */ Array poseNetOutput; // ---------------------------------------- Other (internal) parameters ---------------------------------------- // /** * Scale ratio between the input Datum::cvInputData and the net input size. */ std::vector scaleInputToNetInputs; /** * Size(s) (width x height) of the image(s) fed to the pose deep net. * The size of the std::vector corresponds to the number of scales. */ std::vector> netInputSizes; /** * Scale ratio between the input Datum::cvInputData and the output Datum::cvOutputData. */ double scaleInputToOutput; /** * Size (width x height) of the image returned by the deep net. */ Point netOutputSize; /** * Scale ratio between the net output and the final output Datum::cvOutputData. */ double scaleNetToOutput; /** * Pair with the element key id POSE_BODY_PART_MAPPING on `pose/poseParameters.hpp` and its mapped value (e.g. * 1 and "Neck"). */ std::pair elementRendered; // 3D/Adam parameters (experimental code not meant to be publicly used) #ifdef USE_3D_ADAM_MODEL // Adam/Unity params std::vector adamPosePtr; int adamPoseRows; std::vector adamTranslationPtr; std::vector vtVecPtr; int vtVecRows; std::vector j0VecPtr; int j0VecRows; std::vector adamFaceCoeffsExpPtr; int adamFaceCoeffsExpRows; #ifdef USE_EIGEN // Adam/Unity params Eigen::Matrix adamPose; Eigen::Vector3d adamTranslation; // Adam params (Jacobians) Eigen::Matrix vtVec; Eigen::Matrix j0Vec; Eigen::VectorXd adamFaceCoeffsExp; #endif #endif // ---------------------------------------- Functions ---------------------------------------- // /** * Default constructor struct. * It simply initializes the struct, id is temporary set to 0 and each other variable is assigned to its * default value. */ explicit Datum(); /** * Copy constructor. * It performs `fast copy`: For performance purpose, copying a Datum or Array or cv::Mat just copies the * reference, it still shares the same internal data. * Modifying the copied element will modify the original one. * Use clone() for a slower but real copy, similarly to cv::Mat and Array. * @param datum Datum to be copied. */ Datum(const Datum& datum); /** * Copy assignment. * Similar to Datum::Datum(const Datum& datum). * @param datum Datum to be copied. * @return The resulting Datum. */ Datum& operator=(const Datum& datum); /** * Move constructor. * It destroys the original Datum to be moved. * @param datum Datum to be moved. */ Datum(Datum&& datum); /** * Move assignment. * Similar to Datum::Datum(Datum&& datum). * @param datum Datum to be moved. * @return The resulting Datum. */ Datum& operator=(Datum&& datum); /** * Destructor class. * Declared virtual so that Datum can be inherited. */ virtual ~Datum(); /** * Clone function. * Similar to cv::Mat::clone and Array::clone. * It performs a real but slow copy of the data, i.e., even if the copied element is modified, the original * one is not. * @return The resulting Datum. */ Datum clone() const; // ---------------------------------------- Comparison operators ---------------------------------------- // /** * Less comparison operator. * @param datum Datum to be compared. * @result Whether the instance satisfies the condition with respect to datum. */ inline bool operator<(const Datum& datum) const { // return id < datum.id; return id < datum.id || (id == datum.id && subId < datum.subId); } /** * Greater comparison operator. * @param datum Datum to be compared. * @result Whether the instance satisfies the condition with respect to datum. */ inline bool operator>(const Datum& datum) const { // return id > datum.id; return id > datum.id || (id == datum.id && subId > datum.subId); } /** * Less or equal comparison operator. * @param datum Datum to be compared. * @result Whether the instance satisfies the condition with respect to datum. */ inline bool operator<=(const Datum& datum) const { // return id <= datum.id; return id < datum.id || (id == datum.id && subId <= datum.subId); } /** * Greater or equal comparison operator. * @param datum Datum to be compared. * @result Whether the instance satisfies the condition with respect to datum. */ inline bool operator>=(const Datum& datum) const { // return id >= datum.id; return id > datum.id || (id == datum.id && subId >= datum.subId); } /** * Equal comparison operator. * @param datum Datum to be compared. * @result Whether the instance satisfies the condition with respect to datum. */ inline bool operator==(const Datum& datum) const { // return id == datum.id; return id == datum.id && subId == datum.subId; } /** * Not equal comparison operator. * @param datum Datum to be compared. * @result Whether the instance satisfies the condition with respect to datum. */ inline bool operator!=(const Datum& datum) const { // return id != datum.id; return id != datum.id || subId != datum.subId; } }; // Defines for Datum. Added here rather than in `macros.hpp` to avoid circular dependencies #define BASE_DATUM Datum #define BASE_DATUMS std::vector> #define BASE_DATUMS_SH std::shared_ptr #define DEFINE_TEMPLATE_DATUM(templateName) template class OP_API templateName #define COMPILE_TEMPLATE_DATUM(templateName) extern template class templateName } #endif // OPENPOSE_CORE_DATUM_HPP