bool MainWindow::serverArgs(QStringList& args, QString& app) { app = appPath(appConfig().synergysName(), appConfig().synergys()); if (!QFile::exists(app)) { if (QMessageBox::warning(this, tr("Synergy server not found"), tr("The executable for the synergy server does not exist. Do you want to browse for the synergy server now?"), QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) return false; app = SettingsDialog::browseForSynergys(this, appConfig().synergyProgramDir(), appConfig().synergysName()); if (app.isEmpty()) return false; appConfig().setSynergys(app); } if (appConfig().logToFile()) { appConfig().persistLogDir(); args << "--log" << appConfig().logFilename(); } args << "-c" << configFilename() << "--address" << address(); return true; }
void WINAPI ServiceMain( DWORD argc, LPSTR *argv ) { std::memset( &SPEPService::serviceStatus, 0, sizeof(SPEPService::serviceStatus) ); SPEPService::serviceStatus.dwServiceType = SERVICE_WIN32; SPEPService::serviceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP; SPEPService::updateStatus( SERVICE_START_PENDING ); std::vector<saml2::Handler*> handlers; std::auto_ptr<spep::daemon::StreamLogHandler> logHandler; std::auto_ptr<std::ostream> stream; std::string logFilename; boost::program_options::variables_map configFileVariableMap; bool readConfig = false; // Open the registry to get the filename RegistryKey rKeySoftware( HKEY_LOCAL_MACHINE, REGISTRY_KEY_SOFTWARE, KEY_ENUMERATE_SUB_KEYS ); if( rKeySoftware.valid() ) { RegistryKey rKeyESOEProject( rKeySoftware, REGISTRY_KEY_ESOEPROJECT, KEY_ENUMERATE_SUB_KEYS ); if( rKeyESOEProject.valid() ) { RegistryKey rKeySPEP( rKeyESOEProject, REGISTRY_KEY_SPEP, KEY_READ ); if( rKeySPEP.valid() ) { std::string configFilename( rKeySPEP.queryValueString( "ConfigFile" ) ); logFilename = ( rKeySPEP.queryValueString( "LogFile" ) ); if( logFilename.length() != 0 ) { stream.reset( new std::ofstream( logFilename.c_str() ) ); logHandler.reset( new spep::daemon::StreamLogHandler( *stream, spep::DEBUG ) ); handlers.push_back( logHandler.get() ); } // Read the file std::ifstream configFileInput( configFilename.c_str() ); if( configFileInput.good() ) { parseConfig( configFileVariableMap, configFileInput, handlers ); readConfig = true; } else { directLog( handlers, "The config file specified in the registry key doesn't exist." ); return; } } else { directLog( handlers, "Couldn't open HKEY_LOCAL_MACHINE\Software\ESOE Project\SPEP" ); return; } }
int main(int argc, char *argv[]) { if (argc < 3) return EXIT_FAILURE; std::string port(argv[1]); std::string configFilename(argv[2]); std::cout << "Welcome to Megaman 3 Server Edition" << std::endl; // Seed rand srand(time(NULL)); Logger::getInstance().log(1, "Server starting..."); Server server = Server(port, configFilename); server.run(); Logger::getInstance().log(1, "Server quitting..."); return EXIT_SUCCESS; }
AppConfig* AppConfig::Instance() { static AppConfig* instance = 0; if (!instance) { std::string configFilename(FileUtils::Join( Host::GetInstance()->GetApplication()->getPath().c_str(), CONFIG_FILENAME, 0)); GetLogger()->Debug("Loading config file: %s", configFilename.c_str()); if (!FileUtils::IsFile(configFilename)) { GetLogger()->Critical("Cannot load config file: %s", configFilename.c_str()); throw ValueException::FromFormat("Cannot load config file: %s", configFilename.c_str()); } instance = new AppConfig(configFilename); } return instance; }
//-------------------------------------------------------------------------------------------------- int main( int argc, char** argv ) { // Read in a configuration file if ( argc < 2 ) { fprintf( stderr, "No configuration file provided\n" ); showUsage( argv[ 0 ] ); return -1; } initialiseTestPositions(); //std::string configFilename = Utilities::getDataDir() + std::string( "/" ) + std::string( argv[ 1 ] ); std::string configFilename( argv[ 1 ] ); cv::FileStorage configFileStorage; configFileStorage.open( configFilename, cv::FileStorage::READ ); if ( !configFileStorage.isOpened() ) { fprintf( stderr, "Unable to open %s\n", configFilename.c_str() ); return -1; } cv::Mat kinectDepthCameraPos; cv::Mat kinectDepthCameraRotXYZDeg; double kinectDepthFocalLengthPixel; int32_t kinectDepthImageWidth; int32_t kinectDepthImageHeight; cv::Mat kinectRGBCameraPos; cv::Mat kinectRGBCameraRotXYZDeg; double kinectRGBFocalLengthPixel; int32_t kinectRGBImageWidth; int32_t kinectRGBImageHeight; cv::Mat highResCameraPos; cv::Mat highResCameraRotXYZDeg; double highResFocalLengthPixel; int32_t highResImageWidth; int32_t highResImageHeight; // The camera poses are defined in a coordinate system with the Kinect depth camera at the // origin looking down the +ve z-axis, so z values increase into the image. The x and y axes // of the depth camera are aligned with its image plane, so +ve x points to its right, and // +ve y points down through the base of the camera. To position the camera in world space, it // is rotated 180 degrees about the z axis, the chessboard positions are defined in world space. configFileStorage[ "kinectDepthFocalLengthPixel" ] >> kinectDepthFocalLengthPixel; configFileStorage[ "kinectDepthImageWidth" ] >> kinectDepthImageWidth; configFileStorage[ "kinectDepthImageHeight" ] >> kinectDepthImageHeight; configFileStorage[ "kinectRGBCameraPos" ] >> kinectRGBCameraPos; configFileStorage[ "kinectRGBCameraRotXYZDeg" ] >> kinectRGBCameraRotXYZDeg; configFileStorage[ "kinectRGBFocalLengthPixel" ] >> kinectRGBFocalLengthPixel; configFileStorage[ "kinectRGBImageWidth" ] >> kinectRGBImageWidth; configFileStorage[ "kinectRGBImageHeight" ] >> kinectRGBImageHeight; configFileStorage[ "highResCameraPos" ] >> highResCameraPos; configFileStorage[ "highResCameraRotXYZDeg" ] >> highResCameraRotXYZDeg; configFileStorage[ "highResFocalLengthPixel" ] >> highResFocalLengthPixel; configFileStorage[ "highResImageWidth" ] >> highResImageWidth; configFileStorage[ "highResImageHeight" ] >> highResImageHeight; // Construct camera matrices cv::Mat zeroVec = cv::Mat::zeros( 3, 1, CV_64FC1 ); cv::Mat kinectDepthCalibMtx = createCameraCalibrationMatrix( kinectDepthFocalLengthPixel, kinectDepthImageWidth, kinectDepthImageHeight ); cv::Mat kinectDepthWorldMtx = createCameraWorldMatrix( zeroVec, zeroVec ); cv::Mat kinectRGBCalibMtx = createCameraCalibrationMatrix( kinectRGBFocalLengthPixel, kinectRGBImageWidth, kinectRGBImageHeight ); cv::Mat kinectRGBWorldMtx = createCameraWorldMatrix( kinectRGBCameraPos, kinectRGBCameraRotXYZDeg ); cv::Mat highResCalibMtx = createCameraCalibrationMatrix( highResFocalLengthPixel, highResImageWidth, highResImageHeight ); cv::Mat highResWorldMtx = createCameraWorldMatrix( highResCameraPos, highResCameraRotXYZDeg ); // First generate calibration images for the high resolution camera for ( uint32_t testPosIdx = 0; testPosIdx < gHighResCalibrationPositions.size(); testPosIdx++ ) { cv::Mat chessboardPoseMtx = createChessboardPoseMatrix( gHighResCalibrationPositions[ testPosIdx ] ); // Generate an image from the high resolution camera cv::Mat highResRgbImage = generateRGBImageOfChessboard( highResWorldMtx, highResCalibMtx, highResImageWidth, highResImageHeight, chessboardPoseMtx ); cv::imwrite( createOutputFilename( "chessboard_highres", testPosIdx + 1, ".png" ), highResRgbImage ); } // Now generate images to identify the relative poses of the cameras for ( uint32_t testPosIdx = 0; testPosIdx < gRelativeCalibrationPositions.size(); testPosIdx++ ) { cv::Mat chessboardPoseMtx = createChessboardPoseMatrix( gRelativeCalibrationPositions[ testPosIdx ] ); // Generate a point cloud from the Kinect PointCloud::Ptr pCloud = generatePointCloudOfChessboard( kinectDepthWorldMtx, kinectDepthCalibMtx, kinectDepthImageWidth, kinectDepthImageHeight, chessboardPoseMtx ); pCloud->saveToSpcFile( createOutputFilename( "relative_chessboard", testPosIdx + 1, ".spc" ), true ); // Generate an image from the Kinect RGB camera cv::Mat rgbImage = generateRGBImageOfChessboard( kinectRGBWorldMtx, kinectRGBCalibMtx, kinectRGBImageWidth, kinectRGBImageHeight, chessboardPoseMtx ); cv::imwrite( createOutputFilename( "relative_chessboard", testPosIdx + 1, ".png" ), rgbImage ); // Generate an image from the high resolution camera cv::Mat highResRgbImage = generateRGBImageOfChessboard( highResWorldMtx, highResCalibMtx, highResImageWidth, highResImageHeight, chessboardPoseMtx ); cv::imwrite( createOutputFilename( "relative_chessboard_highres", testPosIdx + 1, ".png" ), highResRgbImage ); } // Generate ideal calibration files // First the kinect calibration cv::FileStorage dataFile( "kinect_calib.yaml", cv::FileStorage::WRITE ); dataFile << "DepthCameraCalibrationMtx" << kinectDepthCalibMtx; dataFile << "ColorCameraCalibrationMtx" << kinectRGBCalibMtx; cv::Mat kinectRGBInKinectDepthSpace = (kinectDepthWorldMtx.inv())*kinectRGBWorldMtx; dataFile << "DepthToColorCameraRotation" << cv::Mat( kinectRGBInKinectDepthSpace, cv::Rect( 0, 0, 3, 3 ) ); dataFile << "DepthToColorCameraTranslation" << cv::Mat( kinectRGBInKinectDepthSpace, cv::Rect( 3, 0, 1, 3 ) ); dataFile.release(); // Now the high resolution camera calibration dataFile = cv::FileStorage( "high_res_calib.yaml", cv::FileStorage::WRITE ); dataFile << "cameraMatrix" << highResCalibMtx; dataFile.release(); // Finally, the position of the high resolution colour camera in Kinect colour camera space dataFile = cv::FileStorage( "colour_stereo_calib.yaml", cv::FileStorage::WRITE ); cv::Mat highResInKinectRGBSpace = (kinectRGBWorldMtx.inv())*highResWorldMtx; dataFile << "R" << cv::Mat( highResInKinectRGBSpace, cv::Rect( 0, 0, 3, 3 ) ); dataFile << "T" << cv::Mat( highResInKinectRGBSpace, cv::Rect( 3, 0, 1, 3 ) ); dataFile.release(); //std::cout << kinectRGBWorldMtx << std::endl; //std::cout << highResWorldMtx << std::endl; //std::cout << highResInKinectRGBSpace << std::endl; return 0; }
int main( int argc, char *argv[] ) { // try { time_t programStartTime(time(NULL) ); boost::filesystem::path workingDir( boost::filesystem::current_path() ); // ========== PROGRAM PARAMETERS ========== std::string progName( "buildrandctree" ); std::string configFilename( "/home/raid2/moreno/Code/hClustering/config/"+progName+".cfg" ); // program parameters std::string roiFilename, inputFolder, outputFolder; float memory( 0.5 ), maxNbDist( 1 ); unsigned int nbLevel( 26 ), threads( 0 ); bool keepDiscarded( false ), niftiMode( true ), debug( false ); TC_GROWTYPE growType( TC_GROWOFF ); size_t baseSize( 0 ); // Declare a group of options that will be allowed only on command line boost::program_options::options_description genericOptions( "Generic options" ); genericOptions.add_options() ( "version", "Program version" ) ( "help,h", "Produce extended program help message" ) ( "roi,r", boost::program_options::value< std::string >(&roiFilename), "file with the seed voxels coordinates." ) ( "inputf,I", boost::program_options::value< std::string >(&inputFolder), "input data folder (seed tractograms)." ) ( "outputf,O", boost::program_options::value< std::string >(&outputFolder), "output folder" ) ( "maxnbdist,d", boost::program_options::value< float >(&maxNbDist)->implicit_value(1), "[opt] maximum dissimilarity a seed voxel tract must have to its most similar neighbor not be discarded. (0,1]." ) ( "cnbhood,c", boost::program_options::value< unsigned int >(&nbLevel)->implicit_value(26), "[opt] centroid method neighborhood level. Valid values: 6, 18, 26(default), 32, 96, 124." ) ( "basesize,S", boost::program_options::value< size_t >(&baseSize), "[opt] grow homogeneous base nodes (meta-leaves) of size S. (>=2)." ) ( "basenum,N", boost::program_options::value< size_t >(&baseSize), "[opt] grow N homogeneous base nodes (meta-leaves). (>=10)." ) ; // Declare a group of options that will be allowed both on command line and in config file boost::program_options::options_description configOptions( "Configuration" ); configOptions.add_options() ( "verbose,v", "[opt] verbose output." ) ( "vista", "[opt] use vista file format (default is nifti)." ) ( "cache-mem,m", boost::program_options::value< float >(&memory)->implicit_value(0.5), "[opt] maximum of memory (in GBytes) to use for tractogram cache memory. Default: 0.5." ) ( "keep-disc,k", "[opt] keep discarded voxels data in a section of the tree file." ) ( "debugout", "[opt] write additional detailed outputs meant for debug." ) ( "pthreads,p", boost::program_options::value< unsigned int >(&threads), "[opt] number of processing cores to run the program in. Default: all available." ) ; // Hidden options, will be allowed both on command line and in config file, but will not be shown to the user. boost::program_options::options_description hiddenOptions( "Hidden options" ); //hiddenOptions.add_options() ; boost::program_options::options_description cmdlineOptions; cmdlineOptions.add(genericOptions).add(configOptions).add(hiddenOptions); boost::program_options::options_description configFileOptions; configFileOptions.add(configOptions).add(hiddenOptions); boost::program_options::options_description visibleOptions( "Allowed options" ); visibleOptions.add(genericOptions).add(configOptions); boost::program_options::positional_options_description posOpt; //this arguments do not need to specify the option descriptor when typed in //posOpt.add( "roi", -1); boost::program_options::variables_map variableMap; store(boost::program_options::command_line_parser(argc, argv).options(cmdlineOptions).positional(posOpt).run(), variableMap); std::ifstream ifs(configFilename.c_str() ); store(parse_config_file(ifs, configFileOptions), variableMap); notify( variableMap); if ( variableMap.count( "help" ) ) { std::cout << "---------------------------------------------------------------------------" << std::endl; std::cout << std::endl; std::cout << " Project: hClustering" << std::endl; std::cout << std::endl; std::cout << " Whole-Brain Connectivity-Based Hierarchical Parcellation Project" << std::endl; std::cout << " David Moreno-Dominguez" << std::endl; std::cout << " [email protected]" << std::endl; std::cout << " [email protected]" << std::endl; std::cout << " www.cbs.mpg.de/~moreno" << std::endl; std::cout << std::endl; std::cout << " For more reference on the underlying algorithm and research they have been used for refer to:" << std::endl; std::cout << " - Moreno-Dominguez, D., Anwander, A., & Knösche, T. R. (2014)." << std::endl; std::cout << " A hierarchical method for whole-brain connectivity-based parcellation." << std::endl; std::cout << " Human Brain Mapping, 35(10), 5000-5025. doi: http://dx.doi.org/10.1002/hbm.22528" << std::endl; std::cout << " - Moreno-Dominguez, D. (2014)." << std::endl; std::cout << " Whole-brain cortical parcellation: A hierarchical method based on dMRI tractography." << std::endl; std::cout << " PhD Thesis, Max Planck Institute for Human Cognitive and Brain Sciences, Leipzig." << std::endl; std::cout << " ISBN 978-3-941504-45-5" << std::endl; std::cout << std::endl; std::cout << " hClustering is free software: you can redistribute it and/or modify" << std::endl; std::cout << " it under the terms of the GNU Lesser General Public License as published by" << std::endl; std::cout << " the Free Software Foundation, either version 3 of the License, or" << std::endl; std::cout << " (at your option) any later version." << std::endl; std::cout << " http://creativecommons.org/licenses/by-nc/3.0" << std::endl; std::cout << std::endl; std::cout << " hClustering is distributed in the hope that it will be useful," << std::endl; std::cout << " but WITHOUT ANY WARRANTY; without even the implied warranty of" << std::endl; std::cout << " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the" << std::endl; std::cout << " GNU Lesser General Public License for more details." << std::endl; std::cout << std::endl; std::cout << "---------------------------------------------------------------------------" << std::endl << std::endl; std::cout << "buildrandctree" << std::endl << std::endl; std::cout << "Build a centroid hierarchical tree from a set of artificially pre-generated set of tractograms yoielding a uniformly random similarity matrix and a seed neighborhood information voxel list." << std::endl << std::endl; std::cout << "* Arguments:" << std::endl << std::endl; std::cout << " --version: Program version." << std::endl << std::endl; std::cout << " -h --help: Produce extended program help message." << std::endl << std::endl; std::cout << " -r --roi: A text file with the seed voxel coordinates and the corresponding tractogram index (if tractogram naming is based on index rather than coordinates)." << std::endl << std::endl; std::cout << " -I --inputf: input data folder (containing the compact tractograms)." << std::endl << std::endl; std::cout << " -O --outputf: Output folder where tree files will be written." << std::endl << std::endl; std::cout << "[-d --maxnbdist]: Maximum dissimilarity a seed voxel tract must have to its most similar neighbor not be discarded." << std::endl; std::cout << " Valid values: (0,1] Use a value of 1 (default) if no discarding is desired." << std::endl << std::endl; std::cout << "[-c --cnbhood]: Use centroid method with C neighborhood level. Valid values: 6, 18, 24(default), 32, 96, 124." << std::endl << std::endl; std::cout << "[-S --basesize]: Merge homogeneous base nodes of size S. (mutually exclusive with -N option). Default: 0 (no homogeneous merging)." << std::endl << std::endl; std::cout << "[-N --basenum]: Grow N homogeneous base nodes. (mutually exclusive with -S option). Default: 0 (no homogeneous merging)." << std::endl << std::endl; std::cout << "[-v --verbose]: Verbose output (recommended)." << std::endl << std::endl; std::cout << "[--vista]: Read/write vista (.v) files [default is nifti (.nii) and compact (.cmpct) files]." << std::endl << std::endl; std::cout << "[-m --cache-mem]: Maximum amount of RAM memory (in GBytes) to use for temporal tractogram cache storing. Valid values [0.1,50]. Default: 0.5." << std::endl << std::endl; std::cout << "[-k --keep-disc]: Keep discarded voxel information in a specialiced section of the tree." << std::endl << std::endl; std::cout << "[--debugout]: Write additional detailed outputs meant to be used for debugging." << std::endl << std::endl; std::cout << "[-p --pthreads]: Number of processing threads to run the program in parallel. Default: use all available processors." << std::endl << std::endl; std::cout << std::endl; std::cout << "* Usage example:" << std::endl << std::endl; std::cout << " buildrandctree -r roi_lh.txt -I tractograms/ -O results/ -c 26 -N 1000 -k -m 2 -v " << std::endl << std::endl; std::cout << std::endl; std::cout << "* Outputs (in output folder defined at option -O):" << std::endl << std::endl; std::cout << " - 'cX_bin_nmt.txt' - (where X is the neighborhood level defined at option -c) non-monotonic binary-branching hierarchical tree without tree processing (if desired use processtree command)." << std::endl; std::cout << " - 'baselist_nmt.txt' - meta-leaves (base nodes defined by the us of option -N or -S) list with IDs corresponding to the non-monotonic tree file." << std::endl; std::cout << " - 'success.txt' - An empty file created when the program has sucessfully exited after completion (to help for automatic re-running scripting after failure)." << std::endl; std::cout << " - 'buildrandtree_log.txt' - A text log file containing the parameter details and in-run and completion information of the program." << std::endl; std::cout << std::endl; std::cout << " [extra outputs when using --debugout option)" << std::endl << std::endl; std::cout << " - 'cX_bin_nmt_debug.txt' - version of the counterpart file without '_debug' suffix with redundant information for debugging purposes." << std::endl; std::cout << std::endl; exit(0); } if ( variableMap.count( "verbose" ) ) { std::cout << "verbose output" << std::endl; verbose=true; } if ( variableMap.count( "pthreads" ) ) { if ( threads == 1 ) { std::cout << "Using a single processor" << std::endl; } else if( threads == 0 || threads >= omp_get_num_procs() ) { threads = omp_get_num_procs(); std::cout << "Using all available processors ( " << threads << " )." << std::endl; } else { std::cout << "Using a maximum of " << threads << " processors " << std::endl; } omp_set_num_threads( threads ); } else { threads = omp_get_num_procs(); omp_set_num_threads( threads ); std::cout << "Using all available processors ( " << threads << " )." << std::endl; } if ( variableMap.count( "vista" ) ) { if( verbose ) { std::cout << "Using vista format" << std::endl; } fileManagerFactory fmf; fmf.setVista(); niftiMode = false; } else { if( verbose ) { std::cout << "Using nifti format" << std::endl; } fileManagerFactory fmf; fmf.setNifti(); niftiMode = true; } if ( variableMap.count( "debugout" ) ) { if( verbose ) { std::cout << "Debug output files activated" << std::endl; } debug = true; } if ( variableMap.count( "version" ) ) { std::cout << progName << ", version 2.0" << std::endl; exit(0); } if ( variableMap.count( "roi" ) ) { if( !boost::filesystem::is_regular_file( boost::filesystem::path( roiFilename ) ) ) { std::cerr << "ERROR: roi file \"" <<roiFilename<< "\" is not a regular file" << std::endl; std::cerr << visibleOptions << std::endl; exit(-1); } else if( verbose ) { std::cout << "Seed voxels roi file: " << roiFilename << std::endl; } } else { std::cerr << "ERROR: no seed voxels roi file stated" << std::endl; std::cerr << visibleOptions << std::endl; exit(-1); } if( verbose ) { std::cout << "Maximum distance to most similar neighbor: " << maxNbDist << std::endl; } if ( maxNbDist <= 0 || maxNbDist > 1 ) { std::cerr << "ERROR: distance value used is out of bounds please use a value within (0,1]" << std::endl; std::cerr << visibleOptions << std::endl; exit(-1); } else if ( maxNbDist == 1 && verbose ) { std::cout << "No neighbor distance restrictions will be applied" << std::endl; } else if( verbose ) { std::cout << "Seed voxels with no neighbors with tract dissimilarity lower than " << maxNbDist << " will be discarded as outliers" << std::endl; } if( verbose ) { std::cout << "Centroid neighborhood level: " << nbLevel << std::endl; } if ( ( nbLevel != 6 ) && ( nbLevel != 18 ) && ( nbLevel != 26 ) && ( nbLevel != 32 ) && ( nbLevel != 92 ) && ( nbLevel != 124 ) ) { std::cerr << "ERROR: invalid nbhood level, only (6,18,26,32,92,124) are accepted" << std::endl; std::cerr << visibleOptions << std::endl; exit(-1); } if ( ( variableMap.count( "basesize" ) && variableMap.count( "basenum" ) ) ) { std::cerr << "ERROR: options --basesize (-S) and --basenum (-N) are mutually exclusive" << std::endl; std::cerr << visibleOptions << std::endl; exit(-1); } if ( variableMap.count( "basesize" ) ) { if( baseSize <= 1 ) { std::cerr << "ERROR: base node (meta-leaf) size must be greater than 1" << std::endl; std::cerr << visibleOptions << std::endl; exit(-1); } else { if( verbose ) { std::cout << "Initial merging stage up to homogeneous base nodes of size: " << baseSize << std::endl; } growType = TC_GROWSIZE; } } if ( variableMap.count( "basenum" ) ) { if( baseSize < 10 ) { std::cerr << "ERROR: base node (meta-leaf) number must be equal or greater than 10" << std::endl; std::cerr << visibleOptions << std::endl; exit(-1); } else { if( verbose ) { std::cout << "Initial merging stage up to " << baseSize << " homogeneous base nodes (meta-leaves)" << std::endl; } growType = TC_GROWNUM; } } if( growType == TC_GROWOFF && verbose ) { std::cout << "No homogeneous merging stage" << std::endl; } if ( variableMap.count( "keep-disc" ) ) { if( verbose ) { std::cout << "Discarded voxel coordinates will be saved in an special section fo the tree file" << std::endl; } keepDiscarded = true; } else { if( verbose ) { std::cout << "Discarded voxel coordinates will not be saved" << std::endl; } keepDiscarded = false; } if ( variableMap.count( "inputf" ) ) { if( !boost::filesystem::is_directory( boost::filesystem::path( inputFolder ) ) ) { std::cerr << "ERROR: input seed tractogram folder \"" <<inputFolder<< "\" is not a directory" << std::endl; std::cerr << visibleOptions << std::endl; exit(-1); } else if( verbose ) { std::cout << "Input seed tractogram folder: " << inputFolder << std::endl; } } else { std::cerr << "ERROR: no input seed tractogram stated" << std::endl; std::cerr << visibleOptions << std::endl; exit(-1); } if ( variableMap.count( "outputf" ) ) { if( !boost::filesystem::is_directory( boost::filesystem::path( outputFolder ) ) ) { std::cerr << "ERROR: output folder \"" <<outputFolder<< "\" is not a directory" << std::endl; std::cerr << visibleOptions << std::endl; exit(-1); } else if( verbose ) { std::cout << "Output folder: " << outputFolder << std::endl; } } else { std::cerr << "ERROR: no output folder stated" << std::endl; std::cerr << visibleOptions << std::endl; exit(-1); } if ( memory < 0.1 || memory > 50) { std::cerr << "ERROR: cache size must be a positive float between 0.1 and 50 (GB)" << std::endl; std::cerr << visibleOptions << std::endl; exit(-1); } else if( verbose ) { std::cout << "Tractogram cache memory: " << memory << " GBytes" << std::endl; } std::string logFilename(outputFolder+"/"+progName+"_log.txt" ); std::ofstream logFile(logFilename.c_str() ); if(!logFile) { std::cerr << "ERROR: unable to open log file: \"" <<logFilename<< "\"" << std::endl; exit(-1); } logFile << "Start Time:\t" << ctime(&programStartTime) << std::endl; logFile << "Working directory:\t" << workingDir.string() << std::endl; logFile << "Verbose:\t" << verbose << std::endl; logFile << "Processors used:\t" << threads << std::endl; if( niftiMode ) { logFile << "Using nifti file format" << std::endl; } else { logFile << "Using vista file format" << std::endl; } logFile << "Vista mode flag:\t" << verbose << std::endl; logFile << "Roi file:\t" << roiFilename << std::endl; logFile << "Max nb distance:\t" << maxNbDist << std::endl; logFile << "Nbhood restriction level:\t" <<nbLevel<< std::endl; switch(growType) { case TC_GROWOFF: logFile << "Region growing: None" << std::endl; break; case TC_GROWSIZE: logFile << "Region growing: Size: " << baseSize << std::endl; break; case TC_GROWNUM: logFile << "Region growing: Number: " << baseSize << std::endl; break; } logFile << "Input seed tract folder:\t" << inputFolder << std::endl; logFile << "Output folder:\t" << outputFolder << std::endl; logFile << "Memory cache size:\t" << memory << " GB" << std::endl; logFile << "Debug outputr:\t" << debug << std::endl; logFile << "-------------" << std::endl; ///////////////////////////////////////////////////////////////// randCnbTreeBuilder builder( roiFilename, verbose ); logFile << "Roi size:\t" << builder.roiSize() << std::endl; builder.log( &logFile ); builder.setInputFolder( inputFolder ); builder.setOutputFolder( outputFolder ); builder.setDebugOutput( debug ); builder.buildRandCentroid( nbLevel, memory, growType, baseSize, keepDiscarded ); ///////////////////////////////////////////////////////////////// // save and print total time time_t programEndTime(time(NULL) ); int totalTime( difftime(programEndTime,programStartTime) ); std::cout << "Program Finished, total time: " << totalTime/3600 << "h " << (totalTime%3600)/60 << "' " << ((totalTime%3600)%60) << "\" " << std::endl; logFile << "-------------" << std::endl; logFile << "Finish Time:\t" << ctime(&programEndTime) << std::endl; logFile << "Elapsed time : " << totalTime/3600 << "h " << (totalTime%3600)/60 << "' " << ((totalTime%3600)%60) << "\"" << std::endl; // create file that indicates process was finished successfully std::string successFilename(outputFolder+"/success.txt" ); std::ofstream successFile(successFilename.c_str() ); if(!successFile) { std::cerr << "ERROR: unable to create success file: \"" <<successFile<< "\"" << std::endl; exit(-1); } successFile << "success"; // } // catch(std::exception& e) // { // std::cout << e.what() << std::endl; // return 1; // } return 0; }
int main( int argc, char *argv[] ) { // try { time_t programStartTime(time(NULL)); boost::filesystem::path workingDir( boost::filesystem::current_path()); // ========== PROGRAM PARAMETERS ========== std::string progName("partitiontree"); std::string configFilename("../../config/"+progName+".cfg"); unsigned int threads(0), levelDepth(3), filterRadius(0); bool verbose(false), niftiMode( true ); // program parameters std::string treeFilename, outputFolder; // Declare a group of options that will be allowed only on command line boost::program_options::options_description genericOptions("Generic options"); genericOptions.add_options() ( "version", "Program version" ) ( "help,h", "Produce extended program help message" ) ( "tree,t", boost::program_options::value< std::string >(&treeFilename), "file with the tree to compute partitions from") ( "outputf,O", boost::program_options::value< std::string >(&outputFolder), "output folder where partition files will be written") ( "search-depth,d", boost::program_options::value< unsigned int >(&levelDepth)->implicit_value(3), "[opt] optimal partition search depth (default = 3)") ( "filter-radius,r", boost::program_options::value< unsigned int >(&filterRadius)->implicit_value(0), "[opt] output partition filter kernel radius (default = 0 | no filtering)") ( "hoz", "[opt] obtain horizontal cut partitions (instead of Spread-Separation ones)") ( "maxgran,m", "[opt] obtain only the maximum granularity partition") ; // Declare a group of options that will be allowed both on command line and in config file boost::program_options::options_description configOptions("Configuration"); configOptions.add_options() ( "verbose,v", "[opt] verbose output." ) ( "vista", "[opt] use vista file format (default is nifti)." ) ( "pthreads,p", boost::program_options::value< unsigned int >(&threads), "[opt] number of processing threads to run the program in parallel, default: all available") ; // Hidden options, will be allowed both on command line and in config file, but will not be shown to the user. boost::program_options::options_description hiddenOptions("Hidden options"); //hiddenOptions.add_options() ; boost::program_options::options_description cmdlineOptions; cmdlineOptions.add(genericOptions).add(configOptions).add(hiddenOptions); boost::program_options::options_description configFileOptions; configFileOptions.add(configOptions).add(hiddenOptions); boost::program_options::options_description visibleOptions("Allowed options"); visibleOptions.add(genericOptions).add(configOptions); boost::program_options::positional_options_description posOpt; //this arguments do not need to specify the option descriptor when typed in //posOpt.add("roi-file", -1); boost::program_options::variables_map variableMap; store(boost::program_options::command_line_parser(argc, argv).options(cmdlineOptions).positional(posOpt).run(), variableMap); std::ifstream ifs(configFilename.c_str()); store(parse_config_file(ifs, configFileOptions), variableMap); notify(variableMap); if (variableMap.count("help")) { std::cout << "---------------------------------------------------------------------------" << std::endl; std::cout << std::endl; std::cout << " Project: hClustering" << std::endl; std::cout << std::endl; std::cout << " Whole-Brain Connectivity-Based Hierarchical Parcellation Project" << std::endl; std::cout << " David Moreno-Dominguez" << std::endl; std::cout << " [email protected]" << std::endl; std::cout << " [email protected]" << std::endl; std::cout << " www.cbs.mpg.de/~moreno" << std::endl; std::cout << std::endl; std::cout << " For more reference on the underlying algorithm and research they have been used for refer to:" << std::endl; std::cout << " - Moreno-Dominguez, D., Anwander, A., & Knösche, T. R. (2014)." << std::endl; std::cout << " A hierarchical method for whole-brain connectivity-based parcellation." << std::endl; std::cout << " Human Brain Mapping, 35(10), 5000-5025. doi: http://dx.doi.org/10.1002/hbm.22528" << std::endl; std::cout << " - Moreno-Dominguez, D. (2014)." << std::endl; std::cout << " Whole-brain cortical parcellation: A hierarchical method based on dMRI tractography." << std::endl; std::cout << " PhD Thesis, Max Planck Institute for Human Cognitive and Brain Sciences, Leipzig." << std::endl; std::cout << " ISBN 978-3-941504-45-5" << std::endl; std::cout << std::endl; std::cout << " hClustering is free software: you can redistribute it and/or modify" << std::endl; std::cout << " it under the terms of the GNU Lesser General Public License as published by" << std::endl; std::cout << " the Free Software Foundation, either version 3 of the License, or" << std::endl; std::cout << " (at your option) any later version." << std::endl; std::cout << " http://creativecommons.org/licenses/by-nc/3.0" << std::endl; std::cout << std::endl; std::cout << " hClustering is distributed in the hope that it will be useful," << std::endl; std::cout << " but WITHOUT ANY WARRANTY; without even the implied warranty of" << std::endl; std::cout << " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the" << std::endl; std::cout << " GNU Lesser General Public License for more details." << std::endl; std::cout << std::endl; std::cout << "---------------------------------------------------------------------------" << std::endl << std::endl; std::cout << "partitiontree" << std::endl << std::endl; std::cout << "Obtain tree partitions at all granularity levels using the Spread-Separation method (finding the the partition with highest SS index at each granularity)." << std::endl; std::cout << " Optimal SS value for each partition is searched within a defined search-depth hierarchical levels. Final partitions can be filtered with a defined kernel size." << std::endl; std::cout << " to keep local SS maxima within that kernel. For SS index refer to (Moreno-Dominguez, 2014)" << std::endl; std::cout << " For an interactive 3D partition management with more options please use the Hierarchcial Clustering module developed in OpenWalnut (www.openwalnut.org)." << std::endl << std::endl; std::cout << "* Arguments:" << std::endl << std::endl; std::cout << " --version: Program version." << std::endl << std::endl; std::cout << " -h --help: produce extended program help message." << std::endl << std::endl; std::cout << " -t --tree: File with the hierarchical tree to extract partitions from." << std::endl << std::endl; std::cout << " -O --outputf: Output folder where partition files will be written." << std::endl << std::endl; std::cout << "[-d --search-depth]: Search optimal partition for each granularity within d hierarchical levels." << std::endl; std::cout << " A higher value will produce more optimized partition but will increase computing time." << std::endl; std::cout << " Default: 3. Recommendened values: 3 for good quality and fast computation, 4 for enhanced quality." << std::endl << std::endl; std::cout << "[-r --filter-radius]: Filter output partitions to keep only local SS (partition quality) maxima" << std::endl; std::cout << " within a r-sized kernel across the granularity dimension." << std::endl << std::endl; std::cout << "[-h --hoz]: Write horizontal cut partitions instead of SS ones (optimal partition search is still based on SS index)." << std::endl << std::endl; std::cout << "[-m --maxgran]: Compute and write only the maximum granularity (meta-leaves) partition." << std::endl << std::endl; std::cout << "[-v --verbose]: verbose output (recommended)." << std::endl << std::endl; std::cout << "[--vista]: write output tree in vista coordinates (default is nifti)." << std::endl << std::endl; std::cout << "[-p --pthreads]: number of processing threads to run the program in parallel. Default: use all available processors." << std::endl << std::endl; std::cout << std::endl; std::cout << "* Usage example:" << std::endl << std::endl; std::cout << " partitiontree -t tree_lh.txt -O results/ -d 3 -r 50 -v" << std::endl << std::endl; std::cout << std::endl; std::cout << "* Outputs (in output folder defined at option -O):" << std::endl << std::endl; std::cout << " (default outputs)" << std::endl; std::cout << " - 'allSSparts_dX.txt' - (where X is the search depth level defined at parameter -d) Contains a summary of the partition information (cut value and size) for all granularities." << std::endl; std::cout << " - 'TREE_SSparts_dX.txt' - (where TREE is the filename of the input tree defined at parameter -t) contains a copy of the original tree file with the partitions at all granularities included in the relevant fields." << std::endl; std::cout << " - 'partitiontree_log.txt' - A text log file containing the parameter details and in-run and completion information of the program." << std::endl; std::cout << std::endl; std::cout << " (additional if using option -r)" << std::endl; std::cout << " - 'filtSSparts_dX_rY.txt' - (where Y is the filter radius defined at parameter -r) Contains a summary of the resulting filtered partitions." << std::endl; std::cout << " - 'TREE_SSparts_dX_rY.txt' - contains a copy of the original tree file with the resulting filtered partitions included in the relevant fields." << std::endl; std::cout << std::endl; std::cout << " (when using --hoz option, the prefix 'SS' will be replaced by 'Hoz'')" << std::endl; std::cout << std::endl; std::cout << " (alternative outputs when using option --maxgran)" << std::endl; std::cout << " - 'fmaxgranPart.txt' - Contains the size information of the resulting maximal granularity partition for that tree." << std::endl; std::cout << " - 'TREE_maxgranPart.txt' - contains a copy of the original tree file with the resulting max granularity partition included in the relevant fields." << std::endl; std::cout << std::endl; exit(0); } if (variableMap.count("version")) { std::cout << progName <<", version 2.0"<<std::endl; exit(0); } if (variableMap.count("verbose")) { std::cout << "verbose output"<<std::endl; verbose=true; } if (variableMap.count("pthreads")) { if (threads==1) { std::cout <<"Using a single processor"<< std::endl; } else if(threads==0 || threads>=omp_get_num_procs()) { threads = omp_get_num_procs(); std::cout <<"Using all available processors ("<< threads <<")." << std::endl; } else { std::cout <<"Using a maximum of "<< threads <<" processors "<< std::endl; } omp_set_num_threads( threads ); } else { threads = omp_get_num_procs(); omp_set_num_threads( threads ); std::cout <<"Using all available processors ("<< threads <<")." << std::endl; } if ( variableMap.count( "vista" ) ) { if( verbose ) { std::cout << "Using vista format" << std::endl; } fileManagerFactory fmf; fmf.setVista(); niftiMode = false; } else { if( verbose ) { std::cout << "Using nifti format" << std::endl; } fileManagerFactory fmf; fmf.setNifti(); niftiMode = true; } if (variableMap.count("tree")) { if(!boost::filesystem::is_regular_file(boost::filesystem::path(treeFilename))) { std::cerr << "ERROR: tree file \""<<treeFilename<<"\" is not a regular file"<<std::endl; std::cerr << visibleOptions << std::endl; exit(-1); } std::cout << "Roi voxels file: "<< treeFilename << std::endl; } else { std::cerr << "ERROR: no tree file stated"<<std::endl; std::cerr << visibleOptions << std::endl; exit(-1); } if (variableMap.count("outputf")) { if(!boost::filesystem::is_directory(boost::filesystem::path(outputFolder))) { std::cerr << "ERROR: output folder \""<<outputFolder<<"\" is not a directory"<<std::endl; std::cerr << visibleOptions << std::endl; exit(-1); } std::cout << "Output folder: "<< outputFolder << std::endl; } else { std::cerr << "ERROR: no output folder stated"<<std::endl; std::cerr << visibleOptions << std::endl; exit(-1); } if (variableMap.count("maxgran")) { std::cout<<"Obtaining only max. granularity partition..."<<std::endl; WHtree tree(treeFilename); std::cout<<tree.getReport( false )<<std::endl; if( tree.testRootBaseNodes() ) { std::vector<size_t > maxpart( tree.getRootBaseNodes() ); std::vector<std::vector<size_t > > partitionVector( 1, maxpart); std::vector<float > partitionValues(1,0); std::cout<<"maxgranpart size: "<<std::endl<<maxpart.size()<<std::endl; WHtreePartition partitioner(&tree); std::string outPartFilename( outputFolder + "/maxgranPart.txt" ); partitioner.writePartitionSet( outPartFilename, partitionValues,partitionVector); tree.insertPartitions( partitionVector, partitionValues ); std::string outTreeFilename( outputFolder + "/" + tree.getName() + "_maxgranPart" ); outTreeFilename += ( ".txt" ); tree.writeTree( outTreeFilename, niftiMode ); return 0; } else { std::cout<<"ERROR: tree does not have a maximum granularity meta-leaf partition"<<std::endl; return(-1); } } if( levelDepth > 5 ) { std::cout << "Level depth indicated: " << levelDepth << " is too high, setting to a maximum of 5" << std::endl; levelDepth = 5; } std::cout << "Using a search depth of: " << levelDepth << std::endl; if( filterRadius > 1000 ) { std::cout << "filter radius indicated: " << filterRadius << " is too high (max is 1000), setting to 100" << std::endl; filterRadius = 10; } if( filterRadius == 0 ) { std::cout << "using no filtering (radius 0)" << std::endl; } else if( filterRadius < 0 ) { std::cout << "filter radius indicated: " << filterRadius << " must be positive. using no filtering (radius 0)" << std::endl; filterRadius = 0; } else { std::cout << "Using a filter radius of: " << filterRadius << std::endl; } ///////////////////////////////////////////////////////////////// std::string logFilename(outputFolder+"/"+progName+"_log.txt"); std::ofstream logFile(logFilename.c_str()); if(!logFile) { std::cerr << "ERROR: unable to open log file: \""<<logFilename<<"\""<<std::endl; exit(-1); } logFile <<"Start Time:\t"<< ctime(&programStartTime) <<std::endl; logFile <<"Working directory:\t"<< workingDir.string() <<std::endl; logFile <<"Verbose:\t"<< verbose <<std::endl; logFile <<"Tree file:\t"<< treeFilename <<std::endl; logFile <<"Output folder:\t"<< outputFolder <<std::endl; logFile <<"Verbose:\t"<< verbose <<std::endl; if( niftiMode ) { logFile << "Using nifti file format" << std::endl; } else { logFile << "Using vista file format" << std::endl; } WHtree tree(treeFilename); logFile << tree.getReport( false ) <<std::endl; std::cout<<tree.getReport( false )<<std::endl; std::vector< float > partitionValues; std::vector< std::vector< size_t> > partitionVector; WHtreePartition treePartition(&tree); std::string prefix; if (variableMap.count("hoz")) { prefix = "Hoz"; std::cout <<"getting hoz partitions at all levels..." <<std::endl; treePartition.scanHozPartitions( &partitionValues, &partitionVector ); std::cout << partitionValues.size() << " Partitions obtained, writing to file..." <<std::endl; logFile <<"Initial partitions:\t"<< partitionValues.size() <<std::endl; std::string outPartFilename( outputFolder + "/all" + prefix + "parts.txt" ); treePartition.writePartitionSet( outPartFilename, partitionValues, partitionVector); tree.insertPartitions( partitionVector, partitionValues ); std::string outTreeFilename( outputFolder + "/" + tree.getName() + "_" + prefix + "parts_d" + boost::lexical_cast<std::string>(levelDepth) ); outTreeFilename += ( ".txt" ); tree.writeTree( outTreeFilename, niftiMode ); } else { prefix = "SS"; std::cout <<"getting SS partitions at all levels..." <<std::endl; treePartition.scanOptimalPartitions( levelDepth, &partitionValues, &partitionVector ); std::cout << partitionValues.size() << " Partitions obtained, writing to file..." <<std::endl; logFile <<"Initial partitions:\t"<< partitionValues.size() <<std::endl; std::string outPartFilename( outputFolder + "/all" + prefix + "parts_d" + boost::lexical_cast<std::string>(levelDepth) + ".txt" ); treePartition.writePartitionSet( outPartFilename, partitionValues, partitionVector); tree.insertPartitions( partitionVector, partitionValues ); std::string outTreeFilename( outputFolder + "/" + tree.getName() + "_" + prefix + "parts_d" + boost::lexical_cast<std::string>(levelDepth) ); outTreeFilename += ( ".txt" ); tree.writeTree( outTreeFilename, niftiMode ); } std::vector < unsigned int > filterRadii; //filterRadii.reserve( 6 ); // filterRadii.push_back( 1 ); // filterRadii.push_back( 2 ); // filterRadii.push_back( 5 ); // filterRadii.push_back( 10 ); // filterRadii.push_back( 15 ); // filterRadii.push_back( 20 ); filterRadii.push_back( filterRadius ); for(size_t i=0; i< filterRadii.size(); ++i) { if( filterRadii[i] <= 0 ) { continue; } std::vector< float > filtPartValues( partitionValues ); std::vector< std::vector< size_t> > filtPartVector( partitionVector ); std::cout << "Filtering with a radius of "<< filterRadii[i] << "..." <<std::endl; treePartition.filterMaxPartitions( filterRadii[i], &filtPartValues, &filtPartVector ); std::cout << filtPartValues.size() << " Filtered partitions obtained, writing to file..." <<std::endl; logFile <<"Filtered partitions:\t"<< filtPartValues.size() <<std::endl; std::string outPartFilename( outputFolder + "/filt" + prefix + "parts_d" + boost::lexical_cast<std::string>(levelDepth) ); outPartFilename += ( "_r" + boost::lexical_cast<std::string>(filterRadii[i]) + ".txt" ); treePartition.writePartitionSet(outPartFilename, filtPartValues, filtPartVector); std::cout << "Adding filtered partitions to tree and writing..." <<std::endl; std::string outTreeFilename( outputFolder + "/" + tree.getName() + "_" + prefix + "parts_d" + boost::lexical_cast<std::string>(levelDepth) ); outTreeFilename += ( "_r" + boost::lexical_cast<std::string>(filterRadii[i]) + ".txt" ); tree.insertPartitions( filtPartVector, filtPartValues ); tree.writeTree( outTreeFilename, niftiMode ); } ///////////////////////////////////////////////////////////////// // save and print total time time_t programEndTime(time(NULL)); int totalTime( difftime(programEndTime,programStartTime) ); std::cout <<"Program Finished, total time: "<< totalTime/3600 <<"h "<< (totalTime%3600)/60 <<"' "<< ((totalTime%3600)%60) <<"\" "<< std::endl; logFile <<"-------------"<<std::endl; logFile <<"Finish Time:\t"<< ctime(&programEndTime) <<std::endl; logFile <<"Elapsed time : "<< totalTime/3600 <<"h "<< (totalTime%3600)/60 <<"' "<< ((totalTime%3600)%60) <<"\""<< std::endl; // } // catch(std::exception& e) // { // std::cout << e.what() << std::endl; // return 1; // } return 0; }
//-------------------------------------------------------------------------------------------------- int main(int argc, char** argv) { // Read in a configuration file if ( argc < 2 ) { fprintf( stderr, "No configuration file provided\n" ); showUsage( argv[ 0 ] ); return -1; } std::cout << "Starting Camera Calibration" << std::endl; cv::Size boardSize; cv::Size boardSizeMm; cv::Size imageSize; std::string cameraName; bool bUseDotPattern; std::string configFilename( argv[ 1 ] ); std::vector<std::string> NameLocation = LoadConfig( configFilename,&boardSize,&boardSizeMm,&cameraName,&bUseDotPattern); float squareWidth = ((float)boardSizeMm.width/1000.0f)/(boardSize.width-1); float squareHeight = ((float)boardSizeMm.height/1000.0f)/(boardSize.height-1); std::cout << squareWidth << " " << squareHeight << std::endl; std::vector<cv::Point3f> objectCorners; //The points in the world coordinates std::vector<std::vector<cv::Point3f>> objectPoints; //The points positions in pixels std::vector<std::vector<cv::Point2f>> imagePoints; //Camera output matrices cv::Mat cameraMatrix; cv::Mat distCoeffs; int successes = 0; //3D Scene Points //Initialize the chessboard corners //in the chessboard reference frame //The corners are at 3D location (x,y,z) = (i,j,0) for(int i=boardSize.height-1; i>=0; i--) for(int j=0; j<boardSize.width; j++) objectCorners.push_back(cv::Point3f(j*squareWidth,i*squareHeight,0.0f)); for(int i = 0; i < (int)NameLocation.size(); i++) { std::string ImageAddress = NameLocation.at(i); std::cout << "Image Name " <<ImageAddress << std::endl; cv::Mat image,colorimage1,colorimage2; image =cv::imread(ImageAddress, CV_LOAD_IMAGE_GRAYSCALE); //colorimage1 =cv::imread(ImageAddress, CV_LOAD_IMAGE_COLOR); //colorimage2 =cv::imread(ImageAddress, CV_LOAD_IMAGE_COLOR); imageSize.height = image.rows; imageSize.width = image.cols; /*cv::imshow("Image",image); cv::waitKey(); cv::destroyWindow("Image");*/ // output vector of image points std::vector<cv::Point2f> imageCorners; // number of corners on the chessboard bool found = false; if ( !bUseDotPattern ) { found = cv::findChessboardCorners(image,boardSize,imageCorners); if ( found ) { //cv::drawChessboardCorners(colorimage1,boardSize,imageCorners,found); //Get subpixel accuracy on the corners //cv::cornerSubPix(image,imageCorners,cv::Size(5,5),cv::Size(-1,-1),cv::TermCriteria(cv::TermCriteria::MAX_ITER + cv::TermCriteria::EPS,100,0.225)); //cv::drawChessboardCorners(colorimage2,boardSize,imageCorners,found); } } else { printf( "Looking for circles...\n" ); //found = cv::findCirclesGrid(image,boardSize,imageCorners); BlobDetector::Params params; //params.minArea = 5.0; //params.minArea = 5.0; params.maxArea = 20000.0; //params.minCircularity = 0.5; //params.minDistBetweenBlobs = 1.0; //params.filterByCircularity = false; //params.filterByInertia = false; //params.filterByConvexity = false; //printf( "minDistBetweenBlobs is %f\n", params.min ); cv::Ptr<cv::FeatureDetector> pDetector = new BlobDetector( params ); found = findCirclesGridAB( image, boardSize, imageCorners, cv::CALIB_CB_SYMMETRIC_GRID, pDetector ); if ( !found ) { cv::Mat scaled; float scale; if ( image.rows < 480 ) { scale = 2.0; } else { scale = 0.25; } cv::resize( image, scaled, cv::Size( 0, 0 ), scale, scale ); found = findCirclesGridAB( scaled, boardSize, imageCorners, cv::CALIB_CB_SYMMETRIC_GRID, pDetector ); std::cout << "Found " << imageCorners.size() << " corners" << std::endl; for ( uint32_t i = 0; i < imageCorners.size(); i++ ) { imageCorners[ i ].x /= scale; imageCorners[ i ].y /= scale; } } /*cv::namedWindow("Corners", CV_WINDOW_NORMAL); cv::drawChessboardCorners(image,boardSize,imageCorners,found); cv::imshow( "Corners", image ); cv::waitKey();*/ //cv::destroyWindow("Corners"); } if ( !found ) { printf( "Warning: Unable to find corners in %s\n", ImageAddress.c_str() ); continue; } //cv::drawChessboardCorners(colorimage1,boardSize,imageCorners,found); //If we have a good board, add it to our data if(imageCorners.size() == (uint32_t)boardSize.area()) { //Add Image and scene points from one view imagePoints.push_back(imageCorners); objectPoints.push_back(objectCorners); std::cout << "Successfully found " << imageCorners.size() << " corners" << std::endl; successes++; } else std::cout << "Failed" << std::endl; //cv::resize(colorimage1,colorimage1,cv::Size(1024,768)); //cv::resize(colorimage2,colorimage2,cv::Size(1024,768)); //cv::imshow("Pre Sub Pixel",colorimage1); //cv::imshow("Post Sub Pixel",colorimage2); //cv::waitKey(); //cv::destroyWindow("Pre Sub Pixel"); //cv::destroyWindow("Post Sub Pixel"); } std::vector<cv::Mat> rvecs,tvecs; cameraMatrix = cv::Mat::eye( 3, 3, CV_64F ); cameraMatrix.at<double>( 0, 0 ) = 5458.0; cameraMatrix.at<double>( 1, 1 ) = 5458.0; cameraMatrix.at<double>( 0, 2 ) = 2272.0/2.0; cameraMatrix.at<double>( 1, 2 ) = 1704.0/2.0; distCoeffs = cv::Mat::zeros( 8, 1, CV_64F ); std::cout << cv::calibrateCamera( objectPoints,imagePoints,imageSize,cameraMatrix,distCoeffs,rvecs,tvecs, CV_CALIB_USE_INTRINSIC_GUESS //| CV_CALIB_FIX_PRINCIPAL_POINT //| CV_CALIB_FIX_ASPECT_RATIO // | CV_CALIB_ZERO_TANGENT_DIST | CV_CALIB_FIX_K1 | CV_CALIB_FIX_K2 | CV_CALIB_FIX_K3 //| CV_CALIB_FIX_K4 | CV_CALIB_FIX_K5 | CV_CALIB_FIX_K6 )<< std::endl; cv::FileStorage fs((cameraName + "_cameraMatrix.yml").c_str(), cv::FileStorage::WRITE); fs << "cameraMatrix" << cameraMatrix; fs << "distCoeffs" << distCoeffs; std::cout << cameraMatrix << std::endl; std::cout << "Finished Camera Calibration" << std::endl; return 0; }
int main( int argc, char *argv[] ) { // try { time_t programStartTime(time(NULL)); boost::filesystem::path workingDir( boost::filesystem::current_path()); // ========== PROGRAM PARAMETERS ========== std::string progName("cpcc"); std::string configFilename("../../config/"+progName+".cfg"); // program parameters std::string treeFilename; std::string distMatrixFolder; unsigned int threads(0); bool niftiMode( true ); bool verbose(false); // Declare a group of options that will be allowed only on command line boost::program_options::options_description genericOptions("Generic options"); genericOptions.add_options() ( "version", "Program version" ) ( "help,h", "Produce extended program help message" ) ( "tree,t", boost::program_options::value< std::string >(&treeFilename), "file with the hierarchical tree to compute the cpcc value from") ( "inputf,I", boost::program_options::value< std::string >(&distMatrixFolder), "Input data folder with the distance matrix files.") ; // Declare a group of options that will be allowed both on command line and in config file boost::program_options::options_description configOptions("Configuration"); configOptions.add_options() ( "verbose,v", "[opt] verbose output." ) ( "vista", "[opt] use vista file format (default is nifti)." ) ( "pthreads,p", boost::program_options::value< unsigned int >(&threads), "[opt] number of processing cores to run the program in. Default: all available." ) ; // Hidden options, will be allowed both on command line and in config file, but will not be shown to the user. boost::program_options::options_description hiddenOptions("Hidden options"); //hiddenOptions.add_options() ; boost::program_options::options_description cmdlineOptions; cmdlineOptions.add(genericOptions).add(configOptions).add(hiddenOptions); boost::program_options::options_description configFileOptions; configFileOptions.add(configOptions).add(hiddenOptions); boost::program_options::options_description visibleOptions("Allowed options"); visibleOptions.add(genericOptions).add(configOptions); boost::program_options::positional_options_description posOpt; //this arguments do not need to specify the option descriptor when typed in posOpt.add("tree", -1); boost::program_options::variables_map variableMap; store(boost::program_options::command_line_parser(argc, argv).options(cmdlineOptions).positional(posOpt).run(), variableMap); std::ifstream ifs(configFilename.c_str()); store(parse_config_file(ifs, configFileOptions), variableMap); notify(variableMap); if (variableMap.count("help")) { std::cout << "---------------------------------------------------------------------------" << std::endl; std::cout << std::endl; std::cout << " Project: hClustering" << std::endl; std::cout << std::endl; std::cout << " Whole-Brain Connectivity-Based Hierarchical Parcellation Project" << std::endl; std::cout << " David Moreno-Dominguez" << std::endl; std::cout << " [email protected]" << std::endl; std::cout << " [email protected]" << std::endl; std::cout << " www.cbs.mpg.de/~moreno" << std::endl; std::cout << std::endl; std::cout << " For more reference on the underlying algorithm and research they have been used for refer to:" << std::endl; std::cout << " - Moreno-Dominguez, D., Anwander, A., & Knösche, T. R. (2014)." << std::endl; std::cout << " A hierarchical method for whole-brain connectivity-based parcellation." << std::endl; std::cout << " Human Brain Mapping, 35(10), 5000-5025. doi: http://dx.doi.org/10.1002/hbm.22528" << std::endl; std::cout << " - Moreno-Dominguez, D. (2014)." << std::endl; std::cout << " Whole-brain cortical parcellation: A hierarchical method based on dMRI tractography." << std::endl; std::cout << " PhD Thesis, Max Planck Institute for Human Cognitive and Brain Sciences, Leipzig." << std::endl; std::cout << " ISBN 978-3-941504-45-5" << std::endl; std::cout << std::endl; std::cout << " hClustering is free software: you can redistribute it and/or modify" << std::endl; std::cout << " it under the terms of the GNU Lesser General Public License as published by" << std::endl; std::cout << " the Free Software Foundation, either version 3 of the License, or" << std::endl; std::cout << " (at your option) any later version." << std::endl; std::cout << " http://creativecommons.org/licenses/by-nc/3.0" << std::endl; std::cout << std::endl; std::cout << " hClustering is distributed in the hope that it will be useful," << std::endl; std::cout << " but WITHOUT ANY WARRANTY; without even the implied warranty of" << std::endl; std::cout << " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the" << std::endl; std::cout << " GNU Lesser General Public License for more details." << std::endl; std::cout << std::endl; std::cout << "---------------------------------------------------------------------------" << std::endl << std::endl; std::cout << "cpcc" << std::endl << std::endl; std::cout << "Compute the cophenetic correlation coefficient (Farris, 1969) of a hierarchical tree." << std::endl << std::endl; std::cout << "* Arguments:" << std::endl << std::endl; std::cout << " --version: Program version." << std::endl << std::endl; std::cout << " -h --help: produce extended program help message." << std::endl << std::endl; std::cout << " -t --tree: File with the hierarchical tree to compute cpcc from." << std::endl << std::endl; std::cout << " -I --inputf: Input data folder containing the blocks of the precomputed tract pairwise distance matrix." << std::endl << std::endl; std::cout << "[-v --verbose]: verbose output (recommended)." << std::endl << std::endl; std::cout << "[--vista]: read/write vista (.v) files [default is nifti (.nii) and compact (.cmpct) files]." << std::endl << std::endl; std::cout << "[-p --pthreads]: number of processing threads to run the program in parallel. Default: use all available processors." << std::endl << std::endl; std::cout << std::endl; std::cout << "* Usage example:" << std::endl << std::endl; std::cout << " cpcc -t tree_lh.txt -I distBlocks/ -v" << std::endl << std::endl; std::cout << std::endl; std::cout << "* Outputs:" << std::endl << std::endl; std::cout << " - Introduces the cpcc value in the #cpcc field of the tree file defined at option -t." << std::endl; std::cout << std::endl; exit(0); } if (variableMap.count("version")) { std::cout << progName <<", version 2.0"<<std::endl; exit(0); } if (variableMap.count("verbose")) { std::cout << "verbose output"<<std::endl; verbose=true; } if (variableMap.count("pthreads")) { if (threads==1) { std::cout <<"Using a single processor"<< std::endl; } else if(threads==0 || threads>=omp_get_max_threads()) { threads = omp_get_max_threads(); std::cout <<"Using all available processors ("<< threads <<")." << std::endl; } else { std::cout <<"Using a maximum of "<< threads <<" processors "<< std::endl; } omp_set_num_threads( threads ); } else { threads = omp_get_max_threads(); omp_set_num_threads( threads ); std::cout <<"Using all available processors ("<< threads <<")." << std::endl; } if (variableMap.count("tree")) { if(!boost::filesystem::is_regular_file(boost::filesystem::path(treeFilename))) { std::cerr << "ERROR: tree file \""<<treeFilename<<"\" is not a regular file"<<std::endl; std::cerr << visibleOptions << std::endl; exit(-1); } std::cout << "Input tree file: "<< treeFilename << std::endl; } else { std::cerr << "ERROR: no tree file stated"<<std::endl; std::cerr << visibleOptions << std::endl; exit(-1); } if (variableMap.count("inputf")) { if(!boost::filesystem::is_directory(boost::filesystem::path(distMatrixFolder))) { std::cerr << "ERROR: distance matrix folder \""<<distMatrixFolder<<"\" is not a directory"<<std::endl; std::cerr << visibleOptions << std::endl; exit(-1); } std::cout << "Distance matrix folder: "<< distMatrixFolder << std::endl; } else { std::cerr << "ERROR: no distance matrix folder stated"<<std::endl; std::cerr << visibleOptions << std::endl; exit(-1); } if ( variableMap.count( "vista" ) ) { if( verbose ) { std::cout << "Using vista format" << std::endl; } fileManagerFactory fmf; fmf.setVista(); niftiMode = false; } else { if( verbose ) { std::cout << "Using nifti format" << std::endl; } fileManagerFactory fmf; fmf.setNifti(); niftiMode = true; } ///////////////////////////////////////////////////////////////// WHtree tree(treeFilename); if (verbose) { std::cout<<tree.getReport()<<std::endl; } if( !tree.isLoaded() ) { std::cerr << "Error while loading tree "<< std::endl; exit(-1); } treeManager treeMngr(&tree, verbose); treeMngr.setDistMatrixFolder(distMatrixFolder); float cpcc(treeMngr.doCpcc()); tree.writeTree(treeFilename,niftiMode); std::cout<<std::endl<<std::endl<<"CPCC: "<< cpcc <<std::endl<<std::endl; ///////////////////////////////////////////////////////////////// // save and print total time time_t programEndTime(time(NULL)); int totalTime( difftime(programEndTime,programStartTime) ); std::cout << "Program Finished, total time: " << totalTime/3600 <<"h "<< (totalTime%3600)/60 <<"' "<< ((totalTime%3600)%60) <<"\""<< std::endl; // } // catch(std::exception& e) // { // std::cout << e.what() << std::endl; // return 1; // } return 0; }
int main( int argc, char *argv[] ) { // try { time_t programStartTime(time(NULL)); boost::filesystem::path workingDir( boost::filesystem::current_path()); // ========== PROGRAM PARAMETERS ========== std::string progName("matchpartition"); std::string configFilename("../../config/"+progName+".cfg"); // program parameters std::string refTreeFilename, targetTreeFilename, matchTableFilename, outputFolder; unsigned int searchDepth(1); float lambda(0); bool signaturePart(false), colorMatching(false), overlapPart(false), exclusive(false); bool verbose(false), niftiMode( true ); // Declare a group of options that will be allowed only on command line boost::program_options::options_description genericOptions("Generic options"); genericOptions.add_options() ( "version", "Program version" ) ( "help,h", "Produce extended program help message" ) ( "reference,r", boost::program_options::value< std::string >(&refTreeFilename), "file with reference partitioned tree" ) ( "target,t", boost::program_options::value< std::string >(&targetTreeFilename), "file with target tree to be partitioned-matched" ) ( "leafmatch,m", boost::program_options::value< std::string >(&matchTableFilename), "file with meta-leaves (base-nodes) matching table" ) ( "outputf,O", boost::program_options::value< std::string >(&outputFolder), "output folder where partition-matched trees will be written" ) ( "signature,s", boost::program_options::value< float >(&lambda), "[xor with -o and -c] Signature-based partition matching, inster lambda coefficient value" ) ( "overlap,o", "[xor with -s and -c] Meta-leaf overlap-based partition matching") ( "depth,d", boost::program_options::value< unsigned int >(&searchDepth)->implicit_value(0), "[opt] partition search depth. Default: 0 (automatic partition-size based adaptive depth, recommended)") ( "justcolor,c", "[xor with -s and -o] Perform only olor matching (requires pre-computed partitions in both trees)") ( "excl,x", "[opt] color exclusively clusters that have a match, clusters without match will be white") ; // Declare a group of options that will be allowed both on command line and in config file boost::program_options::options_description configOptions("Configuration"); configOptions.add_options() ( "verbose,v", "[opt] verbose output." ) ( "vista", "[opt] Write output tree in vista coordinates (default is nifti)." ) ; // Hidden options, will be allowed both on command line and in config file, but will not be shown to the user. boost::program_options::options_description hiddenOptions("Hidden options"); //hiddenOptions.add_options() ; boost::program_options::options_description cmdlineOptions; cmdlineOptions.add(genericOptions).add(configOptions).add(hiddenOptions); boost::program_options::options_description configFileOptions; configFileOptions.add(configOptions).add(hiddenOptions); boost::program_options::options_description visibleOptions("Allowed options"); visibleOptions.add(genericOptions).add(configOptions); boost::program_options::positional_options_description posOpt; //this arguments do not need to specify the option descriptor when typed in //posOpt.add("roi-file", -1); boost::program_options::variables_map variableMap; store(boost::program_options::command_line_parser(argc, argv).options(cmdlineOptions).positional(posOpt).run(), variableMap); std::ifstream ifs(configFilename.c_str()); store(parse_config_file(ifs, configFileOptions), variableMap); notify(variableMap); if (variableMap.count( "help" ) ) { std::cout << "---------------------------------------------------------------------------" << std::endl; std::cout << std::endl; std::cout << " Project: hClustering" << std::endl; std::cout << std::endl; std::cout << " Whole-Brain Connectivity-Based Hierarchical Parcellation Project" << std::endl; std::cout << " David Moreno-Dominguez" << std::endl; std::cout << " [email protected]" << std::endl; std::cout << " [email protected]" << std::endl; std::cout << " www.cbs.mpg.de/~moreno" << std::endl; std::cout << std::endl; std::cout << " For more reference on the underlying algorithm and research they have been used for refer to:" << std::endl; std::cout << " - Moreno-Dominguez, D., Anwander, A., & Knösche, T. R. (2014)." << std::endl; std::cout << " A hierarchical method for whole-brain connectivity-based parcellation." << std::endl; std::cout << " Human Brain Mapping, 35(10), 5000-5025. doi: http://dx.doi.org/10.1002/hbm.22528" << std::endl; std::cout << " - Moreno-Dominguez, D. (2014)." << std::endl; std::cout << " Whole-brain cortical parcellation: A hierarchical method based on dMRI tractography." << std::endl; std::cout << " PhD Thesis, Max Planck Institute for Human Cognitive and Brain Sciences, Leipzig." << std::endl; std::cout << " ISBN 978-3-941504-45-5" << std::endl; std::cout << std::endl; std::cout << " hClustering is free software: you can redistribute it and/or modify" << std::endl; std::cout << " it under the terms of the GNU Lesser General Public License as published by" << std::endl; std::cout << " the Free Software Foundation, either version 3 of the License, or" << std::endl; std::cout << " (at your option) any later version." << std::endl; std::cout << " http://creativecommons.org/licenses/by-nc/3.0" << std::endl; std::cout << std::endl; std::cout << " hClustering is distributed in the hope that it will be useful," << std::endl; std::cout << " but WITHOUT ANY WARRANTY; without even the implied warranty of" << std::endl; std::cout << " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the" << std::endl; std::cout << " GNU Lesser General Public License for more details." << std::endl; std::cout << std::endl; std::cout << "---------------------------------------------------------------------------" << std::endl << std::endl; std::cout << "matchpartition" << std::endl << std::endl; std::cout << "Finds the best matching corresponding partitions in a target tree to those present in an unrelated reference tree (meta-leaf matching across these two trees must have been precomputed using comparetrees)." << std::endl; std::cout << " Two partition matching algorithms are available: signature matching and overlap matching. Found target partitions will be color-matched as best as possible." << std::endl; std::cout << " There is also the possibility of only color-matching predefined partitions of the target tree to predefined partitions of the reference tree." << std::endl << std::endl; std::cout << "* Arguments:" << std::endl << std::endl; std::cout << " --version: Program version." << std::endl << std::endl; std::cout << " -h --help: produce extended program help message." << std::endl << std::endl; std::cout << " -r --reference: The tree file with the reference partitioned tree." << std::endl << std::endl; std::cout << " -t --target: The tree file with the target tree to find matching partitions in (or with partitions to be color-matched)." << std::endl << std::endl; std::cout << " -m --leafmatch File with the meta-leaf matching information across both trees (output of comparetrees command)." << std::endl << std::endl; std::cout << " -O --outputf: Output folder where partitioned/color matched tree files will be written." << std::endl << std::endl; std::cout << "[-s --signature]: Signature-based partition matching, instert lambda coefficient value. [xor with -o and -c]." << std::endl; std::cout << " In this method a pair signature matrices are computed for each reference-target partitions to find the quality of the match." << std::endl; std::cout << " Each signature matrix defines a value for each pair of base-nodes of the tree it belongs to: 1 the base nodes are found in the same cluster, 0 if otherwise." << std::endl; std::cout << " The higher the correlation between the reference and target-derived matrices, the best match is the target tree partition to the reference tree one." << std::endl; std::cout << " A smart hierarchical search through possible partritions is conducted to find the one with best signature matching." << std::endl; std::cout << " The lambda coefficient determines if and how a similar number of clusters in both partitions affects the matching quality value," << std::endl; std::cout << " Lambda=0 -> cluster number does not affect the quality value. Lambda=1 -> cluster value similarity has as much weight as singature correlation." << std::endl << std::endl; std::cout << "[-o --overlap]: Overlap-based partition matching. [xor with -o and -c]." << std::endl; std::cout << " A match between two partititionsis found by iteratively matching clusters with higher base-node overlap and resolving possible ambiguities." << std::endl; std::cout << " The matching quality between partitions is defined as the number of base-nodes pairs that are classified in the same way in both partitions" << std::endl; std::cout << " (both in the smae cluster r both in different clusters) against the total number of pair combinations." << std::endl; std::cout << " A smart hierarchical search through possible partritions is conducted to find the one with best signature matching." << std::endl << std::endl; std::cout << "[-d --depth]: Partition search depth (for signature and overlap matching. A higher value will mean a more exhaustive search of the possible partitions," << std::endl; std::cout << " but also a higher computation time, specially if the partition to be matched has a high number of clusters (>100)." << std::endl; std::cout << " The default value (0, recommended) will adaptively give high search depth to low-cluster partitions and lower search depth to high-cluster partittions." << std::endl << std::endl; std::cout << "[-c --justcolor]: Perform only color matching across reference and target tree parttitions (both trees need to have the same number of precompouted partitions)." << std::endl; std::cout << " In multiple-to-one matching cases clusters from the reference tree might also be recolored to better identify matching relationships across partitions." << std::endl << std::endl; std::cout << "[-x --excl]: Color exclusively clusters that have a match, clusters without match will be recolored white (on both reference and target trees)" << std::endl << std::endl; std::cout << "[-v --verbose]: Verbose output (recommended)." << std::endl << std::endl; std::cout << "[--vista]: Write output tree files in vista coordinates (default is nifti)." << std::endl << std::endl; std::cout << std::endl; std::cout << "* Usage example:" << std::endl << std::endl; std::cout << " matchpartition -r refTree.txt -t targetTree.txt -m matching.txt -O results/ -s 0.5 -v" << std::endl << std::endl; exit(0); } if (variableMap.count( "version" ) ) { std::cout << progName <<", version 2.0"<<std::endl; exit(0); } if ( variableMap.count( "verbose" ) ) { std::cout << "verbose output" << std::endl; verbose=true; } if ( variableMap.count( "vista" ) ) { if( verbose ) { std::cout << "Using vista coordinates" << std::endl; } fileManagerFactory fmf; fmf.setVista(); niftiMode = false; } else { if( verbose ) { std::cout << "Using nifti coordinates" << std::endl; } fileManagerFactory fmf; fmf.setNifti(); niftiMode = true; } if (variableMap.count("reference")) { if(!boost::filesystem::is_regular_file( boost::filesystem::path( refTreeFilename ) ) ) { std::cerr << "ERROR: reference tree file \""<<refTreeFilename<<"\" is not a regular file"<<std::endl; std::cerr << visibleOptions << std::endl; exit(-1); } std::cout << "Reference tree file: "<< refTreeFilename << std::endl; } else { std::cerr << "ERROR: no reference tree file stated"<<std::endl; std::cerr << visibleOptions << std::endl; exit(-1); } if (variableMap.count( "target" ) ) { if(!boost::filesystem::is_regular_file(boost::filesystem::path( targetTreeFilename ) ) ) { std::cerr << "ERROR: target tree file \""<<targetTreeFilename<<"\" is not a regular file"<<std::endl; std::cerr << visibleOptions << std::endl; exit(-1); } std::cout << "Target tree file: "<< targetTreeFilename << std::endl; } else { std::cerr << "ERROR: no target tree file stated"<<std::endl; std::cerr << visibleOptions << std::endl; exit(-1); } if (variableMap.count( "leafmatch" ) ) { if(!boost::filesystem::is_regular_file(boost::filesystem::path( matchTableFilename ) ) ) { std::cerr << "ERROR: match table file \""<<matchTableFilename<<"\" is not a regular file"<<std::endl; std::cerr << visibleOptions << std::endl; exit(-1); } std::cout << "Match table file: "<< matchTableFilename << std::endl; } else { std::cerr << "ERROR: no match Table file stated"<<std::endl; std::cerr << visibleOptions << std::endl; exit(-1); } if( variableMap.count( "signature" ) + variableMap.count( "overlap" ) + variableMap.count( "justcolor" ) > 1 ) { std::cerr << "ERROR: multiple matching types selected, please use only one from -s, -o, -c."<<std::endl; std::cerr << visibleOptions << std::endl; exit(-1); } if (variableMap.count( "signature" ) ) { std::cout << "Performing Signature partition matching (and color matching)" << std::endl; std::cout <<" Using a lambda factor of "<< lambda << std::endl; signaturePart = true; colorMatching = true; } else if (variableMap.count( "overlap" ) ) { std::cout << "Performing Overlap partition matching (and color matching): " << std::endl; overlapPart = true; colorMatching = true; } else if (variableMap.count( "justcolor" ) ) { std::cout << "Performing only color matching: " << std::endl; colorMatching = true; } else { std::cerr << "ERROR: no matching type selected, select signature, overlap or color matching"<<std::endl; std::cerr << visibleOptions << std::endl; exit(-1); } if (variableMap.count( "excl" ) ) { std::cout << "Color exclusively matched clusters (unmatched clusters will be white) " << std::endl; exclusive = true; } if( signaturePart || overlapPart ) { if( searchDepth > 5 ) { std::cout << "Level depth indicated: " << searchDepth << " is too high, setting to a maximum of 5" << std::endl; searchDepth = 5; } else if ( searchDepth = 0 ) { std::cout << "Using automatic parttion-size based adaptive search depth " << std::endl; } else { std::cout << "Using a search depth of: " << searchDepth << std::endl; } } if (variableMap.count( "outputf" ) ) { if(!boost::filesystem::is_directory(boost::filesystem::path( outputFolder ) ) ) { std::cerr << "ERROR: output folder \""<<outputFolder<<"\" is not a directory"<<std::endl; std::cerr << visibleOptions << std::endl; exit(-1); } std::cout << "Output folder: "<< outputFolder << std::endl; } else { std::cerr << "ERROR: no output folder stated"<<std::endl; std::cerr << visibleOptions << std::endl; exit(-1); } std::string logFilename(outputFolder+"/"+progName+"_log.txt"); std::ofstream logFile(logFilename.c_str()); if(!logFile) { std::cerr << "ERROR: unable to open log file: \""<<logFilename<<"\""<<std::endl; exit(-1); } logFile <<"Start Time:\t"<< ctime(&programStartTime) <<std::endl; logFile <<"Working directory:\t"<< workingDir.string() <<std::endl; logFile <<"Verbose:\t"<< verbose <<std::endl; logFile <<"Reference tree:\t"<< refTreeFilename <<std::endl; logFile <<"Target tree:\t"<< targetTreeFilename <<std::endl; logFile <<"Matching table:\t"<< matchTableFilename <<std::endl; logFile <<"Output folder:\t"<< outputFolder <<std::endl; if( niftiMode ) { logFile << "Using nifti coordinates" << std::endl; } else { logFile << "Using vista coordinates" << std::endl; } logFile <<"-------------"<<std::endl; ///////////////////////////////////////////////////////////////// WHtree refTree( refTreeFilename ); WHtree targetTree( targetTreeFilename ); if (!refTree.isLoaded() || !targetTree.isLoaded() ) { throw std::runtime_error ("ERROR @ compareTrees(): trees are not loaded"); } logFile <<"Reference Tree: "<< refTree.getReport(false) <<std::endl; logFile <<"Target Tree: "<< targetTree.getReport(false) <<std::endl; if (refTree.getDataSize() != targetTree.getDataSize() ) { std::cerr <<"Reference Tree: "<< refTree.getReport() <<std::endl; std::cerr <<"Target Tree: "<< targetTree.getReport() <<std::endl; throw std::runtime_error ("ERROR @ compareTrees() datasets have different dimensions"); } if (verbose) { std::cout <<"Reference Tree: "<< refTree.getReport(false) <<std::endl; std::cout <<"Target Tree: "<< targetTree.getReport(false) <<std::endl; } partitionMatcher matcher(&refTree,&targetTree,matchTableFilename, verbose); std::string depthString; if( searchDepth > 0 ) { depthString = "_d"+string_utils::toString< unsigned int >( searchDepth ) ; } std::cout <<matcher.reportBaseNodes()<<std::endl; std::string suffixPart("_pm_Signature_l" + string_utils::toString< float >( lambda ) + depthString + ".txt"); std::string suffixNew("_pm_Overlap" + depthString + ".txt"); std::string suffixColor("_colorMatch.txt"); bool refTreeColorsChanged( false ); if( signaturePart ) { logFile << "Signature Matching" << std::endl; logFile << "Lambda:\t" << lambda <<std::endl; logFile << "Search depth:\t" << searchDepth <<std::endl; matcher.findMatchingPartitions( lambda ); } else if ( overlapPart ) { logFile << "Overlap Matching" <<std::endl; logFile << "Search depth:\t" << searchDepth <<std::endl; matcher.findMatchingPartitions( -1 ); } if( colorMatching ) { logFile << "Color Matching" <<std::endl; refTreeColorsChanged = matcher.matchColors( exclusive ); } std::string refOutput; std::string targetOutput; if ( signaturePart ) { targetOutput = outputFolder + "/" + targetTree.getName() + suffixPart; } else if ( overlapPart ) { targetOutput = outputFolder + "/" + targetTree.getName() + suffixNew ; } else { targetOutput = outputFolder + "/" + targetTree.getName() + suffixColor; } if( refTreeColorsChanged ) { refOutput = outputFolder + "/" + refTree.getName() + suffixColor; } else { refOutput = outputFolder + "/" + refTree.getName() + ".txt"; } if( verbose ) { std::cout << "Writing output target tree file to " << targetOutput << std::endl; std::cout << "Writing output reference tree file to " << refOutput << std::endl; } targetTree.writeTree( targetOutput, niftiMode ); refTree.writeTree( refOutput, niftiMode ); logFile << "Written output target tree file to " << targetOutput << std::endl; logFile << "Written output reference tree file to " << refOutput << std::endl; ///////////////////////////////////////////////////////////////// // save and print total time time_t programEndTime( time( NULL ) ); int totalTime( difftime( programEndTime, programStartTime ) ); std::cout <<"Program Finished, total time: "<< totalTime/3600 <<"h "<< (totalTime%3600)/60 <<"' "<< ((totalTime%3600)%60) <<"\" "<< std::endl; logFile <<"-------------"<<std::endl; logFile <<"Finish Time:\t"<< ctime(&programEndTime) <<std::endl; logFile <<"Elapsed time : "<< totalTime/3600 <<"h "<< (totalTime%3600)/60 <<"' "<< ((totalTime%3600)%60) <<"\""<< std::endl; // } // catch(std::exception& e) // { // std::cout << e.what() << std::endl; // return 1; // } return 0; }
/** Find out operating system name and version This method caches system information in m_osName, m_osVersion and m_osAlias. It requires m_unameInfo to be set prior to call. */ void SCXOSTypeInfo::Init() // private { m_osVersion = L""; m_osName = L"Unknown"; assert(m_unameIsValid); #if defined(hpux) || defined(sun) if (m_unameIsValid) { m_osName = StrFromUTF8(m_unameInfo.sysname); m_osVersion = StrFromUTF8(m_unameInfo.release); } #if defined(hpux) m_osAlias = L"HPUX"; m_osManufacturer = L"Hewlett-Packard Company"; #elif defined(sun) m_osAlias = L"Solaris"; m_osManufacturer = L"Oracle Corporation"; #endif #elif defined(aix) if (m_unameIsValid) { m_osName = StrFromUTF8(m_unameInfo.sysname); // To get "5.3" we must read "5" and "3" from different fields. string ver(m_unameInfo.version); ver.append("."); ver.append(m_unameInfo.release); m_osVersion = StrFromUTF8(ver); } m_osAlias = L"AIX"; m_osManufacturer = L"International Business Machines Corporation"; #elif defined(linux) vector<wstring> lines; SCXStream::NLFs nlfs; #if defined(PF_DISTRO_SUSE) static const string relFileName = "/etc/SuSE-release"; wifstream relfile(relFileName.c_str()); wstring version(L""); wstring patchlevel(L""); SCXStream::ReadAllLines(relfile, lines, nlfs); if (!lines.empty()) { m_osName = ExtractOSName(lines[0]); } // Set the Linux Caption (get first line of the /etc/SuSE-release file) m_linuxDistroCaption = lines[0]; if (0 == m_linuxDistroCaption.length()) { // Fallback - should not normally happen m_linuxDistroCaption = L"SuSE"; } // File contains one or more lines looking like this: // SUSE Linux Enterprise Server 10 (i586) // VERSION = 10 // PATCHLEVEL = 1 for (size_t i = 0; i<lines.size(); i++) { if (StrIsPrefix(StrTrim(lines[i]), L"VERSION", true)) { wstring::size_type n = lines[i].find_first_of(L"="); if (n != wstring::npos) { version = StrTrim(lines[i].substr(n+1)); } } else if (StrIsPrefix(StrTrim(lines[i]), L"PATCHLEVEL", true)) { wstring::size_type n = lines[i].find_first_of(L"="); if (n != wstring::npos) { patchlevel = StrTrim(lines[i].substr(n+1)); } } } if (version.length() > 0) { m_osVersion = version; if (patchlevel.length() > 0) { m_osVersion = version.append(L".").append(patchlevel); } } if (std::wstring::npos != m_osName.find(L"Desktop")) { m_osAlias = L"SLED"; } else { // Assume server. m_osAlias = L"SLES"; } m_osManufacturer = L"SUSE GmbH"; #elif defined(PF_DISTRO_REDHAT) static const string relFileName = "/etc/redhat-release"; wifstream relfile(relFileName.c_str()); SCXStream::ReadAllLines(relfile, lines, nlfs); if (!lines.empty()) { m_osName = ExtractOSName(lines[0]); } // Set the Linux Caption (get first line of the /etc/redhat-release file) m_linuxDistroCaption = lines[0]; if (0 == m_linuxDistroCaption.length()) { // Fallback - should not normally happen m_linuxDistroCaption = L"Red Hat"; } // File should contain one line that looks like this: // Red Hat Enterprise Linux Server release 5.1 (Tikanga) if (lines.size() > 0) { wstring::size_type n = lines[0].find_first_of(L"0123456789"); if (n != wstring::npos) { wstring::size_type n2 = lines[0].substr(n).find_first_of(L" \t\n\t"); m_osVersion = StrTrim(lines[0].substr(n,n2)); } } if ((std::wstring::npos != m_osName.find(L"Client")) // RHED5 || (std::wstring::npos != m_osName.find(L"Desktop"))) // RHED4 { m_osAlias = L"RHED"; } else { // Assume server. m_osAlias = L"RHEL"; } m_osManufacturer = L"Red Hat, Inc."; #elif defined(PF_DISTRO_ULINUX) // The release file is created at agent start time by init.d startup script // This is done to insure that we can write to the appropriate directory at // the time (since, at agent run-time, we may not have root privileges). // // If we CAN create the file here (if we're running as root), then we'll // do so here. But in the normal case, this shouldn't be necessary. Only // in "weird" cases (i.e. starting omiserver by hand, for example). // Create the release file by running GetLinuxOS.sh script // (if we have root privileges) try { if ( !SCXFile::Exists(m_deps->getReleasePath()) && SCXFile::Exists(m_deps->getScriptPath()) && m_deps->isReleasePathWritable() ) { std::istringstream in; std::ostringstream out; std::ostringstream err; int ret = SCXCoreLib::SCXProcess::Run(m_deps->getScriptPath().c_str(), in, out, err, 10000); if ( ret || out.str().length() || err.str().length() ) { wostringstream sout; sout << L"Unexpected errors running script: " << m_deps->getScriptPath().c_str() << L", return code: " << ret << L", stdout: " << StrFromUTF8(out.str()) << L", stderr: " << StrFromUTF8(err.str()); SCX_LOGERROR(m_log, sout.str() ); } } } catch(SCXCoreLib::SCXInterruptedProcessException &e) { wstring msg; msg = L"Timeout running script \"" + m_deps->getScriptPath() + L"\", " + e.Where() + L'.'; SCX_LOGERROR(m_log, msg ); }; // Look in release file for O/S information string sFile = StrToUTF8(m_deps->getReleasePath()); wifstream fin(sFile.c_str()); SCXStream::ReadAllLines(fin, lines, nlfs); if (!lines.empty()) { ExtractToken(L"OSName", lines, m_osName); ExtractToken(L"OSVersion", lines, m_osVersion); ExtractToken(L"OSFullName", lines, m_linuxDistroCaption); ExtractToken(L"OSAlias", lines, m_osAlias); ExtractToken(L"OSManufacturer", lines, m_osManufacturer); } else { m_osAlias = L"Universal"; } // Behavior for m_osCompatName (method GetOSName) should be as follows: // PostInstall scripts will first look for SCX-RELEASE file (only on universal kits) // If found, add "ORIGINAL_KIT_TYPE=Universal" to scxconfig.conf file, // else add "ORIGINAL_KIT_TYPE=!Universal" to scxconfig.conf file. // After that is set up, the SCX-RELEASE file is created. // // A RHEL system should of OSAlias of "RHEL, SLES system should have "SuSE" (in scx-release) // // We need to mimic return values for RHEL and SLES on universal kits that did not // have a universal kit installed previously, but only for RHEL and SLES kits. In // all other cases, continue to return "Linux Distribution". wstring configFilename(m_deps->getConfigPath()); SCXConfigFile configFile(configFilename); try { configFile.LoadConfig(); } catch(SCXFilePathNotFoundException &e) { // Something's whacky with postinstall, so we can't follow algorithm static SCXCoreLib::LogSuppressor suppressor(SCXCoreLib::eError, SCXCoreLib::eTrace); wstring logMessage(L"Unable to load configuration file " + configFilename); SCX_LOG(m_log, suppressor.GetSeverity(logMessage), logMessage); m_osCompatName = L"Unknown Linux Distribution"; } if ( m_osCompatName.empty() ) { wstring kitType; if ( configFile.GetValue(L"ORIGINAL_KIT_TYPE", kitType) ) { if ( L"!Universal" == kitType ) { if ( L"RHEL" == m_osAlias ) { m_osCompatName = L"Red Hat Distribution"; } else if ( L"SLES" == m_osAlias ) { m_osCompatName = L"SuSE Distribution"; } } } if ( m_osCompatName.empty() ) { m_osCompatName = L"Linux Distribution"; } } #else #error "Linux Platform not supported"; #endif #elif defined(macos) m_osAlias = L"MacOS"; m_osManufacturer = L"Apple Inc."; if (m_unameIsValid) { // MacOS is called "Darwin" in uname info, so we hard-code here m_osName = L"Mac OS"; // This value we could read dynamically from the xml file // /System/Library/CoreServices/SystemVersion.plist, but that // file may be named differently based on client/server, and // reading the plist file would require framework stuff. // // Rather than using the plist, we'll use Gestalt, which is an // API designed to figure out versions of anything and everything. // Note that use of Gestalt requires the use of framework stuff // as well, so the Makefiles for MacOS are modified for that. SInt32 major, minor, bugfix; if (0 != Gestalt(gestaltSystemVersionMajor, &major) || 0 != Gestalt(gestaltSystemVersionMinor, &minor) || 0 != Gestalt(gestaltSystemVersionBugFix, &bugfix)) { throw SCXCoreLib::SCXErrnoException(L"Gestalt", errno, SCXSRCLOCATION); } wostringstream sout; sout << major << L"." << minor << L"." << bugfix; m_osVersion = sout.str(); } #else #error "Platform not supported" #endif }
// this is just a workbench. most of the stuff here will go into the Frontend class. int main(int argc, char **argv) { ros::init(argc, argv, "okvis_node_synchronous"); google::InitGoogleLogging(argv[0]); FLAGS_stderrthreshold = 0; // INFO: 0, WARNING: 1, ERROR: 2, FATAL: 3 FLAGS_colorlogtostderr = 1; if (argc != 3 && argc != 4) { LOG(ERROR) << "Usage: ./" << argv[0] << " configuration-yaml-file bag-to-read-from [skip-first-seconds]"; return -1; } okvis::Duration deltaT(0.0); if (argc == 4) { deltaT = okvis::Duration(atof(argv[3])); } // set up the node ros::NodeHandle nh("okvis_node"); // publisher okvis::Publisher publisher(nh); // read configuration file std::string configFilename(argv[1]); okvis::RosParametersReader vio_parameters_reader(configFilename); okvis::VioParameters parameters; vio_parameters_reader.getParameters(parameters); okvis::ThreadedKFVio okvis_estimator(parameters); okvis_estimator.setFullStateCallback(std::bind(&okvis::Publisher::publishFullStateAsCallback,&publisher,std::placeholders::_1,std::placeholders::_2,std::placeholders::_3,std::placeholders::_4)); okvis_estimator.setLandmarksCallback(std::bind(&okvis::Publisher::publishLandmarksAsCallback,&publisher,std::placeholders::_1,std::placeholders::_2,std::placeholders::_3)); okvis_estimator.setStateCallback(std::bind(&okvis::Publisher::publishStateAsCallback,&publisher,std::placeholders::_1,std::placeholders::_2)); okvis_estimator.setBlocking(true); publisher.setParameters(parameters); // pass the specified publishing stuff // extract the folder path std::string bagname(argv[2]); size_t pos = bagname.find_last_of("/"); std::string path; if (pos == std::string::npos) path = "."; else path = bagname.substr(0, pos); const unsigned int numCameras = parameters.nCameraSystem.numCameras(); // setup files to be written publisher.setCsvFile(path + "/okvis_estimator_output.csv"); publisher.setLandmarksCsvFile(path + "/okvis_estimator_landmarks.csv"); okvis_estimator.setImuCsvFile(path + "/imu0_data.csv"); for (size_t i = 0; i < numCameras; ++i) { std::stringstream num; num << i; okvis_estimator.setTracksCsvFile(i, path + "/cam" + num.str() + "_tracks.csv"); } // open the bag rosbag::Bag bag(argv[2], rosbag::bagmode::Read); // views on topics. the slash is needs to be correct, it's ridiculous... std::string imu_topic("/imu0"); rosbag::View view_imu( bag, rosbag::TopicQuery(imu_topic)); if (view_imu.size() == 0) { LOG(ERROR) << "no imu topic"; return -1; } rosbag::View::iterator view_imu_iterator = view_imu.begin(); LOG(INFO) << "No. IMU messages: " << view_imu.size(); std::vector<std::shared_ptr<rosbag::View> > view_cams_ptr; std::vector<rosbag::View::iterator> view_cam_iterators; std::vector<okvis::Time> times; okvis::Time latest(0); for(size_t i=0; i<numCameras;++i) { std::string camera_topic("/cam"+std::to_string(i)+"/image_raw"); std::shared_ptr<rosbag::View> view_ptr( new rosbag::View( bag, rosbag::TopicQuery(camera_topic))); if (view_ptr->size() == 0) { LOG(ERROR) << "no camera topic"; return 1; } view_cams_ptr.push_back(view_ptr); view_cam_iterators.push_back(view_ptr->begin()); sensor_msgs::ImageConstPtr msg1 = view_cam_iterators[i] ->instantiate<sensor_msgs::Image>(); times.push_back( okvis::Time(msg1->header.stamp.sec, msg1->header.stamp.nsec)); if (times.back() > latest) latest = times.back(); LOG(INFO) << "No. cam " << i << " messages: " << view_cams_ptr.back()->size(); } for(size_t i=0; i<numCameras;++i) { if ((latest - times[i]).toSec() > 0.01) view_cam_iterators[i]++; } int counter = 0; okvis::Time start(0.0); while (ros::ok()) { ros::spinOnce(); okvis_estimator.display(); // check if at the end if (view_imu_iterator == view_imu.end()){ std::cout << std::endl << "Finished. Press any key to exit." << std::endl << std::flush; char k = 0; while(k==0 && ros::ok()){ k = cv::waitKey(1); ros::spinOnce(); } return 0; } for (size_t i = 0; i < numCameras; ++i) { if (view_cam_iterators[i] == view_cams_ptr[i]->end()) { std::cout << std::endl << "Finished. Press any key to exit." << std::endl << std::flush; char k = 0; while(k==0 && ros::ok()){ k = cv::waitKey(1); ros::spinOnce(); } return 0; } } // add images okvis::Time t; for(size_t i=0; i<numCameras;++i) { sensor_msgs::ImageConstPtr msg1 = view_cam_iterators[i] ->instantiate<sensor_msgs::Image>(); cv::Mat filtered(msg1->height, msg1->width, CV_8UC1); memcpy(filtered.data, &msg1->data[0], msg1->height * msg1->width); t = okvis::Time(msg1->header.stamp.sec, msg1->header.stamp.nsec); if (start == okvis::Time(0.0)) { start = t; } // get all IMU measurements till then okvis::Time t_imu=start; do { sensor_msgs::ImuConstPtr msg = view_imu_iterator ->instantiate<sensor_msgs::Imu>(); Eigen::Vector3d gyr(msg->angular_velocity.x, msg->angular_velocity.y, msg->angular_velocity.z); Eigen::Vector3d acc(msg->linear_acceleration.x, msg->linear_acceleration.y, msg->linear_acceleration.z); t_imu = okvis::Time(msg->header.stamp.sec, msg->header.stamp.nsec); // add the IMU measurement for (blocking) processing if (t_imu - start > deltaT) okvis_estimator.addImuMeasurement(t_imu, acc, gyr); view_imu_iterator++; } while (view_imu_iterator != view_imu.end() && t_imu <= t); // add the image to the frontend for (blocking) processing if (t - start > deltaT) okvis_estimator.addImage(t, i, filtered); view_cam_iterators[i]++; } ++counter; // display progress if (counter % 20 == 0) { std::cout << "\rProgress: " << int(double(counter) / double(view_cams_ptr.back()->size()) * 100) << "% " ; } } std::cout << std::endl; return 0; }