|
|
|
@ -38,9 +38,8 @@ |
|
|
|
|
//
|
|
|
|
|
// Author: Tolga Birdal <tbirdal AT gmail.com>
|
|
|
|
|
|
|
|
|
|
#include "opencv2/ppf_match_3d.hpp" |
|
|
|
|
#include "opencv2/surface_matching.hpp" |
|
|
|
|
#include <iostream> |
|
|
|
|
#include "opencv2/icp.hpp" |
|
|
|
|
#include "opencv2/surface_matching/ppf_helpers.hpp" |
|
|
|
|
#include "opencv2/core/utility.hpp" |
|
|
|
|
|
|
|
|
@ -48,83 +47,100 @@ using namespace std; |
|
|
|
|
using namespace cv; |
|
|
|
|
using namespace ppf_match_3d; |
|
|
|
|
|
|
|
|
|
static void help(std::string errorMessage) |
|
|
|
|
static void help(const string& errorMessage) |
|
|
|
|
{ |
|
|
|
|
std::cout<<"Program init error : "<<errorMessage<<std::endl; |
|
|
|
|
std::cout<<"\nUsage : ppf_matching [input model file] [input scene file]"<<std::endl; |
|
|
|
|
std::cout<<"\nPlease start again with new parameters"<<std::endl; |
|
|
|
|
cout << "Program init error : "<< errorMessage << endl; |
|
|
|
|
cout << "\nUsage : ppf_matching [input model file] [input scene file]"<< endl; |
|
|
|
|
cout << "\nPlease start again with new parameters"<< endl; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int main(int argc, char** argv) |
|
|
|
|
{ |
|
|
|
|
// welcome message
|
|
|
|
|
std::cout<< "****************************************************"<<std::endl; |
|
|
|
|
std::cout<< "* Surface Matching demonstration : demonstrates the use of surface matching" |
|
|
|
|
" using point pair features."<<std::endl; |
|
|
|
|
std::cout<< "* The sample loads a model and a scene, where the model lies in a different" |
|
|
|
|
" pose than the training. It then "<<std::endl; |
|
|
|
|
std::cout<< "****************************************************"<<std::endl; |
|
|
|
|
|
|
|
|
|
cout << "****************************************************" << endl; |
|
|
|
|
cout << "* Surface Matching demonstration : demonstrates the use of surface matching" |
|
|
|
|
" using point pair features." << endl; |
|
|
|
|
cout << "* The sample loads a model and a scene, where the model lies in a different" |
|
|
|
|
" pose than the training.\n* It then trains the model and searches for it in the" |
|
|
|
|
" input scene. The detected poses are further refined by ICP\n* and printed to the " |
|
|
|
|
" standard output." << endl; |
|
|
|
|
cout << "****************************************************" << endl; |
|
|
|
|
|
|
|
|
|
if (argc < 3) |
|
|
|
|
{ |
|
|
|
|
help("Not enough input arguments"); |
|
|
|
|
exit(1); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if (defined __x86_64__ || defined _M_X64) |
|
|
|
|
cout << "Running on 64 bits" << endl; |
|
|
|
|
#else |
|
|
|
|
cout << "Running on 32 bits" << endl; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#ifdef _OPENMP |
|
|
|
|
cout << "Running with OpenMP" << endl; |
|
|
|
|
#else |
|
|
|
|
cout << "Running without OpenMP and without TBB" << endl; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
string modelFileName = (string)argv[1]; |
|
|
|
|
string sceneFileName = (string)argv[2]; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Mat pc = loadPLYSimple(modelFileName.c_str(), 1); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Now train the model
|
|
|
|
|
cout << "Training..." << endl; |
|
|
|
|
int64 tick1 = cv::getTickCount(); |
|
|
|
|
ppf_match_3d::PPF3DDetector detector(0.03, 0.05); |
|
|
|
|
ppf_match_3d::PPF3DDetector detector(0.025, 0.05); |
|
|
|
|
detector.trainModel(pc); |
|
|
|
|
int64 tick2 = cv::getTickCount(); |
|
|
|
|
cout << endl << "Training complete in " |
|
|
|
|
<< (double)(tick2-tick1)/ cv::getTickFrequency() |
|
|
|
|
<< " ms" << endl << "Loading model..." << endl; |
|
|
|
|
|
|
|
|
|
<< " sec" << endl << "Loading model..." << endl; |
|
|
|
|
|
|
|
|
|
// Read the scene
|
|
|
|
|
Mat pcTest = loadPLYSimple(sceneFileName.c_str(), 1); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Match the model to the scene and get the pose
|
|
|
|
|
cout << endl << "Starting matching..." << endl; |
|
|
|
|
vector < Pose3D* > results; |
|
|
|
|
vector<Pose3DPtr> results; |
|
|
|
|
tick1 = cv::getTickCount(); |
|
|
|
|
detector.match(pcTest, results, 1.0/10.0, 0.05); |
|
|
|
|
detector.match(pcTest, results, 1.0/40.0, 0.05); |
|
|
|
|
tick2 = cv::getTickCount(); |
|
|
|
|
cout << endl << "PPF Elapsed Time " << |
|
|
|
|
(tick2-tick1)/cv::getTickFrequency() << " ms" << endl; |
|
|
|
|
|
|
|
|
|
(tick2-tick1)/cv::getTickFrequency() << " sec" << endl; |
|
|
|
|
|
|
|
|
|
// Get only first N results
|
|
|
|
|
int N = 2; |
|
|
|
|
vector<Pose3D*>::const_iterator first = results.begin(); |
|
|
|
|
vector<Pose3D*>::const_iterator last = results.begin() + N; |
|
|
|
|
vector<Pose3D*> resultsSub(first, last); |
|
|
|
|
|
|
|
|
|
vector<Pose3DPtr> resultsSub(results.begin(),results.begin()+N); |
|
|
|
|
|
|
|
|
|
// Create an instance of ICP
|
|
|
|
|
ICP icp(200, 0.001f, 2.5f, 8); |
|
|
|
|
ICP icp(100, 0.005f, 2.5f, 8); |
|
|
|
|
int64 t1 = cv::getTickCount(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Register for all selected poses
|
|
|
|
|
cout << endl << "Performing ICP on " << N << " poses..." << endl; |
|
|
|
|
icp.registerModelToScene(pc, pcTest, resultsSub); |
|
|
|
|
int64 t2 = cv::getTickCount(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cout << endl << "ICP Elapsed Time " << |
|
|
|
|
(t2-t1)/cv::getTickFrequency() << " sec" << endl; |
|
|
|
|
|
|
|
|
|
(t2-t1)/cv::getTickFrequency() << " sec" << endl; |
|
|
|
|
|
|
|
|
|
cout << "Poses: " << endl; |
|
|
|
|
// debug first five poses
|
|
|
|
|
for (size_t i=0; i<resultsSub.size(); i++) |
|
|
|
|
{ |
|
|
|
|
Pose3D* pose = resultsSub[i]; |
|
|
|
|
Pose3DPtr result = resultsSub[i]; |
|
|
|
|
cout << "Pose Result " << i << endl; |
|
|
|
|
pose->printPose(); |
|
|
|
|
result->printPose(); |
|
|
|
|
if (i==0) |
|
|
|
|
{ |
|
|
|
|
Mat pct = transformPCPose(pc, result->pose); |
|
|
|
|
writePLY(pct, "para6700PCTrans.ply"); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|