49#include <QRegularExpression>
62MatrixXf
Warp::calculate(
const MatrixXf &sLm,
const MatrixXf &dLm,
const MatrixXf &sVert)
64 MatrixXf warpWeight, polWeight;
65 calcWeighting(sLm, dLm, warpWeight, polWeight);
66 MatrixXf wVert = warpVertices(sVert, sLm, warpWeight, polWeight);
72void Warp::calculate(
const MatrixXf & sLm,
const MatrixXf &dLm, QList<MatrixXf> & vertList)
74 MatrixXf warpWeight, polWeight;
75 calcWeighting(sLm, dLm, warpWeight, polWeight);
77 for (
int i=0; i<vertList.size(); i++)
79 vertList.replace(i,warpVertices(vertList.at(i), sLm, warpWeight, polWeight));
86bool Warp::calcWeighting(
const MatrixXf &sLm,
const MatrixXf &dLm, MatrixXf& warpWeight, MatrixXf& polWeight)
88 MatrixXf K = MatrixXf::Zero(sLm.rows(),sLm.rows());
89 for (
int i=0; i<sLm.rows(); i++)
90 K.col(i)=((sLm.rowwise()-sLm.row(i)).rowwise().norm());
94 MatrixXf P (sLm.rows(),4);
95 P << MatrixXf::Ones(sLm.rows(),1),sLm;
98 MatrixXf L ((sLm.rows()+4),(sLm.rows()+4));
100 P.transpose(),MatrixXf::Zero(4,4);
103 MatrixXf
Y ((dLm.rows()+4),3);
111 MatrixXf W ((dLm.rows()+4),3);
112 Eigen::FullPivLU <MatrixXf> Lu(L);
116 warpWeight = W.topRows(sLm.rows());
117 polWeight = W.bottomRows(4);
124MatrixXf Warp::warpVertices(
const MatrixXf &sVert,
const MatrixXf & sLm,
const MatrixXf& warpWeight,
const MatrixXf& polWeight)
126 MatrixXf wVert = sVert * polWeight.bottomRows(3);
127 wVert.rowwise() += polWeight.row(0);
132 MatrixXf K = MatrixXf::Zero(sVert.rows(),sLm.rows());
133 for (
int i=0; i<sVert.rows(); i++)
134 K.row(i)=((sLm.rowwise()-sVert.row(i)).rowwise().norm().transpose());
137 wVert += K*warpWeight;
147 QFile file(electrodeFileName);
149 if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
150 qDebug()<<
"Error opening file";
155 double numberElectrodes;
156 QTextStream in(&file);
161 QString line = in.readLine();
162 QStringList fields = line.split(QRegularExpression(
"\\s+"));
165 if(fields.at(fields.size()-1) ==
"")
170 numberElectrodes = fields.at(fields.size()-1).toDouble();
171 electrodes = MatrixXf::Zero(numberElectrodes, 3);
176 x << fields.at(fields.size()-3).toFloat(),fields.at(fields.size()-2).toFloat(),fields.at(fields.size()-1).toFloat();
177 electrodes.row(i-1)=x.transpose();
189 std::ifstream inFile(electrodeFileName);
191 if(!inFile.is_open()) {
192 qDebug()<<
"Error opening file";
198 double numberElectrodes;
202 while(std::getline(inFile, line)){
203 std::vector<std::string> fields;
204 std::stringstream stream{line};
208 while(stream >> element){
209 fields.push_back(std::move(element));
215 numberElectrodes = std::stod(fields.at(fields.size()-1));
216 electrodes = MatrixXf::Zero(numberElectrodes, 3);
222 x << std::stof(fields.at(fields.size()-3)), std::stof(fields.at(fields.size()-2)), std::stof(fields.at(fields.size()-1));
223 electrodes.row(i-1)=x.transpose();
Thin-plate-spline 3-D warp from landmark correspondences.
Shared utilities (I/O helpers, spectral analysis, layout management, warp algorithms).
Eigen::MatrixXf readsLm(const QString &electrodeFileName)
Eigen::MatrixXf calculate(const Eigen::MatrixXf &sLm, const Eigen::MatrixXf &dLm, const Eigen::MatrixXf &sVert)