42 #include <boost/format.hpp> 43 #include <boost/filesystem/path.hpp> 44 #include <boost/filesystem/operations.hpp> 45 #include <boost/lexical_cast.hpp> 51 void setupArgs(
int argc,
char *argv[],
unsigned int& startId,
unsigned int& endId,
string& extension);
57 int main(
int argc,
char *argv[])
70 bool debugMode =
false;
78 std::shared_ptr<PM::Transformation> rigidTransform;
79 rigidTransform =
PM::get().TransformationRegistrar.create(
"RigidTransformation");
82 transformations.push_back(rigidTransform);
85 TP
Tread = TP::Identity(4,4);
87 TP
Tref = TP::Identity(4,4);
89 unsigned startingI = 0;
90 unsigned listSizeI = list.size();
91 unsigned listSizeJ = list.size();
95 listSizeI = startingI + 1;
98 PM::Matrix overlapResults = PM::Matrix::Ones(listSizeJ, listSizeI);
100 for(
unsigned i = startingI; i < listSizeI; i++)
102 unsigned startingJ = i+1;
106 listSizeJ = startingJ + 1;
108 for(
unsigned j = startingJ; j < listSizeJ; j++)
111 reading =
DP::load(list[i].readingFileName);
112 reference =
DP::load(list[j].readingFileName);
114 cout <<
"Point cloud loaded" << endl;
117 if(list[i].groundTruthTransformation.rows() != 0)
119 Tread = list[i].groundTruthTransformation;
120 Tref = list[j].groundTruthTransformation;
124 cout <<
"ERROR: fields gTXX (i.e., ground truth matrix) is required" << endl;
129 transformations.apply(reading, Tread);
130 transformations.apply(reference, Tref);
133 std::shared_ptr<PM::DataPointsFilter> subSample =
134 PM::get().DataPointsFilterRegistrar.create(
135 "RandomSamplingDataPointsFilter",
139 std::shared_ptr<PM::DataPointsFilter> maxDensity =
140 PM::get().DataPointsFilterRegistrar.create(
141 "MaxDensityDataPointsFilter" 152 PM::get().DataPointsFilterRegistrar.create(
153 "SurfaceNormalDataPointsFilter",
156 {
"keepDensities",
"1"}
160 reading = subSample->filter(reading);
161 reading = computeDensity->filter(reading);
162 reading = maxDensity->filter(reading);
164 const Matrix inliersRead = Matrix::Zero(1, reading.
features.cols());
167 reference = subSample->filter(reference);
168 reference = computeDensity->filter(reference);
169 reference = maxDensity->filter(reference);
170 const Matrix inliersRef = Matrix::Zero(1, reference.
features.cols());
177 for(
int l = 0; l < 2; l++)
179 const int selfPtsCount =
self.features.cols();
180 const int targetPtsCount = target.
features.cols();
185 std::shared_ptr<PM::Matcher> matcherSelf =
186 PM::get().MatcherRegistrar.create(
191 std::shared_ptr<PM::Matcher> matcherTarget =
192 PM::get().MatcherRegistrar.create(
193 "KDTreeVarDistMatcher",
196 {
"maxDistField",
"maxSearchDist"}
200 matcherSelf->init(
self);
201 matcherTarget->init(target);
203 Matches selfMatches(knn, selfPtsCount);
204 selfMatches = matcherSelf->findClosests(
self);
206 const Matrix maxSearchDist = selfMatches.dists.colwise().maxCoeff().cwiseSqrt();
207 self.addDescriptor(
"maxSearchDist", maxSearchDist);
209 Matches targetMatches(knnAll, targetPtsCount);
210 targetMatches = matcherTarget->findClosests(
self);
212 BOOST_AUTO(inlierSelf,
self.getDescriptorViewByName(
"inliers"));
214 for(
int i = 0; i < selfPtsCount; i++)
216 for(
int k = 0; k < knnAll; k++)
218 if (targetMatches.dists(k, i) != Matches::InvalidDist)
220 inlierSelf(0,i) = 1.0;
221 inlierTarget(0,targetMatches.ids(k, i)) = 1.0;
230 const BOOST_AUTO(finalInlierSelf,
self.getDescriptorViewByName(
"inliers"));
232 const double selfRatio = (finalInlierSelf.array() > 0).count()/(double)finalInlierSelf.cols();
233 const double targetRatio = (finalInlierTarget.array() > 0).count()/(double)finalInlierTarget.cols();
235 cout << i <<
" -> " << j <<
": " << selfRatio << endl;
236 cout << j <<
" -> " << i <<
": " << targetRatio << endl;
240 self.save(
"scan_i.vtk");
241 target.
save(
"scan_j.vtk");
245 overlapResults(j,i) = selfRatio;
246 overlapResults(i,j) = targetRatio;
253 std::fstream outFile;
254 outFile.open(
"overlapResults.csv", fstream::out);
255 for(
int x=0;
x < overlapResults.rows();
x++)
257 for(
int y=0; y < overlapResults.cols(); y++)
259 outFile << overlapResults(
x, y) <<
", ";
272 if (!(argc == 2 || argc == 4))
275 cerr <<
" ERROR in command line" << endl << endl;
276 cerr <<
" Usage: " << argv[0] <<
" listOfFiles.csv <i j>" << endl;
277 cerr <<
" Note: 'i' and 'j' are optional arguments. If used, only compute the overlap for those 2 point cloud ids and dump VTK files for visual inspection." << endl;
279 cerr <<
" Example: " << endl;
280 cerr <<
" $ " << argv[0] <<
" ../example/data/carCloudList.csv" << endl;
PM::Transformations Transformations
std::shared_ptr< Interface > create(const std::string &name, const Parametrizable::Parameters ¶ms=Parametrizable::Parameters()) const
Create an instance.
IO Functions and classes that are dependant on scalar type are defined in this templatized class...
PointMatcherIO< float > PMIO
std::string toParam(const S &value)
Return the a string value using lexical_cast.
A factor for subclasses of Interface.
void validateArgs(int argc, char *argv[])
void setLogger(std::shared_ptr< Logger > newLogger)
Set a new logger, protected by a mutex.
void setupArgs(int argc, char *argv[], unsigned int &startId, unsigned int &endId, string &extension)
ConstView getDescriptorViewByName(const std::string &name) const
Get a const view on a descriptor by name, throw an exception if it does not exist.
PM::DataPoints DataPoints
Eigen::Matrix< float, Eigen::Dynamic, Eigen::Dynamic > Matrix
A dense matrix over ScalarType.
int main(int argc, char *argv[])
Functions and classes that are not dependant on scalar type are defined in this namespace.
static const PointMatcher & get()
Return instances.
Target lexical_cast(const Source &arg)
General case of lexical cast, use boost.
PM::TransformationParameters TP
void save(const std::string &fileName, bool binary=false) const
Save a point cloud to a file, determine format from extension.
A vector of file info, to be used in batch processing.
static void swapDataPoints(DataPoints &a, DataPoints &b)
Exchange in place point clouds a and b, with no data copy.
Matrix features
features of points in the cloud
static DataPoints load(const std::string &fileName)
Load a point cloud from a file, determine format from extension.
void addDescriptor(const std::string &name, const Matrix &newDescriptor)
Add a descriptor by name, remove first if already exists.
T computeDensity(const typename PointMatcher< T >::Matrix &NN)
Matrix TransformationParameters
A matrix holding the parameters a transformation.