Commit d240b48a3fa0cc4583b3fe8b36ec9e208746138e

Authored by Scott Klum
1 parent 9e3e99a4

More updates for procrustes and delaunay

openbr/core/core.cpp
@@ -167,7 +167,6 @@ struct AlgorithmCore @@ -167,7 +167,6 @@ struct AlgorithmCore
167 } 167 }
168 168
169 const float speed = 1000 * Globals->totalSteps / Globals->startTime.elapsed() / std::max(1, abs(Globals->parallelism)); 169 const float speed = 1000 * Globals->totalSteps / Globals->startTime.elapsed() / std::max(1, abs(Globals->parallelism));
170 - qDebug() << Globals->startTime.elapsed();  
171 if (!Globals->quiet && (Globals->totalSteps > 1)) 170 if (!Globals->quiet && (Globals->totalSteps > 1))
172 fprintf(stderr, "\rSPEED=%.1e SIZE=%.4g FAILURES=%d/%d \n", 171 fprintf(stderr, "\rSPEED=%.1e SIZE=%.4g FAILURES=%d/%d \n",
173 speed, totalBytes/totalCount, failureCount, totalCount); 172 speed, totalBytes/totalCount, failureCount, totalCount);
openbr/core/plot.cpp
@@ -247,8 +247,8 @@ float Evaluate(const Mat &amp;simmat, const Mat &amp;mask, const QString &amp;csv) @@ -247,8 +247,8 @@ float Evaluate(const Mat &amp;simmat, const Mat &amp;mask, const QString &amp;csv)
247 } 247 }
248 248
249 // Write FAR/TAR Bar Chart (BC) 249 // Write FAR/TAR Bar Chart (BC)
250 - lines.append(qPrintable(QString("BC,0.001,%1").arg(QString::number(result = getTAR(operatingPoints, 0.001), 'f', 3))));  
251 - lines.append(qPrintable(QString("BC,0.01,%1").arg(QString::number(getTAR(operatingPoints, 0.01), 'f', 3)))); 250 + lines.append(qPrintable(QString("BC,0.001,%1").arg(QString::number(getTAR(operatingPoints, 0.001), 'f', 3))));
  251 + lines.append(qPrintable(QString("BC,0.01,%1").arg(QString::number(result = getTAR(operatingPoints, 0.01), 'f', 3))));
252 252
253 // Write SD & KDE 253 // Write SD & KDE
254 points = qMin(qMin(Max_Points, genuines.size()), impostors.size()); 254 points = qMin(qMin(Max_Points, genuines.size()), impostors.size());
@@ -287,7 +287,7 @@ float Evaluate(const Mat &amp;simmat, const Mat &amp;mask, const QString &amp;csv) @@ -287,7 +287,7 @@ float Evaluate(const Mat &amp;simmat, const Mat &amp;mask, const QString &amp;csv)
287 } 287 }
288 288
289 if (!csv.isEmpty()) QtUtils::writeFile(csv, lines); 289 if (!csv.isEmpty()) QtUtils::writeFile(csv, lines);
290 - qDebug("TAR @ FAR = 0.001: %.3f\nRetrieval Rate @ Rank = %d: %.3f", result, Report_Retrieval, reportRetrievalRate); 290 + qDebug("TAR @ FAR = 0.01: %.3f\nRetrieval Rate @ Rank = %d: %.3f", result, Report_Retrieval, reportRetrievalRate);
291 return result; 291 return result;
292 } 292 }
293 293
openbr/plugins/format.cpp
@@ -659,8 +659,8 @@ class xmlFormat : public Format @@ -659,8 +659,8 @@ class xmlFormat : public Format
659 QDomDocument doc(fileName); 659 QDomDocument doc(fileName);
660 QFile f(fileName); 660 QFile f(fileName);
661 661
662 - if (!f.open(QIODevice::ReadOnly)) qFatal("Unable to open %s for reading.", qPrintable(file.flat()));  
663 - if (!doc.setContent(&f)) qFatal("Unable to parse %s.", qPrintable(file.flat())); 662 + if (!f.open(QIODevice::ReadOnly)) qWarning("Unable to open %s for reading.", qPrintable(file.flat()));
  663 + if (!doc.setContent(&f)) qWarning("Unable to parse %s.", qPrintable(file.flat()));
664 f.close(); 664 f.close();
665 665
666 QDomElement docElem = doc.documentElement(); 666 QDomElement docElem = doc.documentElement();
openbr/plugins/landmarks.cpp
@@ -81,6 +81,12 @@ class ProcrustesTransform : public Transform @@ -81,6 +81,12 @@ class ProcrustesTransform : public Transform
81 QList<QPointF> points = src.file.points(); 81 QList<QPointF> points = src.file.points();
82 QList<QRectF> rects = src.file.rects(); 82 QList<QRectF> rects = src.file.rects();
83 83
  84 + if (points.empty() || rects.empty()) {
  85 + dst = src;
  86 + qWarning("Points/rects are empty.");
  87 + return;
  88 + }
  89 +
