145 lines
4.9 KiB
C++
145 lines
4.9 KiB
C++
/*
|
||
----
|
||
This file is part of SECONDO.
|
||
|
||
Copyright (C) 2019,
|
||
Faculty of Mathematics and Computer Science,
|
||
Database Systems for New Applications.
|
||
|
||
SECONDO is free software; you can redistribute it and/or modify
|
||
it under the terms of the GNU General Public License as published by
|
||
the Free Software Foundation; either version 2 of the License, or
|
||
(at your option) any later version.
|
||
|
||
SECONDO is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
GNU General Public License for more details.
|
||
|
||
You should have received a copy of the GNU General Public License
|
||
along with SECONDO; if not, write to the Free Software
|
||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||
----
|
||
|
||
|
||
//[<] [\ensuremath{<}]
|
||
//[>] [\ensuremath{>}]
|
||
|
||
\setcounter{tocdepth}{3}
|
||
\tableofcontents
|
||
|
||
|
||
|
||
1 The ObjectIdManager class
|
||
|
||
During analysis of a Pointcloud2, this class provides free object ids
|
||
and the corresponding category ids. It also stores the object id of the
|
||
biggest object which a point was assigned to so far. If alter in the
|
||
analysis an even bigger object is found for the same point, that object
|
||
will be preferred.
|
||
|
||
*/
|
||
#include "ObjectIdManager.h"
|
||
#include <cassert>
|
||
|
||
using namespace pointcloud2;
|
||
|
||
ObjectIdManager::ObjectIdManager(const size_t pointCount,
|
||
const int maxObjIdInCloud, const bool overwriteOldObjIDs,
|
||
const int attrIndexObjID, const int attrIndexCatID) :
|
||
_idOfBestObject(1 + pointCount, 0),
|
||
_maxObjIdAtStart(maxObjIdInCloud),
|
||
_overwriteOldObjIDs(overwriteOldObjIDs),
|
||
_currentCategory(1),
|
||
_attrIndexObjID(attrIndexObjID),
|
||
_attrIndexCatID(attrIndexCatID)
|
||
{
|
||
_objects.push_back(ObjInfo(0, 0, 0)); // element [0] is never used
|
||
}
|
||
|
||
size_t ObjectIdManager::addObject(const unsigned objectSize,
|
||
const unsigned objectCohesion, const double bboxPerimeter) {
|
||
size_t objId = _objects.size(); // the index of the new _objets entry
|
||
double objectDensity = objectCohesion; // rather not: ... / bboxPerimeter;
|
||
_objects.push_back(
|
||
ObjInfo(objectSize, objectDensity, _currentCategory));
|
||
return objId;
|
||
}
|
||
|
||
void ObjectIdManager::categoryFinished() {
|
||
++_currentCategory;
|
||
}
|
||
|
||
bool ObjectIdManager::setNewObjIdIfObjectBigger(
|
||
const int pointIndex, const int newObjID) {
|
||
// if one of the objIds is SCAN_NOISE or SCAN_UNCLASSIFIED,
|
||
// use the other object
|
||
assert (pointIndex < int(_idOfBestObject.size()));
|
||
assert (newObjID > 0);
|
||
|
||
int oldObjID = _idOfBestObject[pointIndex];
|
||
if (oldObjID <= 0) { // this point was not assigned to an object before
|
||
_idOfBestObject[pointIndex] = newObjID;
|
||
return true;
|
||
}
|
||
|
||
assert (oldObjID < int(_objects.size()) &&
|
||
newObjID < int(_objects.size()));
|
||
int oldObjDensity = _objects[oldObjID]._density;
|
||
int newObjDensity = _objects[newObjID]._density;
|
||
|
||
// TODO: Kommentar anpassen
|
||
// as the point could be assigned to two objects, choose the bigger
|
||
// object (i.e. bigger by count of matching points); the other objects
|
||
// "loses" this point, so its size is decreased
|
||
if (oldObjDensity < newObjDensity) {
|
||
_idOfBestObject[pointIndex] = newObjID;
|
||
--_objects[oldObjID]._size;
|
||
return true;
|
||
} else {
|
||
--_objects[newObjID]._size;
|
||
return false;
|
||
}
|
||
}
|
||
|
||
int ObjectIdManager::appointFinalObjIDs(const size_t requiredObjectSize) {
|
||
int finalObjId = _maxObjIdAtStart;
|
||
_catInfos.resize(_currentCategory, CatInfo(0, 0));
|
||
for (ObjInfo& obj : _objects) {
|
||
obj._finalObjId =
|
||
(obj._size < requiredObjectSize) ? 0 : ++finalObjId;
|
||
// add this object to the category info statistics
|
||
if (obj._finalObjId > 0) {
|
||
size_t catId = obj._catId;
|
||
++_catInfos[catId]._objCount;
|
||
_catInfos[catId]._sizeSum += obj._size;
|
||
}
|
||
}
|
||
return finalObjId;
|
||
}
|
||
|
||
int ObjectIdManager::getFinalObjID(const size_t pointIndex) const {
|
||
int objId = _idOfBestObject[pointIndex];
|
||
return (objId < 0) ? 0 : _objects[objId]._finalObjId;
|
||
}
|
||
|
||
size_t ObjectIdManager::getCategoryID(const size_t pointIndex) const {
|
||
int objId = _idOfBestObject[pointIndex];
|
||
return (objId < 0) ? 0 : _objects[objId]._catId;
|
||
}
|
||
|
||
/* the number of objects assigned to the given category.
|
||
* This can only be called after appointFinalObjIds() was called. */
|
||
size_t ObjectIdManager::getObjectCount(const size_t categoryId) const {
|
||
assert (categoryId < _catInfos.size());
|
||
return _catInfos[categoryId]._objCount;
|
||
}
|
||
|
||
/* returns the total number of points assigned to any object of the
|
||
* given category. This can only be called after appointFinalObjIds()
|
||
* was called. */
|
||
size_t ObjectIdManager::getAssignedPointCount(const size_t categoryId) const {
|
||
assert (categoryId < _catInfos.size());
|
||
return _catInfos[categoryId]._sizeSum;
|
||
}
|