Commit d3fbb06f8499be9f0c5b5608e5e0a9bf67de9a4e
1 parent
86c4be32
Added interpolation methods for affine and resize
Showing
6 changed files
with
64 additions
and
35 deletions
3rdparty/stasm4.0.0/stasm/stasm_lib.cpp
| @@ -157,7 +157,6 @@ int stasm_search_auto_ext( // extended version of stasm_search_auto | @@ -157,7 +157,6 @@ int stasm_search_auto_ext( // extended version of stasm_search_auto | ||
| 157 | { | 157 | { |
| 158 | int returnval = 1; // assume success | 158 | int returnval = 1; // assume success |
| 159 | *foundface = 0; // but assume no face found | 159 | *foundface = 0; // but assume no face found |
| 160 | - CatchOpenCvErrs(); | ||
| 161 | try | 160 | try |
| 162 | { | 161 | { |
| 163 | CheckStasmInit(); | 162 | CheckStasmInit(); |
| @@ -204,7 +203,6 @@ int stasm_search_auto_ext( // extended version of stasm_search_auto | @@ -204,7 +203,6 @@ int stasm_search_auto_ext( // extended version of stasm_search_auto | ||
| 204 | { | 203 | { |
| 205 | returnval = 0; // a call was made to Err or a CV_Assert failed | 204 | returnval = 0; // a call was made to Err or a CV_Assert failed |
| 206 | } | 205 | } |
| 207 | - UncatchOpenCvErrs(); | ||
| 208 | return returnval; | 206 | return returnval; |
| 209 | } | 207 | } |
| 210 | 208 |
openbr/core/bee.cpp
| @@ -96,7 +96,7 @@ void BEE::writeSigset(const QString &sigset, const br::FileList &files, bool ign | @@ -96,7 +96,7 @@ void BEE::writeSigset(const QString &sigset, const br::FileList &files, bool ign | ||
| 96 | if ((key == "Index") || (key == "Subject")) continue; | 96 | if ((key == "Index") || (key == "Subject")) continue; |
| 97 | metadata.append(key+"=\""+QtUtils::toString(file.value(key))+"\""); | 97 | metadata.append(key+"=\""+QtUtils::toString(file.value(key))+"\""); |
| 98 | } | 98 | } |
| 99 | - lines.append("\t<biometric-signature name=\"" + file.get<QString>("Subject") +"\">"); | 99 | + lines.append("\t<biometric-signature name=\"" + file.name +"\">"); |
| 100 | lines.append("\t\t<presentation file-name=\"" + file.name + "\" " + metadata.join(" ") + "/>"); | 100 | lines.append("\t\t<presentation file-name=\"" + file.name + "\" " + metadata.join(" ") + "/>"); |
| 101 | lines.append("\t</biometric-signature>"); | 101 | lines.append("\t</biometric-signature>"); |
| 102 | } | 102 | } |
openbr/core/plot.cpp
| @@ -269,7 +269,7 @@ float Evaluate(const Mat &simmat, const Mat &mask, const QString &csv) | @@ -269,7 +269,7 @@ float Evaluate(const Mat &simmat, const Mat &mask, const QString &csv) | ||
| 269 | } | 269 | } |
| 270 | 270 | ||
| 271 | // Write Cumulative Match Characteristic (CMC) curve | 271 | // Write Cumulative Match Characteristic (CMC) curve |
| 272 | - const int Max_Retrieval = 100; | 272 | + const int Max_Retrieval = 200; |
| 273 | const int Report_Retrieval = 5; | 273 | const int Report_Retrieval = 5; |
| 274 | 274 | ||
| 275 | float reportRetrievalRate = -1; | 275 | float reportRetrievalRate = -1; |
openbr/plugins/crop.cpp
| @@ -71,18 +71,32 @@ BR_REGISTER(Transform, ROITransform) | @@ -71,18 +71,32 @@ BR_REGISTER(Transform, ROITransform) | ||
| 71 | * \ingroup transforms | 71 | * \ingroup transforms |
| 72 | * \brief Resize the template | 72 | * \brief Resize the template |
| 73 | * \author Josh Klontz \cite jklontz | 73 | * \author Josh Klontz \cite jklontz |
| 74 | + * \note Method: Area should be used for shrinking an image, Cubic for slow but accurate enlargment, Bilin for fast enlargement. | ||
| 74 | */ | 75 | */ |
| 75 | class ResizeTransform : public UntrainableTransform | 76 | class ResizeTransform : public UntrainableTransform |
| 76 | { | 77 | { |
| 77 | Q_OBJECT | 78 | Q_OBJECT |
| 79 | + Q_ENUMS(Method) | ||
| 80 | + | ||
| 81 | +public: | ||
| 82 | + /*!< */ | ||
| 83 | + enum Method { Near = INTER_NEAREST, | ||
| 84 | + Area = INTER_AREA, | ||
| 85 | + Bilin = INTER_LINEAR, | ||
| 86 | + Cubic = INTER_CUBIC, | ||
| 87 | + Lanczo = INTER_LANCZOS4}; | ||
| 88 | + | ||
| 89 | +private: | ||
| 78 | Q_PROPERTY(int rows READ get_rows WRITE set_rows RESET reset_rows STORED false) | 90 | Q_PROPERTY(int rows READ get_rows WRITE set_rows RESET reset_rows STORED false) |
| 79 | Q_PROPERTY(int columns READ get_columns WRITE set_columns RESET reset_columns STORED false) | 91 | Q_PROPERTY(int columns READ get_columns WRITE set_columns RESET reset_columns STORED false) |
| 92 | + Q_PROPERTY(Method method READ get_method WRITE set_method RESET reset_method STORED false) | ||
| 80 | BR_PROPERTY(int, rows, -1) | 93 | BR_PROPERTY(int, rows, -1) |
| 81 | BR_PROPERTY(int, columns, -1) | 94 | BR_PROPERTY(int, columns, -1) |
| 95 | + BR_PROPERTY(Method, method, Bilin) | ||
| 82 | 96 | ||
| 83 | void project(const Template &src, Template &dst) const | 97 | void project(const Template &src, Template &dst) const |
| 84 | { | 98 | { |
| 85 | - resize(src, dst, Size((columns == -1) ? src.m().cols*rows/src.m().rows : columns, rows)); | 99 | + resize(src, dst, Size((columns == -1) ? src.m().cols*rows/src.m().rows : columns, rows), 0, 0, method); |
| 86 | } | 100 | } |
| 87 | }; | 101 | }; |
| 88 | 102 |
openbr/plugins/landmarks.cpp
| @@ -119,7 +119,9 @@ class ProcrustesTransform : public Transform | @@ -119,7 +119,9 @@ class ProcrustesTransform : public Transform | ||
| 119 | 119 | ||
| 120 | if (warp) { | 120 | if (warp) { |
| 121 | Eigen::MatrixXf dstMat = srcMat*R; | 121 | Eigen::MatrixXf dstMat = srcMat*R; |
| 122 | - for (int i = 0; i < dstMat.rows(); i++) dst.file.appendPoint(QPointF(dstMat(i,0),dstMat(i,1))); | 122 | + for (int i = 0; i < dstMat.rows(); i++) { |
| 123 | + dst.file.appendPoint(QPointF(dstMat(i,0),dstMat(i,1))); | ||
| 124 | + } | ||
| 123 | } | 125 | } |
| 124 | 126 | ||
| 125 | dst.file.set("Procrustes_0_0", R(0,0)); | 127 | dst.file.set("Procrustes_0_0", R(0,0)); |
| @@ -154,30 +156,40 @@ class DelaunayTransform : public UntrainableTransform | @@ -154,30 +156,40 @@ class DelaunayTransform : public UntrainableTransform | ||
| 154 | { | 156 | { |
| 155 | Q_OBJECT | 157 | Q_OBJECT |
| 156 | 158 | ||
| 159 | + Q_PROPERTY(float normReduction READ get_normReduction WRITE set_normReduction RESET reset_normReduction STORED false) | ||
| 160 | + Q_PROPERTY(bool warp READ get_warp WRITE set_warp RESET reset_warp STORED false) | ||
| 157 | Q_PROPERTY(bool draw READ get_draw WRITE set_draw RESET reset_draw STORED false) | 161 | Q_PROPERTY(bool draw READ get_draw WRITE set_draw RESET reset_draw STORED false) |
| 162 | + BR_PROPERTY(float, normReduction, 1) | ||
| 163 | + BR_PROPERTY(bool, warp, true) | ||
| 158 | BR_PROPERTY(bool, draw, false) | 164 | BR_PROPERTY(bool, draw, false) |
| 159 | 165 | ||
| 160 | void project(const Template &src, Template &dst) const | 166 | void project(const Template &src, Template &dst) const |
| 161 | { | 167 | { |
| 162 | Subdiv2D subdiv(Rect(0,0,src.m().cols,src.m().rows)); | 168 | Subdiv2D subdiv(Rect(0,0,src.m().cols,src.m().rows)); |
| 163 | 169 | ||
| 164 | - QList<cv::Point2f> points = OpenCVUtils::toPoints(src.file.points()); | 170 | + QList<QPointF> points = src.file.points(); |
| 165 | QList<QRectF> rects = src.file.rects(); | 171 | QList<QRectF> rects = src.file.rects(); |
| 166 | 172 | ||
| 167 | if (points.empty() || rects.empty()) { | 173 | if (points.empty() || rects.empty()) { |
| 168 | dst = src; | 174 | dst = src; |
| 169 | - qWarning("Points/rects are empty."); | 175 | + qWarning("Delauney triangulation failed because points or rects are empty."); |
| 170 | return; | 176 | return; |
| 171 | } | 177 | } |
| 172 | 178 | ||
| 173 | - if (rects.size() > 1) qWarning("More than one rect in training data templates."); | ||
| 174 | - | ||
| 175 | - points.append(OpenCVUtils::toPoint(rects[0].topLeft())); | ||
| 176 | - points.append(OpenCVUtils::toPoint(rects[0].topRight())); | ||
| 177 | - points.append(OpenCVUtils::toPoint(rects[0].bottomLeft())); | ||
| 178 | - points.append(OpenCVUtils::toPoint(rects[0].bottomRight())); | 179 | + // Assume rect appended last was bounding box |
| 180 | + points.append(rects.last().topLeft()); | ||
| 181 | + points.append(rects.last().topRight()); | ||
| 182 | + points.append(rects.last().bottomLeft()); | ||
| 183 | + points.append(rects.last().bottomRight()); | ||
| 179 | 184 | ||
| 180 | - for (int i = 0; i < points.size(); i++) subdiv.insert(points[i]); | 185 | + for (int i = 0; i < points.size(); i++) { |
| 186 | + if (points[i].x() < 0 || points[i].y() < 0 || points[i].y() >= src.m().rows || points[i].x() >= src.m().cols) { | ||
| 187 | + dst = src; | ||
| 188 | + qWarning("Delauney triangulation failed because points lie on boundary."); | ||
| 189 | + return; | ||
| 190 | + } | ||
| 191 | + subdiv.insert(OpenCVUtils::toPoint(points[i])); | ||
| 192 | + } | ||
| 181 | 193 | ||
| 182 | vector<Vec6f> triangleList; | 194 | vector<Vec6f> triangleList; |
| 183 | subdiv.getTriangleList(triangleList); | 195 | subdiv.getTriangleList(triangleList); |
| @@ -185,26 +197,18 @@ class DelaunayTransform : public UntrainableTransform | @@ -185,26 +197,18 @@ class DelaunayTransform : public UntrainableTransform | ||
| 185 | QList< QList<Point> > validTriangles; | 197 | QList< QList<Point> > validTriangles; |
| 186 | 198 | ||
| 187 | for (size_t i = 0; i < triangleList.size(); ++i) { | 199 | for (size_t i = 0; i < triangleList.size(); ++i) { |
| 188 | - vector<Point> pt(3); | ||
| 189 | 200 | ||
| 190 | - Vec6f t = triangleList[i]; | ||
| 191 | - | ||
| 192 | - pt[0] = Point(cvRound(t[0]), cvRound(t[1])); | ||
| 193 | - pt[1] = Point(cvRound(t[2]), cvRound(t[3])); | ||
| 194 | - pt[2] = Point(cvRound(t[4]), cvRound(t[5])); | 201 | + vector<Point> pt(3); |
| 202 | + pt[0] = Point(cvRound(triangleList[i][0]), cvRound(triangleList[i][1])); | ||
| 203 | + pt[1] = Point(cvRound(triangleList[i][2]), cvRound(triangleList[i][3])); | ||
| 204 | + pt[2] = Point(cvRound(triangleList[i][4]), cvRound(triangleList[i][5])); | ||
| 195 | 205 | ||
| 196 | bool inside = true; | 206 | bool inside = true; |
| 197 | for (int j = 0; j < 3; j++) { | 207 | for (int j = 0; j < 3; j++) { |
| 198 | if (pt[j].x > src.m().cols || pt[j].y > src.m().rows || pt[j].x <= 0 || pt[j].y <= 0) inside = false; | 208 | if (pt[j].x > src.m().cols || pt[j].y > src.m().rows || pt[j].x <= 0 || pt[j].y <= 0) inside = false; |
| 199 | } | 209 | } |
| 200 | 210 | ||
| 201 | - if (inside) { | ||
| 202 | - QList<Point> triangleBuffer; | ||
| 203 | - | ||
| 204 | - triangleBuffer << pt[0] << pt[1] << pt[2]; | ||
| 205 | - | ||
| 206 | - validTriangles.append(triangleBuffer); | ||
| 207 | - } | 211 | + if (inside) validTriangles.append(QList<Point>()<< pt[0] << pt[1] << pt[2]); |
| 208 | } | 212 | } |
| 209 | 213 | ||
| 210 | dst.m() = src.m().clone(); | 214 | dst.m() = src.m().clone(); |
| @@ -240,9 +244,8 @@ class DelaunayTransform : public UntrainableTransform | @@ -240,9 +244,8 @@ class DelaunayTransform : public UntrainableTransform | ||
| 240 | Eigen::MatrixXf srcMat(validTriangles[i].size(), 2); | 244 | Eigen::MatrixXf srcMat(validTriangles[i].size(), 2); |
| 241 | 245 | ||
| 242 | for (int j = 0; j < validTriangles[i].size(); j++) { | 246 | for (int j = 0; j < validTriangles[i].size(); j++) { |
| 243 | - // WRONG WRONG WRONG cept not | ||
| 244 | - srcMat(j,0) = (validTriangles[i][j].x-mean[0])/(norm/100.)+50; | ||
| 245 | - srcMat(j,1) = (validTriangles[i][j].y-mean[1])/(norm/100.)+50; | 247 | + srcMat(j,0) = (validTriangles[i][j].x-mean[0])/(norm/normReduction)+src.m().cols/2; |
| 248 | + srcMat(j,1) = (validTriangles[i][j].y-mean[1])/(norm/normReduction)+src.m().rows/2; | ||
| 246 | } | 249 | } |
| 247 | 250 | ||
| 248 | Eigen::MatrixXf dstMat = srcMat*R; | 251 | Eigen::MatrixXf dstMat = srcMat*R; |
| @@ -290,10 +293,10 @@ class DelaunayTransform : public UntrainableTransform | @@ -290,10 +293,10 @@ class DelaunayTransform : public UntrainableTransform | ||
| 290 | } | 293 | } |
| 291 | 294 | ||
| 292 | Rect boundingBox = boundingRect(mappedPoints.toVector().toStdVector()); | 295 | Rect boundingBox = boundingRect(mappedPoints.toVector().toStdVector()); |
| 293 | - boundingBox.x += boundingBox.width * .025; | ||
| 294 | - boundingBox.y += boundingBox.height * .025; // 0.025 for nose, .05 for mouth, .10 for brow | 296 | + boundingBox.x += boundingBox.width * .05; |
| 297 | + boundingBox.y += boundingBox.height * .1; // 0.025 for nose, .05 for mouth, .10 for brow | ||
| 295 | boundingBox.width *= .975; | 298 | boundingBox.width *= .975; |
| 296 | - boundingBox.height *= .975; // .975 for nose, .95 for mouth, .925 for brow | 299 | + boundingBox.height *= .925; // .975 for nose, .95 for mouth, .925 for brow |
| 297 | 300 | ||
| 298 | dst.m() = Mat(dst.m(), boundingBox); | 301 | dst.m() = Mat(dst.m(), boundingBox); |
| 299 | } | 302 | } |
openbr/plugins/register.cpp
| @@ -28,10 +28,22 @@ namespace br | @@ -28,10 +28,22 @@ namespace br | ||
| 28 | * \ingroup transforms | 28 | * \ingroup transforms |
| 29 | * \brief Performs a two or three point registration. | 29 | * \brief Performs a two or three point registration. |
| 30 | * \author Josh Klontz \cite jklontz | 30 | * \author Josh Klontz \cite jklontz |
| 31 | + * \note Method: Area should be used for shrinking an image, Cubic for slow but accurate enlargment, Bilin for fast enlargement. | ||
| 31 | */ | 32 | */ |
| 32 | class AffineTransform : public UntrainableTransform | 33 | class AffineTransform : public UntrainableTransform |
| 33 | { | 34 | { |
| 34 | Q_OBJECT | 35 | Q_OBJECT |
| 36 | + Q_ENUMS(Method) | ||
| 37 | + | ||
| 38 | +public: | ||
| 39 | + /*!< */ | ||
| 40 | + enum Method { Near = INTER_NEAREST, | ||
| 41 | + Area = INTER_AREA, | ||
| 42 | + Bilin = INTER_LINEAR, | ||
| 43 | + Cubic = INTER_CUBIC, | ||
| 44 | + Lanczo = INTER_LANCZOS4}; | ||
| 45 | + | ||
| 46 | +private: | ||
| 35 | Q_PROPERTY(int width READ get_width WRITE set_width RESET reset_width STORED false) | 47 | Q_PROPERTY(int width READ get_width WRITE set_width RESET reset_width STORED false) |
| 36 | Q_PROPERTY(int height READ get_height WRITE set_height RESET reset_height STORED false) | 48 | Q_PROPERTY(int height READ get_height WRITE set_height RESET reset_height STORED false) |
| 37 | Q_PROPERTY(float x1 READ get_x1 WRITE set_x1 RESET reset_x1 STORED false) | 49 | Q_PROPERTY(float x1 READ get_x1 WRITE set_x1 RESET reset_x1 STORED false) |
| @@ -40,6 +52,7 @@ class AffineTransform : public UntrainableTransform | @@ -40,6 +52,7 @@ class AffineTransform : public UntrainableTransform | ||
| 40 | Q_PROPERTY(float y2 READ get_y2 WRITE set_y2 RESET reset_y2 STORED false) | 52 | Q_PROPERTY(float y2 READ get_y2 WRITE set_y2 RESET reset_y2 STORED false) |
| 41 | Q_PROPERTY(float x3 READ get_x3 WRITE set_x3 RESET reset_x3 STORED false) | 53 | Q_PROPERTY(float x3 READ get_x3 WRITE set_x3 RESET reset_x3 STORED false) |
| 42 | Q_PROPERTY(float y3 READ get_y3 WRITE set_y3 RESET reset_y3 STORED false) | 54 | Q_PROPERTY(float y3 READ get_y3 WRITE set_y3 RESET reset_y3 STORED false) |
| 55 | + Q_PROPERTY(Method method READ get_method WRITE set_method RESET reset_method STORED false) | ||
| 43 | BR_PROPERTY(int, width, 64) | 56 | BR_PROPERTY(int, width, 64) |
| 44 | BR_PROPERTY(int, height, 64) | 57 | BR_PROPERTY(int, height, 64) |
| 45 | BR_PROPERTY(float, x1, 0) | 58 | BR_PROPERTY(float, x1, 0) |
| @@ -48,6 +61,7 @@ class AffineTransform : public UntrainableTransform | @@ -48,6 +61,7 @@ class AffineTransform : public UntrainableTransform | ||
| 48 | BR_PROPERTY(float, y2, -1) | 61 | BR_PROPERTY(float, y2, -1) |
| 49 | BR_PROPERTY(float, x3, -1) | 62 | BR_PROPERTY(float, x3, -1) |
| 50 | BR_PROPERTY(float, y3, -1) | 63 | BR_PROPERTY(float, y3, -1) |
| 64 | + BR_PROPERTY(Method, method, Bilin) | ||
| 51 | 65 | ||
| 52 | static Point2f getThirdAffinePoint(const Point2f &a, const Point2f &b) | 66 | static Point2f getThirdAffinePoint(const Point2f &a, const Point2f &b) |
| 53 | { | 67 | { |
| @@ -95,7 +109,7 @@ class AffineTransform : public UntrainableTransform | @@ -95,7 +109,7 @@ class AffineTransform : public UntrainableTransform | ||
| 95 | } | 109 | } |
| 96 | if (twoPoints) srcPoints[2] = getThirdAffinePoint(srcPoints[0], srcPoints[1]); | 110 | if (twoPoints) srcPoints[2] = getThirdAffinePoint(srcPoints[0], srcPoints[1]); |
| 97 | 111 | ||
| 98 | - warpAffine(src, dst, getAffineTransform(srcPoints, dstPoints), Size(width, height)); | 112 | + warpAffine(src, dst, getAffineTransform(srcPoints, dstPoints), Size(width, height), method); |
| 99 | } | 113 | } |
| 100 | }; | 114 | }; |
| 101 | 115 |