84 if (rects.size() > 1) qWarning("More than one rect in training data templates."); 90 if (rects.size() > 1) qWarning("More than one rect in training data templates.");
85 91
86 points.append(rects[0].topLeft()); 92 points.append(rects[0].topLeft());
@@ -95,8 +101,8 @@ class ProcrustesTransform : public Transform @@ -95,8 +101,8 @@ class ProcrustesTransform : public Transform
95 Eigen::MatrixXf srcPoints(points.size(), 2); 101 Eigen::MatrixXf srcPoints(points.size(), 2);
96 102
97 for (int i = 0; i < points.size(); i++) { 103 for (int i = 0; i < points.size(); i++) {
98 - srcPoints(i,0) = points[i].x()/(norm/150.)+50;  
99 - srcPoints(i,1) = points[i].y()/(norm/150.)+50; 104 + srcPoints(i,0) = points[i].x()/(norm/100.)+50;
  105 + srcPoints(i,1) = points[i].y()/(norm/100.)+50;
100 } 106 }
101 107
102 Eigen::JacobiSVD<Eigen::MatrixXf> svd(srcPoints.transpose()*meanShape, Eigen::ComputeThinU | Eigen::ComputeThinV); 108 Eigen::JacobiSVD<Eigen::MatrixXf> svd(srcPoints.transpose()*meanShape, Eigen::ComputeThinU | Eigen::ComputeThinV);
@@ -140,11 +146,18 @@ class DelaunayTransform : public UntrainableTransform @@ -140,11 +146,18 @@ class DelaunayTransform : public UntrainableTransform
140 146
141 void project(const Template &src, Template &dst) const 147 void project(const Template &src, Template &dst) const
142 { 148 {
  149 +
143 Subdiv2D subdiv(Rect(0,0,src.m().cols,src.m().rows)); 150 Subdiv2D subdiv(Rect(0,0,src.m().cols,src.m().rows));
144 151
145 QList<cv::Point2f> points = OpenCVUtils::toPoints(src.file.points()); 152 QList<cv::Point2f> points = OpenCVUtils::toPoints(src.file.points());
146 QList<QRectF> rects = src.file.rects(); 153 QList<QRectF> rects = src.file.rects();
147 154
  155 + if (points.empty() || rects.empty()) {
  156 + dst = src;
  157 + qWarning("Points/rects are empty.");
  158 + return;
  159 + }
  160 +
148 if (rects.size() > 1) qWarning("More than one rect in training data templates."); 161 if (rects.size() > 1) qWarning("More than one rect in training data templates.");
149 162
150 points.append(OpenCVUtils::toPoint(rects[0].topLeft())); 163 points.append(OpenCVUtils::toPoint(rects[0].topLeft()));
@@ -176,7 +189,6 @@ class DelaunayTransform : public UntrainableTransform @@ -176,7 +189,6 @@ class DelaunayTransform : public UntrainableTransform
176 189
177 if (inside) { 190 if (inside) {
178 count++; 191 count++;
179 - qDebug() << count << pt[0] << pt[1] << pt[2] << "Area" << contourArea(pt);  
180 192
181 QList<Point> triangleBuffer; 193 QList<Point> triangleBuffer;
182 194
@@ -209,38 +221,36 @@ class DelaunayTransform : public UntrainableTransform @@ -209,38 +221,36 @@ class DelaunayTransform : public UntrainableTransform
209 mean[0] = src.file.get<float>("Procrustes_mean_0"); 221 mean[0] = src.file.get<float>("Procrustes_mean_0");
210 mean[1] = src.file.get<float>("Procrustes_mean_1"); 222 mean[1] = src.file.get<float>("Procrustes_mean_1");
211 223
212 - qDebug() << mean[0] << mean[1];  
213 -  
214 float norm = src.file.get<float>("Procrustes_norm"); 224 float norm = src.file.get<float>("Procrustes_norm");
215 225
216 - qDebug() << norm;  
217 -  
218 dst.m() = Mat::zeros(src.m().rows,src.m().cols,src.m().type()); 226 dst.m() = Mat::zeros(src.m().rows,src.m().cols,src.m().type());
219 227
220 - foreach(const QList<Point> &triangle, validTriangles) {  
221 - Eigen::MatrixXf srcPoints(triangle.size(), 2); 228 + QList<Point2f> mappedPoints;
222 229
223 - for (int j = 0; j < triangle.size(); j++) {  
224 - srcPoints(j,0) = (triangle[j].x-mean[0])/(norm/150.)+50;  
225 - srcPoints(j,1) = (triangle[j].y-mean[1])/(norm/150.)+50; 230 + for (int i = 0; i < validTriangles.size(); i++) {
  231 + Eigen::MatrixXf srcMat(validTriangles[i].size(), 2);
  232 +
  233 + for (int j = 0; j < validTriangles[i].size(); j++) {
  234 + srcMat(j,0) = (validTriangles[i][j].x-mean[0])/(norm/100.)+50;
  235 + srcMat(j,1) = (validTriangles[i][j].y-mean[1])/(norm/100.)+50;
226 } 236 }
227 237
228 - Eigen::MatrixXf dstMat = srcPoints*R; 238 + Eigen::MatrixXf dstMat = srcMat*R;
  239 +
  240 + Point2f srcPoints[3];
  241 + for (int j = 0; j < 3; j++) srcPoints[j] = validTriangles[i][j];
229 242
230 - Point2f test[3];  
231 - test[0] = triangle[0];  
232 - test[1] = triangle[1];  
233 - test[2] = triangle[2];  
234 Point2f dstPoints[3]; 243 Point2f dstPoints[3];
235 - dstPoints[0] = Point2f(dstMat(0,0),dstMat(0,1));  
236 - dstPoints[1] = Point2f(dstMat(1,0),dstMat(1,1));  
237 - dstPoints[2] = Point2f(dstMat(2,0),dstMat(2,1)); 244 + for (int j = 0; j < 3; j++) {
  245 + dstPoints[j] = Point2f(dstMat(j,0),dstMat(j,1));
  246 + mappedPoints.append(dstPoints[j]);
  247 + }
238 248
239 Mat buffer(src.m().rows,src.m().cols,src.m().type()); 249 Mat buffer(src.m().rows,src.m().cols,src.m().type());
240 250
241 - warpAffine(src.m(), buffer, getAffineTransform(test, dstPoints), Size(src.m().cols,src.m().rows)); 251 + warpAffine(src.m(), buffer, getAffineTransform(srcPoints, dstPoints), Size(src.m().cols,src.m().rows));
242 252
243 - Mat mask = Mat::zeros(src.m().rows, src.m().cols, CV_8U); 253 + Mat mask = Mat::zeros(src.m().rows, src.m().cols, CV_8UC1);
244 Point maskPoints[1][3]; 254 Point maskPoints[1][3];
245 maskPoints[0][0] = dstPoints[0]; 255 maskPoints[0][0] = dstPoints[0];
246 maskPoints[0][1] = dstPoints[1]; 256 maskPoints[0][1] = dstPoints[1];
@@ -251,10 +261,31 @@ class DelaunayTransform : public UntrainableTransform @@ -251,10 +261,31 @@ class DelaunayTransform : public UntrainableTransform
251 261
252 Mat output(src.m().rows,src.m().cols,src.m().type()); 262 Mat output(src.m().rows,src.m().cols,src.m().type());
253 263
  264 + // Optimize
  265 + if (i > 0) {
  266 + Mat overlap;
  267 + bitwise_and(dst.m(),mask,overlap);
  268 + for (int j = 0; j < overlap.rows; j++) {
  269 + for (int k = 0; k < overlap.cols; k++) {
  270 + if (overlap.at<uchar>(k,j) != 0) {
  271 + mask.at<uchar>(k,j) = 0;
  272 + }
  273 + }
  274 + }
  275 + }
  276 +
254 bitwise_and(buffer,mask,output); 277 bitwise_and(buffer,mask,output);
255 278
256 - dst.m() += output; 279 + dst.m() += output; // Need to xor stuff out
257 } 280 }
  281 +
  282 + Rect boundingBox = boundingRect(mappedPoints.toVector().toStdVector());
  283 + boundingBox.x += boundingBox.width * .025;
  284 + boundingBox.y += boundingBox.height * .025; // 0.025 for nose, .05 for mouth, .10 for brow
  285 + boundingBox.width *= .975;
  286 + boundingBox.height *= .975; // .975 for nose, .95 for mouth, .925 for brow
  287 +
  288 + dst.m() = Mat(dst.m(), boundingBox);
258 } 289 }
259 } 290 }
260 291
openbr/plugins/stasm4.cpp
@@ -39,7 +39,7 @@ class StasmInitializer : public Initializer @@ -39,7 +39,7 @@ class StasmInitializer : public Initializer
39 Globals->abbreviations.insert("RectFromStasmEyes","RectFromPoints([29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47],0.125,6.0)+Resize(44,164)"); 39 Globals->abbreviations.insert("RectFromStasmEyes","RectFromPoints([29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47],0.125,6.0)+Resize(44,164)");
40 Globals->abbreviations.insert("RectFromStasmBrow","RectFromPoints([17, 18, 19, 20, 21, 22, 23, 24],0.15,6)+Resize(28,132)"); 40 Globals->abbreviations.insert("RectFromStasmBrow","RectFromPoints([17, 18, 19, 20, 21, 22, 23, 24],0.15,6)+Resize(28,132)");
41 Globals->abbreviations.insert("RectFromStasmNose","RectFromPoints([48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58],0.15,1.25)"); 41 Globals->abbreviations.insert("RectFromStasmNose","RectFromPoints([48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58],0.15,1.25)");
42 - Globals->abbreviations.insert("RectFromStasmMouth","RectFromPoints([59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76],0.3,3.0)+Resize(28,68)"); 42 + Globals->abbreviations.insert("RectFromStasmMouth","RectFromPoints([59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76],0.3,2.5)");
43 } 43 }
44 }; 44 };
45 45