Commit d240b48a3fa0cc4583b3fe8b36ec9e208746138e
1 parent
9e3e99a4
More updates for procrustes and delaunay
Showing
5 changed files
with
60 additions
and
30 deletions
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 &simmat, const Mat &mask, const QString &csv) | @@ -247,8 +247,8 @@ float Evaluate(const Mat &simmat, const Mat &mask, const QString &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 &simmat, const Mat &mask, const QString &csv) | @@ -287,7 +287,7 @@ float Evaluate(const Mat &simmat, const Mat &mask, const QString &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 |