diff --git a/3rdparty/stasm4.0.0/stasm/stasm_lib.cpp b/3rdparty/stasm4.0.0/stasm/stasm_lib.cpp index 9c9a7c1..879f157 100755 --- a/3rdparty/stasm4.0.0/stasm/stasm_lib.cpp +++ b/3rdparty/stasm4.0.0/stasm/stasm_lib.cpp @@ -157,7 +157,6 @@ int stasm_search_auto_ext( // extended version of stasm_search_auto { int returnval = 1; // assume success *foundface = 0; // but assume no face found - CatchOpenCvErrs(); try { CheckStasmInit(); @@ -204,7 +203,6 @@ int stasm_search_auto_ext( // extended version of stasm_search_auto { returnval = 0; // a call was made to Err or a CV_Assert failed } - UncatchOpenCvErrs(); return returnval; } diff --git a/openbr/core/bee.cpp b/openbr/core/bee.cpp index fb840ca..1d2658c 100644 --- a/openbr/core/bee.cpp +++ b/openbr/core/bee.cpp @@ -96,7 +96,7 @@ void BEE::writeSigset(const QString &sigset, const br::FileList &files, bool ign if ((key == "Index") || (key == "Subject")) continue; metadata.append(key+"=\""+QtUtils::toString(file.value(key))+"\""); } - lines.append("\t("Subject") +"\">"); + lines.append("\t"); lines.append("\t\t"); lines.append("\t"); } diff --git a/openbr/core/plot.cpp b/openbr/core/plot.cpp index a300a11..0ef731c 100644 --- a/openbr/core/plot.cpp +++ b/openbr/core/plot.cpp @@ -269,7 +269,7 @@ float Evaluate(const Mat &simmat, const Mat &mask, const QString &csv) } // Write Cumulative Match Characteristic (CMC) curve - const int Max_Retrieval = 100; + const int Max_Retrieval = 200; const int Report_Retrieval = 5; float reportRetrievalRate = -1; diff --git a/openbr/plugins/crop.cpp b/openbr/plugins/crop.cpp index 6808031..5c3c548 100644 --- a/openbr/plugins/crop.cpp +++ b/openbr/plugins/crop.cpp @@ -71,18 +71,32 @@ BR_REGISTER(Transform, ROITransform) * \ingroup transforms * \brief Resize the template * \author Josh Klontz \cite jklontz + * \note Method: Area should be used for shrinking an image, Cubic for slow but accurate enlargment, Bilin for fast enlargement. */ class ResizeTransform : public UntrainableTransform { Q_OBJECT + Q_ENUMS(Method) + +public: + /*!< */ + enum Method { Near = INTER_NEAREST, + Area = INTER_AREA, + Bilin = INTER_LINEAR, + Cubic = INTER_CUBIC, + Lanczo = INTER_LANCZOS4}; + +private: Q_PROPERTY(int rows READ get_rows WRITE set_rows RESET reset_rows STORED false) Q_PROPERTY(int columns READ get_columns WRITE set_columns RESET reset_columns STORED false) + Q_PROPERTY(Method method READ get_method WRITE set_method RESET reset_method STORED false) BR_PROPERTY(int, rows, -1) BR_PROPERTY(int, columns, -1) + BR_PROPERTY(Method, method, Bilin) void project(const Template &src, Template &dst) const { - resize(src, dst, Size((columns == -1) ? src.m().cols*rows/src.m().rows : columns, rows)); + resize(src, dst, Size((columns == -1) ? src.m().cols*rows/src.m().rows : columns, rows), 0, 0, method); } }; diff --git a/openbr/plugins/landmarks.cpp b/openbr/plugins/landmarks.cpp index 13954d2..c49549d 100644 --- a/openbr/plugins/landmarks.cpp +++ b/openbr/plugins/landmarks.cpp @@ -119,7 +119,9 @@ class ProcrustesTransform : public Transform if (warp) { Eigen::MatrixXf dstMat = srcMat*R; - for (int i = 0; i < dstMat.rows(); i++) dst.file.appendPoint(QPointF(dstMat(i,0),dstMat(i,1))); + for (int i = 0; i < dstMat.rows(); i++) { + dst.file.appendPoint(QPointF(dstMat(i,0),dstMat(i,1))); + } } dst.file.set("Procrustes_0_0", R(0,0)); @@ -154,30 +156,40 @@ class DelaunayTransform : public UntrainableTransform { Q_OBJECT + Q_PROPERTY(float normReduction READ get_normReduction WRITE set_normReduction RESET reset_normReduction STORED false) + Q_PROPERTY(bool warp READ get_warp WRITE set_warp RESET reset_warp STORED false) Q_PROPERTY(bool draw READ get_draw WRITE set_draw RESET reset_draw STORED false) + BR_PROPERTY(float, normReduction, 1) + BR_PROPERTY(bool, warp, true) BR_PROPERTY(bool, draw, false) void project(const Template &src, Template &dst) const { Subdiv2D subdiv(Rect(0,0,src.m().cols,src.m().rows)); - QList points = OpenCVUtils::toPoints(src.file.points()); + QList points = src.file.points(); QList rects = src.file.rects(); if (points.empty() || rects.empty()) { dst = src; - qWarning("Points/rects are empty."); + qWarning("Delauney triangulation failed because points or rects are empty."); return; } - if (rects.size() > 1) qWarning("More than one rect in training data templates."); - - points.append(OpenCVUtils::toPoint(rects[0].topLeft())); - points.append(OpenCVUtils::toPoint(rects[0].topRight())); - points.append(OpenCVUtils::toPoint(rects[0].bottomLeft())); - points.append(OpenCVUtils::toPoint(rects[0].bottomRight())); + // Assume rect appended last was bounding box + points.append(rects.last().topLeft()); + points.append(rects.last().topRight()); + points.append(rects.last().bottomLeft()); + points.append(rects.last().bottomRight()); - for (int i = 0; i < points.size(); i++) subdiv.insert(points[i]); + for (int i = 0; i < points.size(); i++) { + if (points[i].x() < 0 || points[i].y() < 0 || points[i].y() >= src.m().rows || points[i].x() >= src.m().cols) { + dst = src; + qWarning("Delauney triangulation failed because points lie on boundary."); + return; + } + subdiv.insert(OpenCVUtils::toPoint(points[i])); + } vector triangleList; subdiv.getTriangleList(triangleList); @@ -185,26 +197,18 @@ class DelaunayTransform : public UntrainableTransform QList< QList > validTriangles; for (size_t i = 0; i < triangleList.size(); ++i) { - vector pt(3); - Vec6f t = triangleList[i]; - - pt[0] = Point(cvRound(t[0]), cvRound(t[1])); - pt[1] = Point(cvRound(t[2]), cvRound(t[3])); - pt[2] = Point(cvRound(t[4]), cvRound(t[5])); + vector pt(3); + pt[0] = Point(cvRound(triangleList[i][0]), cvRound(triangleList[i][1])); + pt[1] = Point(cvRound(triangleList[i][2]), cvRound(triangleList[i][3])); + pt[2] = Point(cvRound(triangleList[i][4]), cvRound(triangleList[i][5])); bool inside = true; for (int j = 0; j < 3; j++) { if (pt[j].x > src.m().cols || pt[j].y > src.m().rows || pt[j].x <= 0 || pt[j].y <= 0) inside = false; } - if (inside) { - QList triangleBuffer; - - triangleBuffer << pt[0] << pt[1] << pt[2]; - - validTriangles.append(triangleBuffer); - } + if (inside) validTriangles.append(QList()<< pt[0] << pt[1] << pt[2]); } dst.m() = src.m().clone(); @@ -240,9 +244,8 @@ class DelaunayTransform : public UntrainableTransform Eigen::MatrixXf srcMat(validTriangles[i].size(), 2); for (int j = 0; j < validTriangles[i].size(); j++) { - // WRONG WRONG WRONG cept not - srcMat(j,0) = (validTriangles[i][j].x-mean[0])/(norm/100.)+50; - srcMat(j,1) = (validTriangles[i][j].y-mean[1])/(norm/100.)+50; + srcMat(j,0) = (validTriangles[i][j].x-mean[0])/(norm/normReduction)+src.m().cols/2; + srcMat(j,1) = (validTriangles[i][j].y-mean[1])/(norm/normReduction)+src.m().rows/2; } Eigen::MatrixXf dstMat = srcMat*R; @@ -290,10 +293,10 @@ class DelaunayTransform : public UntrainableTransform } Rect boundingBox = boundingRect(mappedPoints.toVector().toStdVector()); - boundingBox.x += boundingBox.width * .025; - boundingBox.y += boundingBox.height * .025; // 0.025 for nose, .05 for mouth, .10 for brow + boundingBox.x += boundingBox.width * .05; + boundingBox.y += boundingBox.height * .1; // 0.025 for nose, .05 for mouth, .10 for brow boundingBox.width *= .975; - boundingBox.height *= .975; // .975 for nose, .95 for mouth, .925 for brow + boundingBox.height *= .925; // .975 for nose, .95 for mouth, .925 for brow dst.m() = Mat(dst.m(), boundingBox); } diff --git a/openbr/plugins/register.cpp b/openbr/plugins/register.cpp index dd88b06..870dd00 100644 --- a/openbr/plugins/register.cpp +++ b/openbr/plugins/register.cpp @@ -28,10 +28,22 @@ namespace br * \ingroup transforms * \brief Performs a two or three point registration. * \author Josh Klontz \cite jklontz + * \note Method: Area should be used for shrinking an image, Cubic for slow but accurate enlargment, Bilin for fast enlargement. */ class AffineTransform : public UntrainableTransform { Q_OBJECT + Q_ENUMS(Method) + +public: + /*!< */ + enum Method { Near = INTER_NEAREST, + Area = INTER_AREA, + Bilin = INTER_LINEAR, + Cubic = INTER_CUBIC, + Lanczo = INTER_LANCZOS4}; + +private: Q_PROPERTY(int width READ get_width WRITE set_width RESET reset_width STORED false) Q_PROPERTY(int height READ get_height WRITE set_height RESET reset_height STORED false) Q_PROPERTY(float x1 READ get_x1 WRITE set_x1 RESET reset_x1 STORED false) @@ -40,6 +52,7 @@ class AffineTransform : public UntrainableTransform Q_PROPERTY(float y2 READ get_y2 WRITE set_y2 RESET reset_y2 STORED false) Q_PROPERTY(float x3 READ get_x3 WRITE set_x3 RESET reset_x3 STORED false) Q_PROPERTY(float y3 READ get_y3 WRITE set_y3 RESET reset_y3 STORED false) + Q_PROPERTY(Method method READ get_method WRITE set_method RESET reset_method STORED false) BR_PROPERTY(int, width, 64) BR_PROPERTY(int, height, 64) BR_PROPERTY(float, x1, 0) @@ -48,6 +61,7 @@ class AffineTransform : public UntrainableTransform BR_PROPERTY(float, y2, -1) BR_PROPERTY(float, x3, -1) BR_PROPERTY(float, y3, -1) + BR_PROPERTY(Method, method, Bilin) static Point2f getThirdAffinePoint(const Point2f &a, const Point2f &b) { @@ -95,7 +109,7 @@ class AffineTransform : public UntrainableTransform } if (twoPoints) srcPoints[2] = getThirdAffinePoint(srcPoints[0], srcPoints[1]); - warpAffine(src, dst, getAffineTransform(srcPoints, dstPoints), Size(width, height)); + warpAffine(src, dst, getAffineTransform(srcPoints, dstPoints), Size(width, height), method); } };