@@ -601,7 +601,6 @@ namespace op
601
601
// poseKeypoints from neck-part distances
602
602
if (poseModel == PoseModel::BODY_25D)
603
603
{
604
- // TODO: Get scaleDownFactor as parameter, NOT HARD-CODED!
605
604
const auto scaleDownFactor = 8 ;
606
605
Array<T> poseKeypoints2 = poseKeypoints.clone ();
607
606
const auto rootIndex = 1 ;
@@ -610,10 +609,24 @@ namespace op
610
609
// const auto numberPeople = intRound(peaksPtr[rootNumberIndex]);
611
610
poseKeypoints.reset ({numberPeople, (int )numberBodyParts, 3 }, 0 );
612
611
poseScores.reset (numberPeople, 0 );
613
- const std::vector<float > multiplier{3.99662 , 2.83036 , 6.70038 , 7.98778 , 2.83036 , 6.6937 , 7.98559 , 9.03892 , // BODY_25D
614
- 9.25788 , 13.5094 , 18.4561 , 9.25499 , 13.5129 , 18.452 ,
615
- 4.45502 , 4.45194 , 4.06345 , 4.0489 ,
616
- 18.452 , 18.452 , 18.452 , 18.4561 , 18.4561 , 18.4561 };
612
+ const std::vector<float > average{
613
+ 0 .f , -2 .76364f , -1 .3345f , 0 .f , -1 .95322f , 3 .95679f , -1 .20664f , 4 .76543f ,
614
+ 1 .3345f , 0 .f , 1 .92318f , 3 .96891f , 1 .17999f , 4 .7901f , 0 .f , 7 .72201f ,
615
+ -0 .795236f , 7 .74017f , -0 .723963f , 11 .209f , -0 .651316f , 15 .6972f ,
616
+ 0 .764623f , 7 .74869f , 0 .70755f , 11 .2307f , 0 .612832f , 15 .7281f ,
617
+ -0 .123134f , -3 .43515f , 0 .111775f , -3 .42761f ,
618
+ -0 .387066f , -3 .16603f , 0 .384038f , -3 .15951f ,
619
+ 0 .344764f , 12 .9666f , 0 .624157f , 12 .9057f , 0 .195454f , 12 .565f ,
620
+ -1 .06074f , 12 .9951f , -1 .2427f , 12 .9309f , -0 .800837f , 12 .5845f };
621
+ const std::vector<float > sigma{
622
+ 3 .39629f , 3 .15605f , 3 .16913f , 1 .8234f , 5 .82252f , 5 .05674f , 7 .09876f , 6 .64574f ,
623
+ 3 .16913f , 1 .8234f , 5 .79415f , 5 .01424f , 7 .03866f , 6 .62427f , 5 .52593f , 6 .75962f ,
624
+ 5 .91224f , 6 .87241f , 8 .66473f , 10 .1792f , 11 .5871f , 13 .6565f ,
625
+ 5 .86653f , 6 .89568f , 8 .68067f , 10 .2127f , 11 .5954f , 13 .6722f ,
626
+ 3 .3335f , 3 .49128f , 3 .34476f , 3 .50079f ,
627
+ 2 .93982f , 3 .11151f , 2 .95006f , 3 .11004f ,
628
+ 9 .69408f , 7 .58921f , 9 .71193f , 7 .44185f , 9 .19343f , 7 .11157f ,
629
+ 9 .16848f , 7 .86122f , 9 .07613f , 7 .83682f , 8 .91951f , 7 .33715f };
617
630
// To get ideal distance
618
631
const auto numberBodyPartsAndBkgAndPAFChannels = numberBodyParts + 1 + bodyPartPairs.size ();
619
632
const auto heatMapOffset = heatMapSize.area ();
@@ -639,64 +652,76 @@ namespace op
639
652
const auto offsetIndex = numberBodyPartsAndBkgAndPAFChannels + 2 *bpChannel;
640
653
const auto * mapX = heatMapPtr + offsetIndex * heatMapOffset;
641
654
const auto * mapY = heatMapPtr + (offsetIndex+1 ) * heatMapOffset;
642
- const auto increaseRatio = multiplier[bpChannel] *scaleDownFactor*scaleFactor ;
655
+ const auto increaseRatio = scaleFactor *scaleDownFactor;
643
656
// Set (x,y) coordinates from the distance
657
+ const auto index2 = 2 *bpChannel;
658
+ // // Not refined method
644
659
// const auto index = intRound(rootY/scaleFactor)*heatMapSize.x + intRound(rootX/scaleFactor);
645
- // const Point<T> neckPartDist{increaseRatio*mapX[index], increaseRatio*mapY[index]};
660
+ // const Point<T> neckPartDist{increaseRatio*(mapX[index]*sigma[index2]+average[index2]),
661
+ // increaseRatio*(mapY[index]*sigma[index2+1]+average[index2+1])};
646
662
// poseKeypoints[{p,bpOrig,0}] = rootX + neckPartDist.x;
647
663
// poseKeypoints[{p,bpOrig,1}] = rootY + neckPartDist.y;
648
- // Refinement
664
+ // Refined method
665
+ const auto constant = 5 ;
649
666
Point<T> neckPartDistRefined{0 , 0 };
650
- for (auto y = intRound (rootY/scaleFactor) - 3 ; y < intRound (rootY/scaleFactor) + 4 ; y++)
667
+ for (auto y = intRound (rootY/scaleFactor) - constant;
668
+ y < intRound (rootY/scaleFactor) + constant+1 ; y++)
651
669
{
652
- for (auto x = intRound (rootX/scaleFactor) - 3 ; x < intRound (rootX/scaleFactor) + 4 ; x++)
670
+ for (auto x = intRound (rootX/scaleFactor) - constant;
671
+ x < intRound (rootX/scaleFactor) + constant+1 ; x++)
653
672
{
654
673
const auto index = y*heatMapSize.x + x;
655
674
neckPartDistRefined.x += mapX[index];
656
675
neckPartDistRefined.y += mapY[index];
657
676
}
658
677
}
659
- neckPartDistRefined *= increaseRatio/49 ;
678
+ auto sqConst = (constant*2 +1 );
679
+ sqConst *= sqConst;
680
+ neckPartDistRefined = Point<T>{
681
+ neckPartDistRefined.x *sigma[index2]+sqConst*average[index2],
682
+ neckPartDistRefined.y *sigma[index2+1 ]+sqConst*average[index2+1 ],
683
+ };
684
+ neckPartDistRefined *= increaseRatio/sqConst;
660
685
const auto partX = rootX + neckPartDistRefined.x ;
661
686
const auto partY = rootY + neckPartDistRefined.y ;
662
687
poseKeypoints[{p,bpOrig,0 }] = partX;
663
688
poseKeypoints[{p,bpOrig,1 }] = partY;
664
689
// Set (temporary) body part score
665
690
poseKeypoints[{p,bpOrig,2 }] = T (0.0501 );
666
- // Associate estimated keypoint with closest one
667
- const auto candidateNumberIndex = bpOrig*(maxPeaks+1 )*3 ;
668
- const auto numberCandidates = intRound (peaksPtr[candidateNumberIndex]);
669
- int closestIndex = -1 ;
670
- T closetValue = std::numeric_limits<T>::max ();
671
- for (auto i = 0 ; i < numberCandidates ; i++)
672
- {
673
- const auto candidateXYSIndex = candidateNumberIndex+3 *(1 +i);
674
- const auto diffX = partX-scaleFactor*peaksPtr[candidateXYSIndex];
675
- const auto diffY = partY-scaleFactor*peaksPtr[candidateXYSIndex+1 ];
676
- const auto dist = (diffX*diffX + diffY*diffY);
677
- if (closetValue > dist)
678
- {
679
- closetValue = dist;
680
- closestIndex = candidateXYSIndex;
681
- }
682
- }
683
- if (closestIndex != -1 )
684
- {
685
- const auto estimatedDist = neckPartDistRefined.x *neckPartDistRefined.x
686
- + neckPartDistRefined.y *neckPartDistRefined.y ;
687
- const auto x = scaleFactor*peaksPtr[closestIndex];
688
- const auto y = scaleFactor*peaksPtr[closestIndex+1 ];
689
- const auto candidateDist = (rootX-x)*(rootX-x)+(rootY-y)*(rootY-y);
690
- if (estimatedDist/candidateDist < 1.1 && estimatedDist/candidateDist > 0.9 )
691
- {
692
- poseKeypoints[{p,bpOrig,0 }] = x;
693
- poseKeypoints[{p,bpOrig,1 }] = y;
694
- // Set body part score
695
- const auto s = peaksPtr[closestIndex+2 ];
696
- // poseKeypoints[{p,bpOrig,2}] = s -;
697
- poseKeypoints[{p,bpOrig,2 }] = s;
698
- }
699
- }
691
+ // // Associate estimated keypoint with closest one
692
+ // const auto candidateNumberIndex = bpOrig*(maxPeaks+1)*3;
693
+ // const auto numberCandidates = intRound(peaksPtr[candidateNumberIndex]);
694
+ // int closestIndex = -1;
695
+ // T closetValue = std::numeric_limits<T>::max();
696
+ // for (auto i = 0 ; i < numberCandidates ; i++)
697
+ // {
698
+ // const auto candidateXYSIndex = candidateNumberIndex+3*(1+i);
699
+ // const auto diffX = partX-scaleFactor*peaksPtr[candidateXYSIndex];
700
+ // const auto diffY = partY-scaleFactor*peaksPtr[candidateXYSIndex+1];
701
+ // const auto dist = (diffX*diffX + diffY*diffY);
702
+ // if (closetValue > dist)
703
+ // {
704
+ // closetValue = dist;
705
+ // closestIndex = candidateXYSIndex;
706
+ // }
707
+ // }
708
+ // if (closestIndex != -1)
709
+ // {
710
+ // const auto estimatedDist = neckPartDistRefined.x*neckPartDistRefined.x
711
+ // + neckPartDistRefined.y*neckPartDistRefined.y;
712
+ // const auto x = scaleFactor*peaksPtr[closestIndex];
713
+ // const auto y = scaleFactor*peaksPtr[closestIndex+1];
714
+ // const auto candidateDist = (rootX-x)*(rootX-x)+(rootY-y)*(rootY-y);
715
+ // if (estimatedDist/candidateDist < 1.1 && estimatedDist/candidateDist > 0.9)
716
+ // {
717
+ // poseKeypoints[{p,bpOrig,0}] = x;
718
+ // poseKeypoints[{p,bpOrig,1}] = y;
719
+ // // Set body part score
720
+ // const auto s = peaksPtr[closestIndex+2];
721
+ // // poseKeypoints[{p,bpOrig,2}] = s -;
722
+ // poseKeypoints[{p,bpOrig,2}] = s;
723
+ // }
724
+ // }
700
725
// Set poseScore
701
726
poseScores[p] += poseKeypoints[{p,bpOrig,2 }];
702
727
}
0 commit comments