Commit 16f41d0221a1028627eda7c367a87fea0c2222c7

Authored by Josh Klontz
1 parent 897b65bd

remove synthesizekeypoints

openbr/plugins/imgproc/synthesizekeypoints.cpp deleted
1   -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2   - * Copyright 2015 Noblis *
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 <opencv2/imgproc/imgproc.hpp>
18   -#include "openbr/plugins/openbr_internal.h"
19   -#include "openbr/core/qtutils.h"
20   -#include "openbr/core/opencvutils.h"
21   -#include "openbr/core/eigenutils.h"
22   -#include "openbr/core/common.h"
23   -#include <QString>
24   -#include <Eigen/SVD>
25   -#include <Eigen/Dense>
26   -
27   -using namespace std;
28   -using namespace cv;
29   -using namespace Eigen;
30   -
31   -namespace br
32   -{
33   -
34   -// SynthesizePointsTransform helper class
35   -struct TriangleIndicies
36   -{
37   - int indicies[3];
38   -
39   - TriangleIndicies()
40   - {
41   - indicies[0] = 0;
42   - indicies[1] = 0;
43   - indicies[2] = 0;
44   - }
45   -
46   - TriangleIndicies(QList<int> indexList)
47   - {
48   - assert(indexList.size() == 3);
49   - qSort(indexList);
50   - indicies[0] = indexList[0];
51   - indicies[1] = indexList[1];
52   - indicies[2] = indexList[2];
53   - }
54   -};
55   -
56   -inline bool operator==(const TriangleIndicies &a, const TriangleIndicies &b)
57   -{
58   - return (a.indicies[0] == b.indicies[0]) && (a.indicies[1] == b.indicies[1]) && (a.indicies[2] == b.indicies[2]);
59   -}
60   -
61   -inline uint qHash(const TriangleIndicies &key)
62   -{
63   - return ::qHash(key.indicies[0]) ^ ::qHash(key.indicies[1]) ^ ::qHash(key.indicies[2]);
64   -}
65   -
66   -QDataStream &operator<<(QDataStream &stream, const TriangleIndicies &ti)
67   -{
68   - return stream << ti.indicies[0] << ti.indicies[1] << ti.indicies[2];
69   -}
70   -
71   -QDataStream &operator>>(QDataStream &stream, TriangleIndicies &ti)
72   -{
73   - return stream >> ti.indicies[0] >> ti.indicies[1] >> ti.indicies[2];
74   -}
75   -
76   -/*!
77   - * \ingroup transforms
78   - * \brief Synthesize additional points via triangulation.
79   - * \author Josh Klontz \cite jklontz
80   - */
81   -class SynthesizePointsTransform : public MetadataTransform
82   -{
83   - Q_OBJECT
84   - Q_PROPERTY(float minRelativeDistance READ get_minRelativeDistance WRITE set_minRelativeDistance RESET reset_minRelativeDistance STORED false)
85   - BR_PROPERTY(float, minRelativeDistance, 0) // [0, 1] range controlling whether or not to nearby synthetic points.
86   - // 0 = keep all points, 1 = keep only the most distance point.
87   -
88   - QList<TriangleIndicies> triangles;
89   -
90   - static QRectF getBounds(const QList<QPointF> &points, int dstPadding)
91   - {
92   - float srcMinX = FLT_MAX;
93   - float srcMinY = FLT_MAX;
94   - float srcMaxX = -FLT_MAX;
95   - float srcMaxY = -FLT_MAX;
96   - foreach (const QPointF &point, points) {
97   - if (point.x() < srcMinX) srcMinX = point.x();
98   - if (point.y() < srcMinY) srcMinY = point.y();
99   - if (point.x() > srcMaxX) srcMaxX = point.x();
100   - if (point.y() > srcMaxY) srcMaxY = point.y();
101   - }
102   -
103   - const float padding = (srcMaxX - srcMinX) / 80 * dstPadding;
104   - return QRectF(qRound(srcMinX - padding), qRound(srcMinY - padding), qRound(srcMaxX - srcMinX + 2 * padding), qRound(srcMaxY - srcMinY + 2 * padding));
105   - }
106   -
107   - static int getVertexIndex(const QPointF &trianglePts, const QList<QPointF> &pts)
108   - {
109   - for (int i = 0; i < pts.size(); i++)
110   - // Check points using single precision accuracy to avoid potential rounding error
111   - if ((float(trianglePts.x()) == float(pts[i].x())) && (float(trianglePts.y()) == float(pts[i].y())))
112   - return i;
113   - qFatal("Couldn't identify index of requested point!");
114   - return -1;
115   - }
116   -
117   - static QList<QList<int> > getTriangulation(const QList<QPointF> &points, const QRectF &bound)
118   - {
119   - Subdiv2D subdiv(OpenCVUtils::toRect(bound));
120   - foreach (const QPointF &point, points) {
121   - if (!bound.contains(point))
122   - return QList<QList<int> >();
123   - subdiv.insert(OpenCVUtils::toPoint(point));
124   - }
125   -
126   -
127   - vector<Vec6f> triangleList;
128   - subdiv.getTriangleList(triangleList);
129   -
130   - QList<QList<int> > triangleIndices;
131   - foreach (const Vec6f &triangle, triangleList) {
132   - bool valid = true;
133   - const QPointF vertices[3] = { QPointF(triangle[0], triangle[1]),
134   - QPointF(triangle[2], triangle[3]),
135   - QPointF(triangle[4], triangle[5]) };
136   - for (int j = 0; j < 3; j++)
137   - if (vertices[j].x() > bound.right() || vertices[j].y() > bound.bottom() || vertices[j].x() < bound.left() || vertices[j].y() < bound.top()) {
138   - valid = false;
139   - break;
140   - }
141   -
142   - if (valid) {
143   - QList<int> tri;
144   - for (int j = 0; j < 3; j++)
145   - tri.append(getVertexIndex(vertices[j], points));
146   - triangleIndices.append(tri);
147   - }
148   - }
149   -
150   - return triangleIndices;
151   - }
152   -
153   - void train(const TemplateList &data)
154   - {
155   - // Because not all triangulations are the same, we have to decide on a canonical set of triangles at training time.
156   - QHash<TriangleIndicies, int> counts;
157   - foreach (const Template &datum, data) {
158   - const QList<QPointF> points = datum.file.points();
159   - if (points.size() <= 4)
160   - continue;
161   -
162   - const QList< QList<int> > triangulation = getTriangulation(points, getBounds(points, 10));
163   - if (triangulation.empty())
164   - continue;
165   -
166   - foreach (const QList<int> &indicies, triangulation)
167   - counts[TriangleIndicies(indicies)]++;
168   - }
169   -
170   - if (counts.empty())
171   - return;
172   -
173   - triangles.clear();
174   - QHash<TriangleIndicies, int>::const_iterator i = counts.constBegin();
175   - while (i != counts.constEnd()) {
176   - if (3 * i.value() > data.size())
177   - triangles.append(i.key()); // Keep triangles that occur in at least a third of the training instances
178   - ++i;
179   - }
180   -
181   - if (minRelativeDistance > 0) { // Discard relatively small triangles
182   - QVector<float> averageMinDistances(triangles.size());
183   - foreach (const Template &datum, data) {
184   - File dst;
185   - projectMetadata(datum.file, dst);
186   - const QList<QPointF> points = dst.points();
187   -
188   - QVector<float> minDistances(triangles.size());
189   - for (int i=0; i<triangles.size(); i++) {
190   - // Work backwards so that we can also consider distances between synthetic points
191   - const QPointF &point = points[points.size()-1-i];
192   - float minDistance = std::numeric_limits<float>::max();
193   - for (int j=0; j<points.size()-1-i; j++)
194   - minDistance = min(minDistance, sqrtf(powf(point.x() - points[j].x(), 2.f) + powf(point.y() - points[j].y(), 2.f)));
195   - minDistances[triangles.size()-1-i] = minDistance;
196   - }
197   -
198   - const float maxMinDistance = Common::Max(minDistances);
199   - for (int i=0; i<minDistances.size(); i++)
200   - averageMinDistances[i] += (minDistances[i] / maxMinDistance);
201   - }
202   -
203   - const float maxAverageMinDistance = Common::Max(averageMinDistances);
204   - for (int i=averageMinDistances.size()-1; i>=0; i--)
205   - if (averageMinDistances[i] / maxAverageMinDistance < minRelativeDistance)
206   - triangles.removeAt(i);
207   - }
208   -
209   - if (Globals->verbose)
210   - qDebug() << "Kept" << triangles.size() << "of" << counts.size() << "triangles.";
211   - }
212   -
213   - void projectMetadata(const File &src, File &dst) const
214   - {
215   - QList<QPointF> points = src.points();
216   - if (points.size() == 0) {
217   - dst.fte = true;
218   - return;
219   - }
220   -
221   - foreach (const TriangleIndicies &triangle, triangles) {
222   - const QPointF &p0 = points[triangle.indicies[0]];
223   - const QPointF &p1 = points[triangle.indicies[1]];
224   - const QPointF &p2 = points[triangle.indicies[2]];
225   - points.append((p0 + p1 + p2) / 3 /* append the centroid of the triangle */);
226   - }
227   - dst.setPoints(points);
228   - }
229   -
230   - void store(QDataStream &stream) const
231   - {
232   - stream << triangles;
233   - }
234   -
235   - void load(QDataStream &stream)
236   - {
237   - stream >> triangles;
238   - }
239   -};
240   -
241   -BR_REGISTER(Transform, SynthesizePointsTransform)
242   -
243   -} // namespace br
244   -
245   -#include "synthesizekeypoints.moc"