in visualization/FitAdam/include/FitCost.h [456:652]
void SetupCost()
{
using namespace cv;
using namespace Eigen;
joint_only = false;
double BODYJOINT_WEIGHT_Strong = 1;
double BODYJOINT_WEIGHT = 1;
double HANDJOINT_WEIGHT = 1;
WEAK_WEIGHT = 1; //for foot and face
// WEAK_WEIGHT = 0; //for foot and face
// Joint correspondences ////////////////////////////////////////////////
std::vector<Eigen::Triplet<double> > IJV;
m_nCorrespond_adam2joints = m_adam.m_indices_jointConst_adamIdx.rows();
std::cout << "m_nCorrespond_adam2joints " << m_nCorrespond_adam2joints << std::endl;
if (m_lHandJoints.size() > 0)
m_nCorrespond_adam2joints += m_adam.m_correspond_adam2lHand_adamIdx.rows();
std::cout << "m_nCorrespond_adam2joints " << m_nCorrespond_adam2joints << std::endl;
if (m_rHandJoints.size() > 0)
m_nCorrespond_adam2joints += m_adam.m_correspond_adam2rHand_adamIdx.rows();
std::cout << "m_nCorrespond_adam2joints " << m_nCorrespond_adam2joints << std::endl;
IJV.reserve(m_nCorrespond_adam2joints * 3); //A sparse selection (permutation) matrix to select parameters from SMPL joints order
m_targetPts.resize(m_nCorrespond_adam2joints * 5); //reordered target joint (CPM)
m_targetPts.setZero();
m_targetPts_weight.resize(m_nCorrespond_adam2joints * res_dim);
m_targetPts_weight_buffer.resize(m_nCorrespond_adam2joints * res_dim);
int offset = 0;
for (int ic = 0; ic<m_adam.m_indices_jointConst_adamIdx.rows(); ic++)
{
IJV.push_back(Triplet<double>(ic * 3 + 0, m_adam.m_indices_jointConst_adamIdx(ic) * 3 + 0, 1.0));
IJV.push_back(Triplet<double>(ic * 3 + 1, m_adam.m_indices_jointConst_adamIdx(ic) * 3 + 1, 1.0));
IJV.push_back(Triplet<double>(ic * 3 + 2, m_adam.m_indices_jointConst_adamIdx(ic) * 3 + 2, 1.0));
m_targetPts(ic * 5 + 0) = m_bodyJoints(0, m_adam.m_indices_jointConst_smcIdx(ic)); //Joints_: 3 x #Joints matrix
m_targetPts(ic * 5 + 1) = m_bodyJoints(1, m_adam.m_indices_jointConst_smcIdx(ic));
m_targetPts(ic * 5 + 2) = m_bodyJoints(2, m_adam.m_indices_jointConst_smcIdx(ic));
m_targetPts(ic * 5 + 3) = m_bodyJoints(3, m_adam.m_indices_jointConst_smcIdx(ic));
m_targetPts(ic * 5 + 4) = m_bodyJoints(4, m_adam.m_indices_jointConst_smcIdx(ic));
int smcjoint = m_adam.m_indices_jointConst_smcIdx(ic);
if (smcjoint == 4 || smcjoint == 10 || smcjoint == 3 || smcjoint == 9 || smcjoint == 7 || smcjoint == 13)
{
for (int i = 0; i < res_dim; i++)
{
m_targetPts_weight[ic * res_dim + i] = BODYJOINT_WEIGHT_Strong;
m_targetPts_weight_buffer[ic * res_dim + i] = BODYJOINT_WEIGHT_Strong;
}
}
else
{
for (int i = 0; i < res_dim; i++)
{
m_targetPts_weight[ic * res_dim + i] = BODYJOINT_WEIGHT;
m_targetPts_weight_buffer[ic * res_dim + i] = BODYJOINT_WEIGHT;
}
}
}
offset += m_adam.m_indices_jointConst_adamIdx.rows();
m_spineResIdx = -1;
//Hands
if (m_lHandJoints.size() > 0)
{
//correspondences.reserve(nCorrespond_);
for (int ic = 0; ic < m_adam.m_correspond_adam2lHand_adamIdx.rows(); ic++)
{
IJV.push_back(Triplet<double>(offset * 3 + ic * 3 + 0, m_adam.m_correspond_adam2lHand_adamIdx(ic) * 3 + 0, 1.0));
IJV.push_back(Triplet<double>(offset * 3 + ic * 3 + 1, m_adam.m_correspond_adam2lHand_adamIdx(ic) * 3 + 1, 1.0));
IJV.push_back(Triplet<double>(offset * 3 + ic * 3 + 2, m_adam.m_correspond_adam2lHand_adamIdx(ic) * 3 + 2, 1.0));
m_targetPts(offset * 5 + ic * 5 + 0) = m_lHandJoints(0, m_adam.m_correspond_adam2lHand_lHandIdx(ic)); //Joints_: 3 x #Joints matrix
m_targetPts(offset * 5 + ic * 5 + 1) = m_lHandJoints(1, m_adam.m_correspond_adam2lHand_lHandIdx(ic));
m_targetPts(offset * 5 + ic * 5 + 2) = m_lHandJoints(2, m_adam.m_correspond_adam2lHand_lHandIdx(ic));
m_targetPts(offset * 5 + ic * 5 + 3) = m_lHandJoints(3, m_adam.m_correspond_adam2lHand_lHandIdx(ic));
m_targetPts(offset * 5 + ic * 5 + 4) = m_lHandJoints(4, m_adam.m_correspond_adam2lHand_lHandIdx(ic));
for (int i = 0; i < res_dim; i++)
{
m_targetPts_weight[(ic + offset) * res_dim + i] = HANDJOINT_WEIGHT;
m_targetPts_weight_buffer[(ic + offset) * res_dim + i] = HANDJOINT_WEIGHT;
}
}
offset += m_adam.m_correspond_adam2lHand_adamIdx.rows();
}
if (m_rHandJoints.size() > 0)
{
//correspondences.reserve(nCorrespond_);
for (int ic = 0; ic < m_adam.m_correspond_adam2rHand_adamIdx.rows(); ic++)
{
IJV.push_back(Triplet<double>(offset * 3 + ic * 3 + 0, m_adam.m_correspond_adam2rHand_adamIdx(ic) * 3 + 0, 1.0));
IJV.push_back(Triplet<double>(offset * 3 + ic * 3 + 1, m_adam.m_correspond_adam2rHand_adamIdx(ic) * 3 + 1, 1.0));
IJV.push_back(Triplet<double>(offset * 3 + ic * 3 + 2, m_adam.m_correspond_adam2rHand_adamIdx(ic) * 3 + 2, 1.0));
m_targetPts(offset * 5 + ic * 5 + 0) = m_rHandJoints(0, m_adam.m_correspond_adam2rHand_rHandIdx(ic)); //Joints_: 3 x #Joints matrix
m_targetPts(offset * 5 + ic * 5 + 1) = m_rHandJoints(1, m_adam.m_correspond_adam2rHand_rHandIdx(ic));
m_targetPts(offset * 5 + ic * 5 + 2) = m_rHandJoints(2, m_adam.m_correspond_adam2rHand_rHandIdx(ic));
m_targetPts(offset * 5 + ic * 5 + 3) = m_rHandJoints(3, m_adam.m_correspond_adam2rHand_rHandIdx(ic));
m_targetPts(offset * 5 + ic * 5 + 4) = m_rHandJoints(4, m_adam.m_correspond_adam2rHand_rHandIdx(ic));
for (int i = 0; i < res_dim; i++)
{
m_targetPts_weight[(ic + offset) * res_dim + i] = HANDJOINT_WEIGHT;
m_targetPts_weight_buffer[(ic + offset) * res_dim + i] = HANDJOINT_WEIGHT;
}
}
}
// Precomputing
m_Ajoints.resize(m_nCorrespond_adam2joints * 3, TotalModel::NUM_JOINTS * 3);
m_Ajoints.reserve(m_nCorrespond_adam2joints * 3);
m_Ajoints.setFromTriplets(IJV.begin(), IJV.end());
m_mat_vert2joints = m_Ajoints*m_adam.m_J_reg_smc;
// //////////////////////////////////////////////////////////////////////////
// // Surface point correspondences ////////////////////////////////////////////////
// if (m_rfoot_joints.cols() > 0) //3xNumofJoint (bigToe, smallToe, heel)
// {
// cv::Point3d targetPt = cv::Point3d(m_rfoot_joints(0, 0), m_rfoot_joints(1, 0), m_rfoot_joints(2, 0));
// corres_vertex2targetpt.push_back(std::make_pair(14238, targetPt)); //right_bigToe //-1 due to 1based in matlab
// targetPt = cv::Point3d(m_rfoot_joints(0, 1), m_rfoot_joints(1, 1), m_rfoot_joints(2, 1));
// corres_vertex2targetpt.push_back(std::make_pair(14288, targetPt)); //right_smallToe
// targetPt = cv::Point3d(m_rfoot_joints(0, 2), m_rfoot_joints(1, 2), m_rfoot_joints(2, 2));
// corres_vertex2targetpt.push_back(std::make_pair(14357, targetPt)); //right_heel
// targetPt = cv::Point3d(m_rfoot_joints(0, 2), m_rfoot_joints(1, 2), m_rfoot_joints(2, 2));
// corres_vertex2targetpt.push_back(std::make_pair(14361, targetPt)); //right_heel
// }
// if (m_lfoot_joints.cols() > 0)
// {
// cv::Point3d targetPt = cv::Point3d(m_lfoot_joints(0, 1), m_lfoot_joints(1, 0), m_lfoot_joints(2, 0));
// corres_vertex2targetpt.push_back(std::make_pair(12239, targetPt)); //left big toe
// targetPt = cv::Point3d(m_lfoot_joints(0, 1), m_lfoot_joints(1, 1), m_lfoot_joints(2, 1));
// corres_vertex2targetpt.push_back(std::make_pair(12289, targetPt)); //left small toe
// targetPt = cv::Point3d(m_lfoot_joints(0, 2), m_lfoot_joints(1, 2), m_lfoot_joints(2, 2));
// corres_vertex2targetpt.push_back(std::make_pair(12368, targetPt)); //left heel
// targetPt = cv::Point3d(m_lfoot_joints(0, 2), m_lfoot_joints(1, 2), m_lfoot_joints(2, 2));
// corres_vertex2targetpt.push_back(std::make_pair(12357, targetPt)); //left heel
// }
// Faces. m_FaceJoints: 3x face70JointsNum
if (this->fit_face_ && m_FaceJoints.cols() > 0)
{
for (int r = 0; r < m_adam.m_correspond_adam2face70_adamIdx.rows(); ++r)
{
int adamVertexIdx = m_adam.m_correspond_adam2face70_adamIdx(r);
int face70ID = m_adam.m_correspond_adam2face70_face70Idx(r);
if (face70ID < 0)
continue;
if (m_FaceJoints(0, face70ID) == 0.0)
continue;
std::vector<double> targetPt = {m_FaceJoints(0, face70ID), m_FaceJoints(1, face70ID), m_FaceJoints(2, face70ID), m_FaceJoints(3, face70ID), m_FaceJoints(4, face70ID)};
corres_vertex2targetpt.push_back(std::make_pair(adamVertexIdx, targetPt));
}
}
//CoCo Faces
if (m_bodyJoints(0, 1) != 0.0) //nose
{
std::vector<double> targetPt = {m_bodyJoints(0, 1), m_bodyJoints(1, 1), m_bodyJoints(2, 1), m_bodyJoints(3, 1), m_bodyJoints(4, 1)};
corres_vertex2targetpt.push_back(std::make_pair(8130, targetPt));
}
if (m_bodyJoints(0, 16) != 0.0) //left ear
{
std::vector<double> targetPt = {m_bodyJoints(0, 16), m_bodyJoints(1, 16), m_bodyJoints(2, 16), m_bodyJoints(3, 16), m_bodyJoints(4, 16)};
corres_vertex2targetpt.push_back(std::make_pair(6970, targetPt));
}
if (m_bodyJoints(0, 18) != 0.0) //right ear
{
std::vector<double> targetPt = {m_bodyJoints(0, 18), m_bodyJoints(1, 18), m_bodyJoints(2, 18), m_bodyJoints(3, 18), m_bodyJoints(4, 18)};
corres_vertex2targetpt.push_back(std::make_pair(10088, targetPt));
}
m_nCorrespond_adam2pts = corres_vertex2targetpt.size();
// Other setting ////////////////////////////////////////////////////////////
SparseMatrix<double, ColMajor> eye3(3, 3); eye3.setIdentity();
m_dVdt = kroneckerProduct(VectorXd::Ones(TotalModel::NUM_VERTICES), eye3); //Precomputing
m_nResiduals = m_nCorrespond_adam2joints * res_dim + m_nCorrespond_adam2pts * res_dim;
std::cout << "m_nResiduals " << m_nResiduals << std::endl;
CostFunction::set_num_residuals(m_nResiduals);
auto parameter_block_sizes = CostFunction::mutable_parameter_block_sizes();
parameter_block_sizes->clear();
parameter_block_sizes->push_back(3); // Translation
parameter_block_sizes->push_back(TotalModel::NUM_JOINTS * 3); // SMPL Pose
parameter_block_sizes->push_back(TotalModel::NUM_SHAPE_COEFFICIENTS); // Shape coefficients
if (this->fit_face_) parameter_block_sizes->push_back(TotalModel::NUM_EXP_BASIS_COEFFICIENTS); // Face expression coefficients
}