Commit a50d515a8c15222376909c1a76e9d16b3a318bdf
1 parent
800affe8
remove procustes
Showing
1 changed file
with
0 additions
and
155 deletions
openbr/plugins/metadata/procrustes.cpp deleted
| 1 | -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * | ||
| 2 | - * Copyright 2012 The MITRE Corporation * | ||
| 3 | - * * | ||
| 4 | - * Licensed under the Apache License, Version 2.0 (the "License"); * | ||
| 5 | - * you may not use this file except in compliance with the License. * | ||
| 6 | - * You may obtain a copy of the License at * | ||
| 7 | - * * | ||
| 8 | - * http://www.apache.org/licenses/LICENSE-2.0 * | ||
| 9 | - * * | ||
| 10 | - * Unless required by applicable law or agreed to in writing, software * | ||
| 11 | - * distributed under the License is distributed on an "AS IS" BASIS, * | ||
| 12 | - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * | ||
| 13 | - * See the License for the specific language governing permissions and * | ||
| 14 | - * limitations under the License. * | ||
| 15 | - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | ||
| 16 | - | ||
| 17 | -#include <Eigen/Dense> | ||
| 18 | - | ||
| 19 | -#include <openbr/plugins/openbr_internal.h> | ||
| 20 | -#include <openbr/core/opencvutils.h> | ||
| 21 | -#include <openbr/core/eigenutils.h> | ||
| 22 | - | ||
| 23 | -using namespace cv; | ||
| 24 | - | ||
| 25 | -namespace br | ||
| 26 | -{ | ||
| 27 | - | ||
| 28 | -/*! | ||
| 29 | - * \ingroup transforms | ||
| 30 | - * \brief Procrustes alignment of points | ||
| 31 | - * \author Scott Klum \cite sklum | ||
| 32 | - */ | ||
| 33 | -class ProcrustesTransform : public MetadataTransform | ||
| 34 | -{ | ||
| 35 | - Q_OBJECT | ||
| 36 | - | ||
| 37 | - Q_PROPERTY(bool warp READ get_warp WRITE set_warp RESET reset_warp STORED false) | ||
| 38 | - BR_PROPERTY(bool, warp, true) | ||
| 39 | - | ||
| 40 | - Eigen::MatrixXf meanShape; | ||
| 41 | - | ||
| 42 | - void train(const TemplateList &data) | ||
| 43 | - { | ||
| 44 | - QList< QList<QPointF> > normalizedPoints; | ||
| 45 | - | ||
| 46 | - // Normalize all sets of points | ||
| 47 | - foreach (br::Template datum, data) { | ||
| 48 | - QList<QPointF> points = datum.file.points(); | ||
| 49 | - QList<QRectF> rects = datum.file.rects(); | ||
| 50 | - | ||
| 51 | - if (points.empty() || rects.empty()) continue; | ||
| 52 | - | ||
| 53 | - // Assume rect appended last was bounding box | ||
| 54 | - points.append(rects.last().topLeft()); | ||
| 55 | - points.append(rects.last().topRight()); | ||
| 56 | - points.append(rects.last().bottomLeft()); | ||
| 57 | - points.append(rects.last().bottomRight()); | ||
| 58 | - | ||
| 59 | - // Center shape at origin | ||
| 60 | - Scalar mean = cv::mean(OpenCVUtils::toPoints(points).toVector().toStdVector()); | ||
| 61 | - for (int i = 0; i < points.size(); i++) points[i] -= QPointF(mean[0],mean[1]); | ||
| 62 | - | ||
| 63 | - // Remove scale component | ||
| 64 | - float norm = cv::norm(OpenCVUtils::toPoints(points).toVector().toStdVector()); | ||
| 65 | - for (int i = 0; i < points.size(); i++) points[i] /= norm; | ||
| 66 | - | ||
| 67 | - normalizedPoints.append(points); | ||
| 68 | - } | ||
| 69 | - | ||
| 70 | - if (normalizedPoints.empty()) qFatal("Unable to calculate normalized points"); | ||
| 71 | - | ||
| 72 | - // Determine mean shape, assuming all shapes contain the same number of points | ||
| 73 | - meanShape = Eigen::MatrixXf(normalizedPoints[0].size(), 2); | ||
| 74 | - | ||
| 75 | - for (int i = 0; i < normalizedPoints[0].size(); i++) { | ||
| 76 | - double x = 0; | ||
| 77 | - double y = 0; | ||
| 78 | - | ||
| 79 | - for (int j = 0; j < normalizedPoints.size(); j++) { | ||
| 80 | - x += normalizedPoints[j][i].x(); | ||
| 81 | - y += normalizedPoints[j][i].y(); | ||
| 82 | - } | ||
| 83 | - | ||
| 84 | - x /= (double)normalizedPoints.size(); | ||
| 85 | - y /= (double)normalizedPoints.size(); | ||
| 86 | - | ||
| 87 | - meanShape(i,0) = x; | ||
| 88 | - meanShape(i,1) = y; | ||
| 89 | - } | ||
| 90 | - } | ||
| 91 | - | ||
| 92 | - void projectMetadata(const File &src, File &dst) const | ||
| 93 | - { | ||
| 94 | - QList<QPointF> points = src.points(); | ||
| 95 | - QList<QRectF> rects = src.rects(); | ||
| 96 | - | ||
| 97 | - if (points.empty() || rects.empty()) { | ||
| 98 | - dst = src; | ||
| 99 | - if (Globals->verbose) qWarning("Procrustes alignment failed because points or rects are empty."); | ||
| 100 | - return; | ||
| 101 | - } | ||
| 102 | - | ||
| 103 | - // Assume rect appended last was bounding box | ||
| 104 | - points.append(rects.last().topLeft()); | ||
| 105 | - points.append(rects.last().topRight()); | ||
| 106 | - points.append(rects.last().bottomLeft()); | ||
| 107 | - points.append(rects.last().bottomRight()); | ||
| 108 | - | ||
| 109 | - Scalar mean = cv::mean(OpenCVUtils::toPoints(points).toVector().toStdVector()); | ||
| 110 | - for (int i = 0; i < points.size(); i++) points[i] -= QPointF(mean[0],mean[1]); | ||
| 111 | - | ||
| 112 | - Eigen::MatrixXf srcMat(points.size(), 2); | ||
| 113 | - float norm = cv::norm(OpenCVUtils::toPoints(points).toVector().toStdVector()); | ||
| 114 | - for (int i = 0; i < points.size(); i++) { | ||
| 115 | - points[i] /= norm; | ||
| 116 | - srcMat(i,0) = points[i].x(); | ||
| 117 | - srcMat(i,1) = points[i].y(); | ||
| 118 | - } | ||
| 119 | - | ||
| 120 | - Eigen::JacobiSVD<Eigen::MatrixXf> svd(srcMat.transpose()*meanShape, Eigen::ComputeThinU | Eigen::ComputeThinV); | ||
| 121 | - Eigen::MatrixXf R = svd.matrixU()*svd.matrixV().transpose(); | ||
| 122 | - | ||
| 123 | - dst = src; | ||
| 124 | - | ||
| 125 | - // Store procrustes stats in the order: | ||
| 126 | - // R(0,0), R(1,0), R(1,1), R(0,1), mean_x, mean_y, norm | ||
| 127 | - QList<float> procrustesStats; | ||
| 128 | - procrustesStats << R(0,0) << R(1,0) << R(1,1) << R(0,1) << mean[0] << mean[1] << norm; | ||
| 129 | - dst.setList<float>("ProcrustesStats",procrustesStats); | ||
| 130 | - | ||
| 131 | - if (warp) { | ||
| 132 | - Eigen::MatrixXf dstMat = srcMat*R; | ||
| 133 | - for (int i = 0; i < dstMat.rows(); i++) { | ||
| 134 | - dst.appendPoint(QPointF(dstMat(i,0),dstMat(i,1))); | ||
| 135 | - } | ||
| 136 | - } | ||
| 137 | - } | ||
| 138 | - | ||
| 139 | - void store(QDataStream &stream) const | ||
| 140 | - { | ||
| 141 | - stream << meanShape; | ||
| 142 | - } | ||
| 143 | - | ||
| 144 | - void load(QDataStream &stream) | ||
| 145 | - { | ||
| 146 | - stream >> meanShape; | ||
| 147 | - } | ||
| 148 | - | ||
| 149 | -}; | ||
| 150 | - | ||
| 151 | -BR_REGISTER(Transform, ProcrustesTransform) | ||
| 152 | - | ||
| 153 | -} // namespace br | ||
| 154 | - | ||
| 155 | -#include "metadata/procrustes.moc" |