diff --git a/include/skeletonTreeFactory.h b/include/skeletonTreeFactory.h index b77768d56deccd74fa40abe9f4fb5e3e25a19b95..52bb584cab6792e0006e69aafdf19b4151138cf1 100644 --- a/include/skeletonTreeFactory.h +++ b/include/skeletonTreeFactory.h @@ -36,38 +36,42 @@ **/ struct XSenseStruct { - cv::Point3f mRoot; /***< pSacrum used as sacrum and root. Id is 0. */ + cv::Point3f mRoot; /**< used as root. Id is 0. */ - cv::Point3f mNeck; /**< pC7SpinalProcess used as atlas bone. Id is 1. */ + cv::Point3f mNeck1; /**< used as atlas bone. Id is 1. */ + cv::Point3f mNeck2; /**< used as atlas bone. Id is 19. */ - cv::Point3f mHeadTop; /**< pTopOfHead used as the top of the head. Id is 2. */ + cv::Point3f mHeadTop; /**< used as the top of the head. Id is 2. */ - cv::Point3f mShldrR; /**< pRightAcromion used as right shoulder. Id is 7. */ - cv::Point3f mShldrL; /**< pLeftAcromion used as left shoulder. Id is 3. */ + cv::Point3f mShldrR; /**< used as right shoulder. Id is 7. */ + cv::Point3f mShldrL; /**< used as left shoulder. Id is 3. */ - cv::Point3f mElbowR; /**< pRightOlecranon used as right elbow. Id is 8. */ - cv::Point3f mElbowL; /**< pLeftOlecranon used as left elbow. Id is 4. */ + cv::Point3f mElbowR; /**< used as right elbow. Id is 8. */ + cv::Point3f mElbowL; /**< used as left elbow. Id is 4. */ - cv::Point3f mWristR; /**< pRightStyloid used as right wrist. Id is 9. */ - cv::Point3f mWristL; /**< pLeftStyloid used as left wrist. Id is 5. */ + cv::Point3f mWristR; /**< used as right wrist. Id is 9. */ + cv::Point3f mWristL; /**< used as left wrist. Id is 5. */ - cv::Point3f mHandR; /**< pRightTopOfHand used as the right hand. Id is 10. */ - cv::Point3f mHandL; /**< pLeftTopOfHand used as the left hand. Id is 6.*/ + cv::Point3f mHandR; /**< used as the right hand. Id is 10. */ + cv::Point3f mHandL; /**< used as the left hand. Id is 6.*/ - cv::Point3f mHipR; /**< pRightIschialTub used as the right hip. Id is 15. */ - cv::Point3f mHipL; /**< pLeftIschialTub used as the left hip. Id is 11. */ + cv::Point3f mHipR; /**< used as the right hip. Id is 15. */ + cv::Point3f mHipL; /**< used as the left hip. Id is 11. */ - cv::Point3f mKneeR; /**< pRightPatella used as the right knee. Id is 16. */ - cv::Point3f mKneeL; /**< pLeftPatella used as the left knee. Id is 12. */ + cv::Point3f mKneeR; /**< used as the right knee. Id is 16. */ + cv::Point3f mKneeL; /**< used as the left knee. Id is 12. */ - cv::Point3f mHeelR; /**< pRightHeelFoot used as the right heel. Id is 17. */ - cv::Point3f mHeelL; /**< pLeftHeelFoot used as the left heel. Id is 13 .*/ + cv::Point3f mAnkleR; /**< used as the right ankle. Id is 20. */ + cv::Point3f mAnkleL; /**< used as the left ankle. Id is 21. */ - cv::Point3f mToeR; /**< pRightHeel used as the right of the right foot. Id is 18. */ - cv::Point3f mToeL; /**< pLeftHeel used as the right of the left foot. Id is 14. */ + cv::Point3f mHeelR; /**< used as the right heel. Id is 17. */ + cv::Point3f mHeelL; /**< used as the left heel. Id is 13 .*/ - cv::Point3f mEarR; /**< pRightAuricularis used as the right ear. No id. */ - cv::Point3f mEarL; /**< pLeftAuricularis used as the left ear. No id. */ + cv::Point3f mToeR; /**< used as the right of the right foot. Id is 18. */ + cv::Point3f mToeL; /**< used as the right of the left foot. Id is 14. */ + + cv::Point3f mEarR; /**< used as the right ear. No id. */ + cv::Point3f mEarL; /**< used as the left ear. No id. */ }; /** @brief This class is used to construct a SkeletonTree. diff --git a/src/IO.cpp b/src/IO.cpp index c60fad128b647123fe6674443c915d6c3dd83d95..1293ba31a768284ca41b190b411b879cd7f0a484 100644 --- a/src/IO.cpp +++ b/src/IO.cpp @@ -212,55 +212,40 @@ void IO::readSkeletonC3D_XSENS( MoCapPerson & person, const std::function<cv::Point3f(const ezc3d::DataNS::Points3dNS::Point &)> &c3dToPoint3f) { - /* - * Points from XSens - * 1 based so everything minus 1 - * hip/Sacrum: 8 - * C7: 16 - * right shoulder: 21 - * left shoulder: 22 - * right elbow: 29 - * left elbow: 32 - * right wrist: 28 - * left wrist: 31 - * right top of hand: 33 - * left top of hand: 36 - * top of head: 17 - * right ischial tub: 6 - * left ischial tub: 7 - * right kneecap: 42 - * left kneecap: 46 - * right heel: 53 - * left heel: 59 - * right toe: 58 - * left toe: 64 - */ - const auto &frames = c3d.data().frames(); for(const auto &frame : frames) { - const auto & points = frame.points().points(); + const auto &points = frame.points().points(); + if(points.size() != 87) + { + PCritical(nullptr, "Wrong C3D", "You need a C3D-File with joints for visualization in PeTrack."); + break; + } + XSenseStruct skeletonStruct; - skeletonStruct.mHipR = c3dToPoint3f(points[5]); - skeletonStruct.mHipL = c3dToPoint3f(points[6]); - skeletonStruct.mRoot = c3dToPoint3f(points[7]); - skeletonStruct.mNeck = c3dToPoint3f(points[15]); + skeletonStruct.mHipR = c3dToPoint3f(points[78]); + skeletonStruct.mHipL = c3dToPoint3f(points[82]); + skeletonStruct.mRoot = c3dToPoint3f(points[0]); + skeletonStruct.mNeck1 = c3dToPoint3f(points[15]); + skeletonStruct.mNeck2 = c3dToPoint3f(points[69]); skeletonStruct.mHeadTop = c3dToPoint3f(points[16]); skeletonStruct.mEarR = c3dToPoint3f(points[17]); skeletonStruct.mEarL = c3dToPoint3f(points[18]); - skeletonStruct.mShldrR = c3dToPoint3f(points[20]); - skeletonStruct.mShldrL = c3dToPoint3f(points[21]); - skeletonStruct.mWristR = c3dToPoint3f(points[27]); - skeletonStruct.mElbowR = c3dToPoint3f(points[28]); - skeletonStruct.mWristL = c3dToPoint3f(points[30]); - skeletonStruct.mElbowL = c3dToPoint3f(points[31]); + skeletonStruct.mShldrR = c3dToPoint3f(points[71]); + skeletonStruct.mShldrL = c3dToPoint3f(points[75]); + skeletonStruct.mWristR = c3dToPoint3f(points[73]); + skeletonStruct.mElbowR = c3dToPoint3f(points[72]); + skeletonStruct.mWristL = c3dToPoint3f(points[77]); + skeletonStruct.mElbowL = c3dToPoint3f(points[76]); skeletonStruct.mHandR = c3dToPoint3f(points[32]); skeletonStruct.mHandL = c3dToPoint3f(points[35]); - skeletonStruct.mKneeR = c3dToPoint3f(points[41]); - skeletonStruct.mKneeL = c3dToPoint3f(points[45]); + skeletonStruct.mKneeR = c3dToPoint3f(points[79]); + skeletonStruct.mKneeL = c3dToPoint3f(points[83]); + skeletonStruct.mAnkleR = c3dToPoint3f(points[80]); skeletonStruct.mHeelR = c3dToPoint3f(points[52]); skeletonStruct.mToeR = c3dToPoint3f(points[57]); + skeletonStruct.mAnkleL = c3dToPoint3f(points[84]); skeletonStruct.mHeelL = c3dToPoint3f(points[58]); skeletonStruct.mToeL = c3dToPoint3f(points[63]); diff --git a/src/moCapController.cpp b/src/moCapController.cpp index 5561ea338732848b8b685cf55a857f0c34d56f0d..8ec534dab95e9e60385ee644b20841970057cf64 100644 --- a/src/moCapController.cpp +++ b/src/moCapController.cpp @@ -95,7 +95,7 @@ void MoCapController::transformPersonSkeleton( for(const auto &pair : interpolatedPairs) { projectedPairs.emplace_back(mExtrCalib.getImagePoint(pair.start), mExtrCalib.getImagePoint(pair.end)); - if(pair.start_id == 1 && pair.end_id == 2) + if(pair.start_id == 19 && pair.end_id == 2) { neckToHead = pair; neckToHead3D = Vec3F(pair.end - pair.start); diff --git a/src/skeletonTreeFactory.cpp b/src/skeletonTreeFactory.cpp index 681aade7ff75f5eff7792f77ee3ed027d1de2a53..e98bbd5700fb48bc950c9e0017fa2598668bfa71 100644 --- a/src/skeletonTreeFactory.cpp +++ b/src/skeletonTreeFactory.cpp @@ -37,15 +37,16 @@ SkeletonTree SkeletonTreeFactory::generateTree(const XSenseStruct &points) { // Start from the root SkeletonNode root(0, points.mRoot); - SkeletonNode &neck = root.addChild(SkeletonNode(1, points.mNeck)); + SkeletonNode &neck = root.addChild(SkeletonNode(1, points.mNeck1)); // continue with the neck - neck.addChild(SkeletonNode(2, points.mHeadTop)); - SkeletonNode &lShoulder = neck.addChild(SkeletonNode(3, points.mShldrL)); + SkeletonNode &neck2 = neck.addChild(SkeletonNode(19, points.mNeck2)); + neck2.addChild(SkeletonNode(2, points.mHeadTop)); // add the left arm - SkeletonNode &lElbow = lShoulder.addChild(SkeletonNode(4, points.mElbowL)); - SkeletonNode &lWrist = lElbow.addChild(SkeletonNode(5, points.mWristL)); + SkeletonNode &lShoulder = neck.addChild(SkeletonNode(3, points.mShldrL)); + SkeletonNode &lElbow = lShoulder.addChild(SkeletonNode(4, points.mElbowL)); + SkeletonNode &lWrist = lElbow.addChild(SkeletonNode(5, points.mWristL)); lWrist.addChild(SkeletonNode(6, points.mHandL)); // add the right arm @@ -55,19 +56,21 @@ SkeletonTree SkeletonTreeFactory::generateTree(const XSenseStruct &points) rWrist.addChild(SkeletonNode(10, points.mHandR)); // add the left leg - SkeletonNode &lHip = root.addChild(SkeletonNode(11, points.mHipL)); - SkeletonNode &lKnee = lHip.addChild(SkeletonNode(12, points.mKneeL)); - SkeletonNode &lHeel = lKnee.addChild(SkeletonNode(13, points.mHeelL)); + SkeletonNode &lHip = root.addChild(SkeletonNode(11, points.mHipL)); + SkeletonNode &lKnee = lHip.addChild(SkeletonNode(12, points.mKneeL)); + SkeletonNode &lAnkle = lKnee.addChild(SkeletonNode(20, points.mAnkleL)); + SkeletonNode &lHeel = lAnkle.addChild(SkeletonNode(13, points.mHeelL)); lHeel.addChild(SkeletonNode(14, points.mToeL)); - SkeletonNode &rHip = root.addChild(SkeletonNode(15, points.mHipR)); - SkeletonNode &rKnee = rHip.addChild(SkeletonNode(16, points.mKneeR)); - SkeletonNode &rHeel = rKnee.addChild(SkeletonNode(17, points.mHeelR)); + SkeletonNode &rHip = root.addChild(SkeletonNode(15, points.mHipR)); + SkeletonNode &rKnee = rHip.addChild(SkeletonNode(16, points.mKneeR)); + SkeletonNode &rAnkle = rKnee.addChild(SkeletonNode(21, points.mAnkleR)); + SkeletonNode &rHeel = rAnkle.addChild(SkeletonNode(17, points.mHeelR)); rHeel.addChild(SkeletonNode(18, points.mToeR)); // calculate view direction of the head - cv::Point3f headUp = points.mHeadTop - points.mNeck; + cv::Point3f headUp = points.mHeadTop - points.mNeck2; cv::Point3f rightVector = points.mEarR - points.mEarL; // the direction is calculated using the cross product cv::Point3f dir = headUp.cross(rightVector); diff --git a/tests/unit_test/tst_SkeletonTree.cpp b/tests/unit_test/tst_SkeletonTree.cpp index 758183b7745955e6c6171277818d3068bfff5f11..3c925482bfb84301297c3f61da798ab01c177f4e 100644 --- a/tests/unit_test/tst_SkeletonTree.cpp +++ b/tests/unit_test/tst_SkeletonTree.cpp @@ -53,18 +53,19 @@ TEST_CASE("SkeletonTree for XSenseData is built") // check neck next auto &neckNode = rootNode.getChildById(1); - REQUIRE(neckNode.getPos() == XSENSE_DUMMY_DATA.mNeck); + REQUIRE(neckNode.getPos() == XSENSE_DUMMY_DATA.mNeck1); REQUIRE(neckNode.getChildrenCount() == 3); // head - REQUIRE_NOTHROW(neckNode.getChildById(2)); + auto &upperNeckNode = neckNode.getChildById(19); + REQUIRE_NOTHROW(upperNeckNode.getChildById(2)); // left shoulder REQUIRE_NOTHROW(neckNode.getChildById(3)); // right shoulder REQUIRE_NOTHROW(neckNode.getChildById(7)); // head - auto &headNode = neckNode.getChildById(2); + auto &headNode = upperNeckNode.getChildById(2); REQUIRE(headNode.getPos() == XSENSE_DUMMY_DATA.mHeadTop); REQUIRE(headNode.getChildrenCount() == 0); @@ -137,19 +138,26 @@ TEST_CASE("SkeletonTree for XSenseData is built") REQUIRE(lKneeNode.getPos() == XSENSE_DUMMY_DATA.mKneeL); REQUIRE(lKneeNode.getChildrenCount() == 1); - REQUIRE_NOTHROW(lKneeNode.getChildById(13)); + REQUIRE_NOTHROW(lKneeNode.getChildById(20)); + + // left ankle + auto &lAnkle = lKneeNode.getChildById(20); + REQUIRE(lAnkle.getPos() == XSENSE_DUMMY_DATA.mAnkleL); + REQUIRE(lAnkle.getChildrenCount() == 1); + + REQUIRE_NOTHROW(lAnkle.getChildById(13)); // left heel - auto &lHeelNode = lKneeNode.getChildById(13); - REQUIRE(lKneeNode.getPos() == XSENSE_DUMMY_DATA.mKneeL); - REQUIRE(lKneeNode.getChildrenCount() == 1); + auto &lHeel = lAnkle.getChildById(13); + REQUIRE(lHeel.getPos() == XSENSE_DUMMY_DATA.mHeelL); + REQUIRE(lHeel.getChildrenCount() == 1); - REQUIRE_NOTHROW(lHeelNode.getChildById(14)); + REQUIRE_NOTHROW(lHeel.getChildById(14)); - // left toe - auto &lToeNode = lHeelNode.getChildById(14); - REQUIRE(lToeNode.getPos() == XSENSE_DUMMY_DATA.mToeL); - REQUIRE(lToeNode.getChildrenCount() == 0); + // left Toe + auto &lToe = lHeel.getChildById(14); + REQUIRE(lToe.getPos() == XSENSE_DUMMY_DATA.mToeL); + REQUIRE(lToe.getChildrenCount() == 0); // right hip auto &rHipNode = rootNode.getChildById(15); @@ -163,25 +171,32 @@ TEST_CASE("SkeletonTree for XSenseData is built") REQUIRE(rKneeNode.getPos() == XSENSE_DUMMY_DATA.mKneeR); REQUIRE(rKneeNode.getChildrenCount() == 1); - REQUIRE_NOTHROW(rKneeNode.getChildById(17)); + REQUIRE_NOTHROW(rKneeNode.getChildById(21)); + + // right ankle + auto &rAnkle = rKneeNode.getChildById(21); + REQUIRE(rAnkle.getPos() == XSENSE_DUMMY_DATA.mAnkleR); + REQUIRE(rAnkle.getChildrenCount() == 1); + + REQUIRE_NOTHROW(rAnkle.getChildById(17)); // right heel - auto &rHeelNode = rKneeNode.getChildById(17); - REQUIRE(rKneeNode.getPos() == XSENSE_DUMMY_DATA.mKneeR); - REQUIRE(rKneeNode.getChildrenCount() == 1); + auto &rHeel = rAnkle.getChildById(17); + REQUIRE(rHeel.getPos() == XSENSE_DUMMY_DATA.mHeelR); + REQUIRE(rHeel.getChildrenCount() == 1); - REQUIRE_NOTHROW(rHeelNode.getChildById(18)); + REQUIRE_NOTHROW(rHeel.getChildById(18)); - // right toe - auto &rToeNode = rHeelNode.getChildById(18); - REQUIRE(rToeNode.getPos() == XSENSE_DUMMY_DATA.mToeR); - REQUIRE(rToeNode.getChildrenCount() == 0); + // right Toe + auto &rToe = rHeel.getChildById(18); + REQUIRE(rToe.getPos() == XSENSE_DUMMY_DATA.mToeR); + REQUIRE(rToe.getChildrenCount() == 0); } SECTION("Test the line data") { auto lines = skel.getLines(); - REQUIRE(lines.size() == 18); + REQUIRE(lines.size() == 21); for(SkeletonLine &line : lines) { REQUIRE(line.start_id != line.end_id); diff --git a/tests/unit_test/tst_io.cpp b/tests/unit_test/tst_io.cpp index 292f6592d3b950095430a2371fe941f13c8e335e..601efcdf460b9a6b52831648dd7be34e97542be5 100644 --- a/tests/unit_test/tst_io.cpp +++ b/tests/unit_test/tst_io.cpp @@ -501,7 +501,8 @@ SCENARIO("I want to read a XSens c3d file", "[io]") unit.set("cm"); c3d.parameter("POINT", unit); - for(int i = 0; i < 64; ++i) + constexpr int numPoints = 87; + for(int i = 0; i < numPoints; ++i) { c3d.point("marker_" + std::to_string(i + 1)); } @@ -544,7 +545,7 @@ SCENARIO("I want to read a XSens c3d file", "[io]") auto root = skeleton.getRoot(); // NOTE checking everything should be part of a test for the SkeletonFactory - REQUIRE(root.getPos() == cv::Point3f{7, 7, 7}); // pSacrum point[7] + REQUIRE(root.getPos() == cv::Point3f{0, 0, 0}); // pSacrum point[7] REQUIRE(root.getChildById(1).getPos() == cv::Point3f(15, 15, 15)); // pC7SpinalProcess point[15] } } diff --git a/tests/unit_test/tst_moCapController.cpp b/tests/unit_test/tst_moCapController.cpp index 1e8591e6fd66c947ab87edc353453db8aa4e6da6..b57727d79420731602490dd451a085e054f4ad1e 100644 --- a/tests/unit_test/tst_moCapController.cpp +++ b/tests/unit_test/tst_moCapController.cpp @@ -46,13 +46,13 @@ SCENARIO("I want to get the render data with one person loaded", "[ui]") * Resulting Lines should be: root to child; child to grandchild; */ SkeletonNode rootA{0, cv::Point3f{100, 100, 0}}; - SkeletonNode &childA = rootA.addChild({1, cv::Point3f{200, 100, 69}}); - SkeletonNode &grandchildA = childA.addChild({1, cv::Point3f{50, 50, 42}}); + SkeletonNode &childA = rootA.addChild({19, cv::Point3f{200, 100, 69}}); + SkeletonNode &grandchildA = childA.addChild({19, cv::Point3f{50, 50, 42}}); grandchildA.addChild({2, cv::Point3f{150, 150, 1337}}); SkeletonNode rootB{0, cv::Point3f{50, 50, 0}}; - SkeletonNode &childB = rootB.addChild({1, cv::Point3f{100, 50, 69}}); - SkeletonNode &grandchildB = childB.addChild({1, cv::Point3f{25, 25, 42}}); + SkeletonNode &childB = rootB.addChild({19, cv::Point3f{100, 50, 69}}); + SkeletonNode &grandchildB = childB.addChild({19, cv::Point3f{25, 25, 42}}); grandchildB.addChild({2, cv::Point3f{75, 75, 1337}}); MoCapPerson person;