46 virtual QString
getName()
const {
return "Dimensionality"; }
70 if (neighbors.
size() >= 3) {
74 std::vector<double> eigValues;
79 eigVectors, eigValues);
82 double totalVariance = 0;
87 for (
unsigned j = 0; j < 3; ++j) {
88 sValues.
u[j] = eigValues[j];
89 totalVariance += sValues.
u[j];
92 assert(totalVariance != 0);
93 sValues /= totalVariance;
99 double a = std::min<double>(
100 1.0, std::max<double>(0.0, sValues.
x - sValues.
y));
101 double b = std::min<double>(
102 1.0, std::max<double>(
103 0.0, 2 * sValues.
x + 4 * sValues.
y - 2.0));
104 double c = 1.0 - a - b;
106 params[0] =
static_cast<float>(b + c / 2);
136 #ifdef COMPILE_PRIVATE_CANUPO
142 DimensionalityAndSFScaleParamsComputer() : m_firstScale(
true) {}
148 virtual QString
getName()
const {
return "Dimensionality + SF"; }
154 virtual bool needSF()
const {
return true; }
157 virtual void reset() {
162 m_defaultParams[0] = 0.5;
166 m_defaultParams[2] = 0.0;
175 bool& invalidScale) {
177 if (neighbors.
size() >= 3) {
179 unsigned validCount = 0;
181 for (
unsigned i = 0; i < neighbors.
size(); ++i) {
190 m_defaultParams[2] =
static_cast<float>(meanVal / validCount);
194 params[0] = m_defaultParams[0];
195 params[1] = m_defaultParams[1];
196 params[2] = m_defaultParams[2];
203 std::vector<double> eigValues;
205 Z.computeCovarianceMatrix(), eigVectors, eigValues,
208 eigVectors, eigValues);
211 double totalVariance = 0;
216 for (
unsigned j = 0; j < 3; ++j) {
217 sValues.u[j] = eigValues(j);
218 totalVariance += sValues.u[j];
221 assert(totalVariance != 0);
222 sValues /= totalVariance;
228 double a = std::min<double>(
229 1.0, std::max<double>(0.0, sValues.x - sValues.y));
230 double b = std::min<double>(
231 1.0, std::max<double>(
232 0.0, 2 * sValues.x + 4 * sValues.y - 2.0));
233 double c = 1.0 - a - b;
235 params[0] =
static_cast<float>(b + c / 2);
239 m_defaultParams[0] =
params[0];
240 m_defaultParams[1] =
params[1];
241 m_defaultParams[2] =
params[2];
242 m_firstScale =
false;
243 }
else if (m_firstScale)
246 params[0] = m_defaultParams[0];
247 params[1] = m_defaultParams[1];
248 params[2] = m_defaultParams[2];
250 }
else if (m_firstScale)
253 params[0] = m_defaultParams[0];
254 params[1] = m_defaultParams[1];
255 params[2] = m_defaultParams[2];
263 float m_defaultParams[3];
272 CurvatureScaleParamsComputer() : m_firstScale(true) {}
278 virtual QString
getName()
const {
return "Gaussian curvature"; }
284 virtual void reset() {
285 m_defaultParams[0] = 0;
293 bool& invalidScale) {
295 if (neighbors.
size() >= 6) {
297 params[0] = Z.computeCurvature(
302 m_defaultParams[0] =
params[0];
303 m_firstScale =
false;
304 }
else if (m_firstScale)
307 params[0] = m_defaultParams[0];
315 float m_defaultParams[1];
395 #ifdef COMPILE_PRIVATE_CANUPO
397 new DimensionalityAndSFScaleParamsComputer);
408 for (QMap<unsigned, ScaleParamsComputer*>::Iterator it =
map.begin();
409 it !=
map.end(); ++it) {
416 QMap<unsigned, ScaleParamsComputer*>
map;
429 return static_cast<unsigned>(
s_vault.
map.size());
443 QMap<unsigned, ScaleParamsComputer*>::Iterator it =
s_vault.
map.begin();
444 for (
unsigned i = 0; i < index; ++i) {
452 int scaleCount =
static_cast<int>(
m_scales.size());
453 int descCount =
static_cast<int>(
size());
455 if (scaleCount == 0 || descCount == 0)
return QByteArray();
457 int totalSize = 4 *
sizeof(int) +
461 QByteArray data(totalSize, Qt::Uninitialized);
463 if (data.capacity() < totalSize)
466 char* buffer = data.data();
469 *
reinterpret_cast<int*
>(buffer) = scaleCount;
470 buffer +=
sizeof(int);
471 *
reinterpret_cast<int*
>(buffer) = descCount;
472 buffer +=
sizeof(int);
473 *
reinterpret_cast<int*
>(buffer) =
static_cast<int>(
m_descriptorID);
474 buffer +=
sizeof(int);
475 *
reinterpret_cast<int*
>(buffer) =
static_cast<int>(
m_dimPerScale);
476 buffer +=
sizeof(int);
480 for (
int i = 0; i < scaleCount; ++i) {
481 *
reinterpret_cast<float*
>(buffer) =
m_scales[i];
482 buffer +=
sizeof(float);
488 for (
int j = 0; j < descCount; ++j) {
491 for (
size_t i = 0; i < desc.
params.size(); ++i) {
492 *
reinterpret_cast<float*
>(buffer) = desc.
params[i];
493 buffer +=
sizeof(
float);
503 if (data.size() < 2 *
sizeof(
int))
return false;
505 const char* buffer = data.data();
508 int scaleCount = *
reinterpret_cast<const int*
>(buffer);
509 buffer +=
sizeof(int);
510 int descCount = *
reinterpret_cast<const int*
>(buffer);
511 buffer +=
sizeof(int);
512 int descriptorID = *
reinterpret_cast<const int*
>(buffer);
513 buffer +=
sizeof(int);
516 int dimPerScale = *
reinterpret_cast<const int*
>(buffer);
517 buffer +=
sizeof(int);
521 if (scaleCount == 0 || descCount == 0)
return false;
524 int totalSize = 4 *
sizeof(int) +
527 if (data.size() < totalSize)
return false;
530 std::vector<float>
scales;
533 scales.resize(scaleCount);
534 }
catch (
const std::bad_alloc&) {
541 for (
int i = 0; i < scaleCount; ++i) {
542 scales[i] = *
reinterpret_cast<const float*
>(buffer);
543 buffer +=
sizeof(float);
552 for (
int j = 0; j < descCount; ++j) {
556 desc.
params[i] = *
reinterpret_cast<const float*
>(buffer);
557 buffer +=
sizeof(float);
577 size_t scaleCount =
m_scales.size();
580 for (
size_t i = 0; i <
size(); ++i)
at(i).params.resize(paramPerDesc);
581 }
catch (
const std::bad_alloc&) {
594 std::ifstream mscfile(qPrintable(
filename), std::ifstream::binary);
596 if (!mscfile.is_open()) {
597 error =
"Failed to open input file";
603 mscfile.read((
char*)&ncorepoints,
sizeof(ncorepoints));
605 mscfile.read((
char*)&nscales_msc,
sizeof(
int));
615 }
catch (
const std::bad_alloc&) {
617 error =
"Not enough memory";
629 std::vector<float>
scales;
631 scales.resize(nscales_msc);
632 }
catch (
const std::bad_alloc&) {
634 error =
"Not enough memory";
638 for (
int si = 0; si < nscales_msc; ++si)
639 mscfile.read((
char*)&
scales[si],
sizeof(
float));
644 error =
"Not enough memory";
653 mscfile.read((
char*)&ptnparams,
sizeof(
int));
655 std::vector<cloudViewer::ScalarField*> paramsSf(3, 0);
658 for (
int i = 3; i < ptnparams; ++i) {
660 qPrintable(QString(
"scalar #%1").arg(i - 2)));
661 paramsSf.push_back(sfIdx >= 0 ?
corePoints->getScalarField(sfIdx)
666 error =
"Not enough memory to import additional scalars! (they "
667 "are not used for classification anyway)";
673 for (
int pt = 0; pt < ncorepoints; ++pt) {
675 mscfile.read((
char*)&x,
sizeof(
float));
676 mscfile.read((
char*)&y,
sizeof(
float));
677 mscfile.read((
char*)&z,
sizeof(
float));
679 if (ptnparams >= 4) {
681 mscfile.read((
char*)&dummy,
684 for (
int i = 4; i < ptnparams; ++i) {
686 mscfile.read((
char*)¶m,
sizeof(
float));
688 if (
static_cast<int>(paramsSf.size()) > i)
689 paramsSf[i]->addElement(
static_cast<ScalarType
>(param));
693 for (
int s = 0; s < nscales_msc; ++s) {
695 mscfile.read((
char*)(&a),
sizeof(
float));
696 mscfile.read((
char*)(&b),
sizeof(
float));
699 float c = 1.0f - a - b;
701 float y = c * sqrt(3.0f) / 2;
702 at(pt).params[s * 2] = x;
703 at(pt).params[s * 2 + 1] = y;
708 for (
int i = 0; i < nscales_msc; ++i)
709 mscfile.read((
char*)&dummyInt,
sizeof(
int));
718 for (
size_t i = 3; i < paramsSf.size(); ++i) {
720 paramsSf[i]->computeMinAndMax();
724 paramsSf[i]->getName()));
Vector3Tpl< PointCoordinateType > CCVector3
Default 3D Vector.
cmdLineReadable * params[]
static ScaleParamsComputerVault s_vault
static const double SQRT_3_DIV_2
static const unsigned DESC_DIMENSIONALITY
static const unsigned DESC_CURVATURE
static const unsigned DESC_DIMENSIONALITY_SF
const std::vector< float > & scales() const
Returns associated scales.
const unsigned descriptorID() const
Returns associated descriptor ID.
std::vector< float > m_scales
Associated scales.
unsigned m_descriptorID
Associated descriptor ID.
bool setScales(const std::vector< float > &scales)
Sets associated scales.
const unsigned dimPerScale() const
Returns the number of dimensions per scale.
QByteArray toByteArray() const
Converts structure to a byte array.
bool fromByteArray(const QByteArray &data)
Inits structure from a byte array.
bool loadFromMSC(QString filename, QString &error, ccPointCloud *corePoints=0)
Loads structure of descriptors from an ".msc" file (see Brodu's version)
unsigned m_dimPerScale
Dimensions per scale.
DimensionalityScaleParamsComputer()
Default constructor.
virtual QString getName() const
Returns the associated descriptor name.
bool m_firstScale
First scale flag.
virtual void reset()
Called once before computing parameters at first scale.
float m_defaultParams[2]
Default parameters (or last computed scale's ones!)
virtual unsigned dimPerScale() const
Returns the number of dimensions per scale for this descriptor.
virtual unsigned getID() const
Returns the associated descriptor ID.
virtual bool computeScaleParams(cloudViewer::ReferenceCloud &neighbors, double radius, float params[], bool &invalidScale)
Computes the parameters at a given scale.
Jacobi eigen vectors/values decomposition.
static bool SortEigenValuesAndVectors(SquareMatrix &eigenVectors, EigenValues &eigenValues)
Generic parameters 'computer' class (at a given scale)
static ScaleParamsComputer * GetByID(unsigned descID)
Vault: returns the computer corresponding to the given ID.
virtual unsigned dimPerScale() const =0
Returns the number of dimensions per scale for this descriptor.
static unsigned AvailableCount()
Returns the number of available 'descriptors'.
static ScaleParamsComputer * GetByIndex(unsigned index)
Vault: returns the ith computer.
virtual unsigned getID() const =0
Returns the associated descriptor ID.
virtual bool computeScaleParams(cloudViewer::ReferenceCloud &neighbors, double radius, float params[], bool &invalidScale)=0
Computes the parameters at a given scale.
virtual QString getName() const =0
Returns the associated descriptor name.
virtual void reset()=0
Called once before computing parameters at first scale.
virtual bool needSF() const
Returns whether the computer requires a scalar field or not.
A 3D cloud and its associated features (color, normals, scalar fields, etc.)
cloudViewer::SquareMatrixd computeCovarianceMatrix()
Computes the covariance matrix.
A very simple point cloud (no point duplication)
unsigned size() const override
Returns the number of points.
const CCVector3 * getPoint(unsigned index) const override
Returns the ith point.
ScalarType getPointScalarValue(unsigned pointIndex) const override
Returns the ith point associated scalar value.
static bool ValidValue(ScalarType value)
Returns whether a scalar value is valid or not.
static void error(char *msg)
std::vector< float > params
ScaleParamsComputerVault()
Default constructor.
QMap< unsigned, ScaleParamsComputer * > map
~ScaleParamsComputerVault()
Destructor.