Commit 9f84bcdb460ae5bb67bb10b5932e42296d4c0d50

Authored by Brendan Klare
1 parent dd300435

project stable, still verifying accuracy

Showing 1 changed file with 23 additions and 49 deletions
openbr/plugins/landmarks.cpp
@@ -150,16 +150,15 @@ class ProcrustesAlignTransform : public Transform @@ -150,16 +150,15 @@ class ProcrustesAlignTransform : public Transform
150 150
151 Eigen::MatrixXf referenceShape; 151 Eigen::MatrixXf referenceShape;
152 152
153 - MatrixXf getRotation(MatrixXf ref, MatrixXf sample) { 153 + MatrixXf getRotation(MatrixXf ref, MatrixXf sample) const {
154 MatrixXf R = ref.transpose() * sample; 154 MatrixXf R = ref.transpose() * sample;
155 JacobiSVD<MatrixXf> svd(R, ComputeFullU | ComputeFullV); 155 JacobiSVD<MatrixXf> svd(R, ComputeFullU | ComputeFullV);
156 R = svd.matrixU() * svd.matrixV(); 156 R = svd.matrixU() * svd.matrixV();
157 -  
158 return R; 157 return R;
159 } 158 }
160 159
161 //Converts x y points in a single vector to two column matrix 160 //Converts x y points in a single vector to two column matrix
162 - MatrixXf vectorToMatrix(MatrixXf vector) { 161 + MatrixXf vectorToMatrix(MatrixXf vector) const {
163 int n = vector.rows(); 162 int n = vector.rows();
164 MatrixXf matrix(n / 2, 2); 163 MatrixXf matrix(n / 2, 2);
165 for (int i = 0; i < n / 2; i++) { 164 for (int i = 0; i < n / 2; i++) {
@@ -170,7 +169,7 @@ class ProcrustesAlignTransform : public Transform @@ -170,7 +169,7 @@ class ProcrustesAlignTransform : public Transform
170 return matrix; 169 return matrix;
171 } 170 }
172 171
173 - MatrixXf matrixToVector(MatrixXf matrix) { 172 + MatrixXf matrixToVector(MatrixXf matrix) const {
174 int n2 = matrix.rows(); 173 int n2 = matrix.rows();
175 MatrixXf vector(n2 * 2, 1); 174 MatrixXf vector(n2 * 2, 1);
176 for (int i = 0; i < n2; i++) { 175 for (int i = 0; i < n2; i++) {
@@ -181,6 +180,7 @@ class ProcrustesAlignTransform : public Transform @@ -181,6 +180,7 @@ class ProcrustesAlignTransform : public Transform
181 return vector; 180 return vector;
182 } 181 }
183 182
  183 +
184 void train(const TemplateList &data) 184 void train(const TemplateList &data)
185 { 185 {
186 MatrixXf points(data[0].file.points().size() * 2, data.size()); 186 MatrixXf points(data[0].file.points().size() * 2, data.size());
@@ -214,72 +214,46 @@ class ProcrustesAlignTransform : public Transform @@ -214,72 +214,46 @@ class ProcrustesAlignTransform : public Transform
214 //Normalize rotation 214 //Normalize rotation
215 MatrixXf refPrev; 215 MatrixXf refPrev;
216 referenceShape = vectorToMatrix(points.rowwise().sum() / points.cols()); 216 referenceShape = vectorToMatrix(points.rowwise().sum() / points.cols());
217 - float diff = FLT_MAX;  
218 217
219 for (int j = 0; j < points.cols(); j++) { 218 for (int j = 0; j < points.cols(); j++) {
220 MatrixXf p = vectorToMatrix(points.col(j)); 219 MatrixXf p = vectorToMatrix(points.col(j));
221 MatrixXf R = getRotation(referenceShape, p); 220 MatrixXf R = getRotation(referenceShape, p);
222 - p = p * R.transpose(); 221 + p = p * R;
223 points.col(j) = matrixToVector(p); 222 points.col(j) = matrixToVector(p);
224 } 223 }
225 224
226 referenceShape = vectorToMatrix(points.rowwise().sum() / points.cols()); 225 referenceShape = vectorToMatrix(points.rowwise().sum() / points.cols());
227 } 226 }
228 227
229 - void procustesAlgin(const Template &src, Template &dst, MatrixXf p) {  
230 228
  229 + void project(const Template &src, Template &dst) const
  230 + {
231 QList<QPointF> imagePoints = src.file.points(); 231 QList<QPointF> imagePoints = src.file.points();
232 MatrixXf p(imagePoints.size() * 2, 1); 232 MatrixXf p(imagePoints.size() * 2, 1);
233 for (int i = 0; i < imagePoints.size(); i++) { 233 for (int i = 0; i < imagePoints.size(); i++) {
234 - 234 + p(i * 2) = imagePoints[i].x();
  235 + p(i * 2 + 1) = imagePoints[i].y();
235 } 236 }
236 - } 237 + float norm = p.norm();
  238 + p = vectorToMatrix(p);
237 239
238 - void project(const Template &src, Template &dst) const  
239 - {  
240 - MatrixXf p(src.file.points().size() * 2, 1); 240 + //Nomralize translation
  241 + p.col(0) = p.col(0) - MatrixXf::Ones(p.rows(),1) * (p.col(0).sum() / p.rows());
  242 + p.col(1) = p.col(1) - MatrixXf::Ones(p.rows(),1) * (p.col(1).sum() / p.rows());
241 243
242 -  
243 - // Normalize all sets of points  
244 - for (int j = 0; j < data.size(); j++) {  
245 - QList<QPointF> imagePoints = data[j].file.points();  
246 -  
247 - float meanX = 0,  
248 - meanY = 0;  
249 - for (int i = 0; i < imagepoints.size(); i++) {  
250 - points(i * 2, j) = imagepoints[i].x();  
251 - points(i * 2 + 1, j) = imagepoints[i].y();  
252 - meanX += imagePoints[i].x();  
253 - meanY += imagePoints[i].y();  
254 - }  
255 - meanX /= imagePoints.size();  
256 - meanY /= imagePoints.size();  
257 -  
258 - for (int i = 0; i < imagePoints.size(); i++) {  
259 - points(i * 2, j) -= meanX;  
260 - points(i * 2 + 1, j) -= meanY;  
261 - }  
262 - }  
263 -  
264 -  
265 - //normalize scale  
266 - for (int i = 0; i < points.cols(); i++)  
267 - points.col(i) = points.col(i) / points.col(i).norm(); 244 + //Normalize scale
  245 + p /= norm;
268 246
269 //Normalize rotation 247 //Normalize rotation
270 - MatrixXf refPrev;  
271 - referenceShape = vectorToMatrix(points.rowwise().sum() / points.cols());  
272 - float diff = FLT_MAX;  
273 -  
274 - for (int j = 0; j < points.cols(); j++) {  
275 - MatrixXf p = vectorToMatrix(points.col(j));  
276 - MatrixXf R = getRotation(referenceShape, p);  
277 - p = p * R.transpose();  
278 - points.col(j) = matrixToVector(p);  
279 - } 248 + MatrixXf R = getRotation(referenceShape, p);
  249 + p = p * R;
280 250
281 - referenceShape = vectorToMatrix(points.rowwise().sum() / points.cols()); 251 + QList<QPointF> procrustesPoints;
  252 + for (int i = 0; i < p.rows(); i++)
  253 + procrustesPoints.append(QPointF(p(i, 0), p(i, 1)));
282 254
  255 + dst = src;
  256 + dst.file.setList<QPointF>("ProcrustesPoints", procrustesPoints);
283 } 257 }
284 258
285 void store(QDataStream &stream) const 259 void store(QDataStream &stream) const