36 float& condnumber)
const {
38 if (
path.size() < 2) {
50 unsigned numcross = 0;
53 float closestSquareDist = -1.0f;
55 size_t segCount =
path.size() - 1;
56 for (
size_t i = 0; i < segCount; ++i) {
63 condnumber = std::max<float>(condnumber,
fabs(v.
dot(u)));
66 float denom = (u.
x * v.
y - v.
x * u.
y);
72 float alpha = (AP.
y * v.
x - AP.
x * v.
y) / denom;
73 bool pathIntersects = (alpha >= 0 && alpha * alpha <= PR.
norm2());
75 float beta = (AP.
y * u.
x - AP.
x * u.
y) / denom;
78 bool refSegIntersects =
79 ((i == 0 || beta >= 0) &&
88 if (refSegIntersects) numcross++;
94 float squareDistToSeg = 0;
95 float distAH = v.
dot(AP);
96 if ((i == 0 || distAH >= 0.0) &&
97 (i + 1 == segCount || distAH <= AB.
norm())) {
100 squareDistToSeg = PH.
norm2();
108 if (closestSquareDist < 0 || squareDistToSeg < closestSquareDist) {
109 closestSquareDist = squareDistToSeg;
113 assert(closestSquareDist >= 0);
114 float deltaNorm = sqrt(closestSquareDist);
116 return ((numcross & 1) == 0 ? deltaNorm : -deltaNorm);
120 float condpos, condneg;
126 return condpos < condneg ? predpos : -predneg;
138 size_t paramCount = mscdata.
params.size();
139 assert(weightCount <= paramCount);
140 unsigned shift =
static_cast<unsigned>(paramCount - weightCount);
144 for (
size_t i = 0; i < weightCount; ++i) {
158 std::vector<Classifier>& classifiers,
159 std::vector<float>& scales,
164 if (!file.open(QIODevice::ReadOnly)) {
165 error = QString(
"Failed to open input classifier file!");
179 file.read(
reinterpret_cast<char*
>(&nscales),
sizeof(
unsigned));
184 if (nscales == 9999) {
187 file.read(
reinterpret_cast<char*
>(&
descriptorID),
sizeof(
unsigned));
189 file.read(
reinterpret_cast<char*
>(&
dimPerScale),
sizeof(
unsigned));
191 file.read(
reinterpret_cast<char*
>(&nscales),
sizeof(
unsigned));
197 }
catch (
const std::bad_alloc&) {
198 error = QString(
"Not enough memory!");
204 for (
unsigned s = 0; s < nscales; ++s)
205 file.read(
reinterpret_cast<char*
>(&
scales[s]),
sizeof(
float));
209 unsigned nclassifiers;
210 file.read(
reinterpret_cast<char*
>(&nclassifiers),
sizeof(
unsigned));
225 classifiers.resize(nclassifiers);
226 }
catch (
const std::bad_alloc&) {
227 error = QString(
"Not enough memory!");
234 for (
unsigned ci = 0; ci < nclassifiers; ++ci) {
242 file.read(
reinterpret_cast<char*
>(&classifier.
class1),
sizeof(
int));
243 file.read(
reinterpret_cast<char*
>(&classifier.
class2),
sizeof(
int));
247 for (
unsigned i = 0; i <= fdim; ++i)
248 file.read(
reinterpret_cast<char*
>(
254 for (
unsigned i = 0; i <= fdim; ++i)
255 file.read(
reinterpret_cast<char*
>(
261 file.read(
reinterpret_cast<char*
>(&pathsize),
sizeof(
unsigned));
262 classifier.
path.resize(pathsize);
264 for (
unsigned i = 0; i < pathsize; ++i) {
265 file.read(
reinterpret_cast<char*
>(&classifier.
path[i].x),
267 file.read(
reinterpret_cast<char*
>(&classifier.
path[i].y),
272 file.read(
reinterpret_cast<char*
>(&classifier.
refPointPos.
x),
274 file.read(
reinterpret_cast<char*
>(&classifier.
refPointPos.
y),
276 file.read(
reinterpret_cast<char*
>(&classifier.
refPointNeg.
x),
278 file.read(
reinterpret_cast<char*
>(&classifier.
refPointNeg.
y),
280 file.read(
reinterpret_cast<char*
>(&classifier.
absMaxXY),
291 }
catch (
const std::bad_alloc&) {
292 error = QString(
"Not enough memory!");
301 if (!file.open(QIODevice::WriteOnly)) {
302 error = QString(
"Failed to open output file!");
312 const unsigned headerCode = 9999;
313 file.write(
reinterpret_cast<const char*
>(&headerCode),
317 file.write(
reinterpret_cast<const char*
>(&
descriptorID),
320 file.write(
reinterpret_cast<const char*
>(&
dimPerScale),
325 unsigned nscales =
static_cast<unsigned>(
scales.size());
326 file.write(
reinterpret_cast<const char*
>(&nscales),
sizeof(unsigned));
330 for (
unsigned s = 0; s < nscales; ++s)
331 file.write(
reinterpret_cast<const char*
>(&
scales[s]),
336 unsigned nclassifiers = 1;
337 file.write(
reinterpret_cast<const char*
>(&nclassifiers),
sizeof(unsigned));
341 file.write(
reinterpret_cast<const char*
>(&
class1),
sizeof(int));
342 file.write(
reinterpret_cast<const char*
>(&
class2),
sizeof(int));
346 for (
unsigned i = 0; i <= fdim; ++i)
347 file.write(
reinterpret_cast<const char*
>(&
weightsAxis1[i]),
352 for (
unsigned i = 0; i <= fdim; ++i)
353 file.write(
reinterpret_cast<const char*
>(&
weightsAxis2[i]),
357 unsigned pathsize =
static_cast<unsigned>(
path.size());
358 file.write(
reinterpret_cast<const char*
>(&pathsize),
sizeof(unsigned));
360 for (
unsigned i = 0; i < pathsize; ++i) {
361 file.write(
reinterpret_cast<const char*
>(&
path[i].x),
363 file.write(
reinterpret_cast<const char*
>(&
path[i].y),
368 file.write(
reinterpret_cast<const char*
>(&
refPointPos.
x),
sizeof(float));
369 file.write(
reinterpret_cast<const char*
>(&
refPointPos.
y),
sizeof(float));
370 file.write(
reinterpret_cast<const char*
>(&
refPointNeg.
x),
sizeof(float));
371 file.write(
reinterpret_cast<const char*
>(&
refPointNeg.
y),
sizeof(float));
372 file.write(
reinterpret_cast<const char*
>(&
absMaxXY),
sizeof(float));
373 file.write(
reinterpret_cast<const char*
>(&
axisScaleRatio),
sizeof(float));
static const unsigned DESC_DIMENSIONALITY
static const unsigned DESC_INVALID
std::vector< float > weightsAxis2
static bool Load(QString filename, std::vector< Classifier > &classifiers, std::vector< float > &scales, QString &error, FileHeader *header=0, bool headerOnly=false)
Loads a CANUPO's classifier file (.prm)
float classify2D(const Point2D &P) const
Classification in the 2D space.
float classify2D_checkcondnum(const Point2D &P, const Point2D &R, float &condnumber) const
Checks numerical condition.
bool save(QString filename, QString &error)
Saves classifier as a CANUPO's classifier file (.prm)
unsigned dimPerScale
Dimension (per-scale)
Point2D project(const CorePointDesc &mscdata) const
Projects a parameter vector in (2D) MSC space.
unsigned descriptorID
Associated descriptor ID (see ccPointDescriptor.h)
std::vector< float > weightsAxis1
std::vector< Point2D > path
std::vector< float > scales
Associated scales.
float classify(const CorePointDesc &mscdata) const
Classification in MSC space.
bool checkRefPoints()
Checks the ref. points.
Classifier()
Default constructor.
Type dot(const Vector2Tpl &v) const
Dot product.
Type norm() const
Returns vector norm.
void normalize()
Sets vector norm to unity.
Type norm2() const
Returns vector square norm.
__host__ __device__ float2 fabs(float2 v)
static void error(char *msg)
void swap(cloudViewer::core::SmallVectorImpl< T > &LHS, cloudViewer::core::SmallVectorImpl< T > &RHS)
Implement std::swap in terms of SmallVector swap.
std::vector< float > params