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 | 157 | { |
| 158 | 158 | int returnval = 1; // assume success |
| 159 | 159 | *foundface = 0; // but assume no face found |
| 160 | - CatchOpenCvErrs(); | |
| 161 | 160 | try |
| 162 | 161 | { |
| 163 | 162 | CheckStasmInit(); |
| ... | ... | @@ -204,7 +203,6 @@ int stasm_search_auto_ext( // extended version of stasm_search_auto |
| 204 | 203 | { |
| 205 | 204 | returnval = 0; // a call was made to Err or a CV_Assert failed |
| 206 | 205 | } |
| 207 | - UncatchOpenCvErrs(); | |
| 208 | 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 | 96 | if ((key == "Index") || (key == "Subject")) continue; |
| 97 | 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 | 100 | lines.append("\t\t<presentation file-name=\"" + file.name + "\" " + metadata.join(" ") + "/>"); |
| 101 | 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 | 269 | } |
| 270 | 270 | |
| 271 | 271 | // Write Cumulative Match Characteristic (CMC) curve |
| 272 | - const int Max_Retrieval = 100; | |
| 272 | + const int Max_Retrieval = 200; | |
| 273 | 273 | const int Report_Retrieval = 5; |
| 274 | 274 | |
| 275 | 275 | float reportRetrievalRate = -1; | ... | ... |
openbr/plugins/crop.cpp
| ... | ... | @@ -71,18 +71,32 @@ BR_REGISTER(Transform, ROITransform) |
| 71 | 71 | * \ingroup transforms |
| 72 | 72 | * \brief Resize the template |
| 73 | 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 | 76 | class ResizeTransform : public UntrainableTransform |
| 76 | 77 | { |
| 77 | 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 | 90 | Q_PROPERTY(int rows READ get_rows WRITE set_rows RESET reset_rows STORED false) |
| 79 | 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 | 93 | BR_PROPERTY(int, rows, -1) |
| 81 | 94 | BR_PROPERTY(int, columns, -1) |
| 95 | + BR_PROPERTY(Method, method, Bilin) | |
| 82 | 96 | |
| 83 | 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 | 119 | |
| 120 | 120 | if (warp) { |
| 121 | 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 | 127 | dst.file.set("Procrustes_0_0", R(0,0)); |
| ... | ... | @@ -154,30 +156,40 @@ class DelaunayTransform : public UntrainableTransform |
| 154 | 156 | { |
| 155 | 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 | 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 | 164 | BR_PROPERTY(bool, draw, false) |
| 159 | 165 | |
| 160 | 166 | void project(const Template &src, Template &dst) const |
| 161 | 167 | { |
| 162 | 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 | 171 | QList<QRectF> rects = src.file.rects(); |
| 166 | 172 | |
| 167 | 173 | if (points.empty() || rects.empty()) { |
| 168 | 174 | dst = src; |
| 169 | - qWarning("Points/rects are empty."); | |
| 175 | + qWarning("Delauney triangulation failed because points or rects are empty."); | |
| 170 | 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 | 194 | vector<Vec6f> triangleList; |
| 183 | 195 | subdiv.getTriangleList(triangleList); |
| ... | ... | @@ -185,26 +197,18 @@ class DelaunayTransform : public UntrainableTransform |
| 185 | 197 | QList< QList<Point> > validTriangles; |
| 186 | 198 | |
| 187 | 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 | 206 | bool inside = true; |
| 197 | 207 | for (int j = 0; j < 3; j++) { |
| 198 | 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 | 214 | dst.m() = src.m().clone(); |
| ... | ... | @@ -240,9 +244,8 @@ class DelaunayTransform : public UntrainableTransform |
| 240 | 244 | Eigen::MatrixXf srcMat(validTriangles[i].size(), 2); |
| 241 | 245 | |
| 242 | 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 | 251 | Eigen::MatrixXf dstMat = srcMat*R; |
| ... | ... | @@ -290,10 +293,10 @@ class DelaunayTransform : public UntrainableTransform |
| 290 | 293 | } |
| 291 | 294 | |
| 292 | 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 | 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 | 301 | dst.m() = Mat(dst.m(), boundingBox); |
| 299 | 302 | } | ... | ... |
openbr/plugins/register.cpp
| ... | ... | @@ -28,10 +28,22 @@ namespace br |
| 28 | 28 | * \ingroup transforms |
| 29 | 29 | * \brief Performs a two or three point registration. |
| 30 | 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 | 33 | class AffineTransform : public UntrainableTransform |
| 33 | 34 | { |
| 34 | 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 | 47 | Q_PROPERTY(int width READ get_width WRITE set_width RESET reset_width STORED false) |
| 36 | 48 | Q_PROPERTY(int height READ get_height WRITE set_height RESET reset_height STORED false) |
| 37 | 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 | 52 | Q_PROPERTY(float y2 READ get_y2 WRITE set_y2 RESET reset_y2 STORED false) |
| 41 | 53 | Q_PROPERTY(float x3 READ get_x3 WRITE set_x3 RESET reset_x3 STORED false) |
| 42 | 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 | 56 | BR_PROPERTY(int, width, 64) |
| 44 | 57 | BR_PROPERTY(int, height, 64) |
| 45 | 58 | BR_PROPERTY(float, x1, 0) |
| ... | ... | @@ -48,6 +61,7 @@ class AffineTransform : public UntrainableTransform |
| 48 | 61 | BR_PROPERTY(float, y2, -1) |
| 49 | 62 | BR_PROPERTY(float, x3, -1) |
| 50 | 63 | BR_PROPERTY(float, y3, -1) |
| 64 | + BR_PROPERTY(Method, method, Bilin) | |
| 51 | 65 | |
| 52 | 66 | static Point2f getThirdAffinePoint(const Point2f &a, const Point2f &b) |
| 53 | 67 | { |
| ... | ... | @@ -95,7 +109,7 @@ class AffineTransform : public UntrainableTransform |
| 95 | 109 | } |
| 96 | 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 | ... | ... |