def runMainMenu(): main_menu = TerminalMenu( [ "1. Install dependencies", "2. Download datasets", "3. Compile project", "4. Compile author generated results into spreadsheets", "5. Run Clutterbox experiment", "6. Run Clutter fraction estimation", "7. Run projection algorithm benchmark (Table 1)", "8. Dump result visualisation OBJ files", "9. exit" ], title='---------------------- Main Menu ----------------------') while True: choice = main_menu.show() if choice == 0: installDependenciesMenu() if choice == 1: downloadDatasetsMenu() if choice == 2: compileProject() if choice == 3: runSpreadsheetBuilder() if choice == 4: runClutterbox() if choice == 5: runClutterEstimation() if choice == 6: runProjectionBenchmark() if choice == 7: runOBJDump() if choice == 8: return
def installDependenciesMenu(): install_menu = TerminalMenu( [ "Install all dependencies except CUDA", "Install CUDA (through APT)", "back" ], title='---------------- Install Dependencies ----------------') while True: choice = install_menu.show() if choice == 0: run_command_line_command( 'sudo apt install cmake python3 python3-pip libpcl-dev g++-7 gcc-7 wget p7zip' ) run_command_line_command( 'sudo pip3 install simple-term-menu xlwt xlrd numpy matplotlib pillow PyQt5' ) print() if choice == 1: run_command_line_command( 'sudo apt install nvidia-cuda-toolkit nvidia-cuda-dev') print() if choice == 2: return
def runClutterEstimation(): fileCount = len([ name for name in os.listdir(clutterSourceDumpFileDirectory) if os.path.isfile(os.path.join(clutterSourceDumpFileDirectory, name)) ]) while True: clutterEstimation_menu = TerminalMenu( [ "Run Clutter Estimator with random file index", "Run Clutter Estimator with manually specified file index", "Configure GPU (use if system has more than one, currently set to GPU " + str(gpuID) + ")", "back" ], title='------------ Run Clutter Estimator ------------') choice = clutterEstimation_menu.show() if choice == 0: index = random.randint(0, fileCount) executeClutterEstimator(index) if choice == 1: index = str( input( 'Specify index of file to process (must be an integer between 0 and ' + str(fileCount) + '): ')) executeClutterEstimator(index) if choice == 2: configureGPU() if choice == 3: activeObjectCounts.sort() return
def configureActiveDescriptors(): while True: run_menu = TerminalMenu( [ "Generate results for Radial Intersection Count Image: " + ("enabled" if "rici" in activeDescriptors else "disabled"), "Generate results for Spin Image: " + ("enabled" if "si" in activeDescriptors else "disabled"), "Generate results for 3D Shape Context: " + ("enabled" if "3dsc" in activeDescriptors else "disabled"), "done" ], title='-- Configure descriptors to be tested --') choice = run_menu.show() if choice == 0: if "rici" in activeDescriptors: activeDescriptors.remove("rici") else: activeDescriptors.append("rici") if choice == 1: if "si" in activeDescriptors: activeDescriptors.remove("si") else: activeDescriptors.append("si") if choice == 2: if "3dsc" in activeDescriptors: activeDescriptors.remove("3dsc") else: activeDescriptors.append("3dsc") if choice == 3: return
def configureActiveObjectCounts(): while True: run_menu = TerminalMenu( [ "Generate results for scene with 1 uncluttered object: " + ("enabled" if "1" in activeObjectCounts else "disabled"), "Generate results for scene with 4 added clutter objects: " + ("enabled" if "5" in activeObjectCounts else "disabled"), "Generate results for scene with 9 added clutter objects: " + ("enabled" if "10" in activeObjectCounts else "disabled"), "done" ], title='-- Configure object counts to be tested --') choice = run_menu.show() if choice == 0: if "1" in activeObjectCounts: activeObjectCounts.remove("1") else: activeObjectCounts.append("1") if choice == 1: if "5" in activeObjectCounts: activeObjectCounts.remove("5") else: activeObjectCounts.append("5") if choice == 2: if "10" in activeObjectCounts: activeObjectCounts.remove("10") else: activeObjectCounts.append("10") if choice == 3: activeObjectCounts.sort() return
def compileProject(): print('This project uses cmake for generating its makefiles.') print( 'It has a tendency to at times be unable to find an installed CUDA compiler.' ) print( 'Also, depending on which version of CUDA you have installed, you may need' ) print('to change the version of GCC/G++ used for compatibility reasons.') print( 'If either of these occurs, modify the paths at the top of the following file: ' ) print(' src/clutterbox/CMakeLists.txt') print() os.makedirs('src/clutterbox/build', exist_ok=True) compileProjectMenu = TerminalMenu( ["Run cmake (must run before make)", "Run make", "back"], title='------------------- Compile Project -------------------') while True: choice = compileProjectMenu.show() if choice == 0: run_command_line_command('rm src/clutterbox/build/*') run_command_line_command('cmake ..', 'src/clutterbox/build') if choice == 1: run_command_line_command('make -j 4', 'src/clutterbox/build') if choice == 2: return
def configureSpinImageAngle(): global spinImageSupportAngle spinangle_menu = TerminalMenu( [ "Set spin image support angle to 180 degrees (used for most charts)", "Set spin image support angle to 60 degrees (used for Figure 11)" ], title='-- Configure spin image support angle to use during testing --') choice = spinangle_menu.show() if choice == 0: spinImageSupportAngle = 180 if choice == 1: spinImageSupportAngle = 60
def runClutterbox(): while True: run_menu = TerminalMenu([ "Run experiment with random seed drawn from seed list at random", "Run experiment with random seed with specific index in seed list", "Run experiment with manually entered random seed", "Configure descriptors to test (currently active: " + ', '.join(activeDescriptors) + ")", "Configure object counts (currently active: " + ', '.join(activeObjectCounts) + ")", "Configure Spin Image support angle (currently set to " + str(spinImageSupportAngle) + ")", "Configure GPU (use if system has more than one, currently set to GPU " + str(gpuID) + ")", "back" ], title= '------------ Run Clutterbox Experiment ------------' ) choice = run_menu.show() if choice == 0: chosenSeed = random.choice(random_seeds) executeClutterboxExperiment(chosenSeed) print() if choice == 1: chosenSeedIndex = input( 'Specify the index of the random seed to use (must be between 0 and ' + str(len(random_seeds)) + '): ') chosenSeed = random_seeds[int(chosenSeedIndex)] executeClutterboxExperiment(chosenSeed) print() if choice == 2: chosenSeed = input( 'Manually specify random seed to use (must be an integer!): ') executeClutterboxExperiment(chosenSeed) print() if choice == 3: configureActiveDescriptors() print() if choice == 4: configureActiveObjectCounts() print() if choice == 5: configureSpinImageAngle() print() if choice == 6: configureGPU() print() if choice == 7: return
def runMainMenu(): main_menu = TerminalMenu( [ "1. Install dependencies", "2. Download datasets", "3. Compile project", "4. Run Hamming Tree Evaluation (Figure 7)", "5. Compile author generated results into spreadsheets (Figures 8-11)", "6. Run Clutterbox experiment (used for Figures 8-11)", "7. Run Clutter fraction estimation (used for Figure 9)", "8. Render scene shown in Figure 12", "9. Run Evaluation of Distance Functions (Figure 13)", "10. exit" ], title='---------------------- Main Menu ----------------------') while True: choice = main_menu.show() if choice == 0: installDependenciesMenu() if choice == 1: downloadDatasetsMenu() if choice == 2: compileProject() if choice == 3: runHammingTreeEvaluation() if choice == 4: runSpreadsheetBuilder() if choice == 5: runClutterbox() if choice == 6: runClutterEstimation() if choice == 7: runSofaScene() if choice == 8: runDistanceFunctionEvaluation() if choice == 9: return
def runOBJDump(): global activeDescriptors global activeObjectCounts os.makedirs('output/highlightedobjects/figure15a', exist_ok=True) os.makedirs('output/highlightedobjects/figure15b', exist_ok=True) os.makedirs('output/highlightedobjects/figure15c', exist_ok=True) os.makedirs('output/highlightedobjects/figure15d', exist_ok=True) os.makedirs('output/highlightedobjects/figure15e', exist_ok=True) os.makedirs('output/highlightedobjects/figure15f', exist_ok=True) os.makedirs('output/highlightedobjects/figure16/toprank', exist_ok=True) os.makedirs('output/highlightedobjects/figure16/top4ranks', exist_ok=True) os.makedirs('output/highlightedobjects/figure16/top6ranks', exist_ok=True) os.makedirs('output/highlightedobjects/figure16/top12ranks', exist_ok=True) while True: visualisation_menu = TerminalMenu( [ "Generate OBJ files for Figure 15a", "Generate OBJ files for Figure 15b", "Generate OBJ files for Figure 15c", "Generate OBJ files for Figure 15d", "Generate OBJ files for Figure 15e", "Generate OBJ files for Figure 15f", "Generate OBJ files for Figure 16", "Configure descriptors to test (currently active: " + ', '.join(activeDescriptors) + ")", "Configure object counts (currently active: " + ', '.join(activeObjectCounts) + ")", "Configure Spin Image support angle (currently set to " + str(spinImageSupportAngle) + ")", "Configure GPU (use if system has more than one, currently set to GPU " + str(gpuID) + ")", "back" ], title= '------------ Dump OBJ files with match visualisation ------------' ) choice = visualisation_menu.show() if choice == 0: executeClutterboxExperiment('3056361425', 'output/highlightedobjects/figure15a', 0, 'output/highlightedobjects/figure15a') if choice == 1: executeClutterboxExperiment('3461184303', 'output/highlightedobjects/figure15b', 0, 'output/highlightedobjects/figure15b') if choice == 2: executeClutterboxExperiment('1919129218', 'output/highlightedobjects/figure15c', 0, 'output/highlightedobjects/figure15c') if choice == 3: executeClutterboxExperiment('3617347629', 'output/highlightedobjects/figure15d', 0, 'output/highlightedobjects/figure15d') if choice == 4: executeClutterboxExperiment('3500854400', 'output/highlightedobjects/figure15e', 0, 'output/highlightedobjects/figure15e') if choice == 5: executeClutterboxExperiment('3098714219', 'output/highlightedobjects/figure15f', 0, 'output/highlightedobjects/figure15f') if choice == 6: print('Overriding settings with those used to generate images..') print() backup_objectCounts = activeObjectCounts backup_descriptors = activeDescriptors activeObjectCounts = ['1'] activeDescriptors = ['rici'] print('Generating top rank visualisation') executeClutterboxExperiment( '3048759171', 'output/highlightedobjects/figure16/toprank', 0) print() print('Generating top 4 ranks visualisation') executeClutterboxExperiment( '3048759171', 'output/highlightedobjects/figure16/top4ranks', 3) print() print('Generating top 6 ranks visualisation') executeClutterboxExperiment( '3048759171', 'output/highlightedobjects/figure16/top6ranks', 5) print() print('Generating top 12 ranks visualisation') executeClutterboxExperiment( '3048759171', 'output/highlightedobjects/figure16/top12ranks', 11) print() activeObjectCounts = backup_objectCounts activeDescriptors = backup_descriptors if choice == 7: configureActiveDescriptors() print() if choice == 8: configureActiveObjectCounts() print() if choice == 9: configureSpinImageAngle() print() if choice == 10: configureGPU() print() if choice == 11: return
def downloadDatasetsMenu(): download_menu = TerminalMenu([ "Download SHREC 2017 3D shape dataset (7.3GB download, ~50GB extracted)", "Download experiment results generated by authors (~1.5GB download, ~12GB extracted)", "back" ], title= '------------------ Download Datasets ------------------' ) while True: choice = download_menu.show() os.makedirs('input/download/', exist_ok=True) if choice == 0: if not os.path.isfile( 'input/download/SHREC17.7z' ) or ask_for_confirmation( 'It appears the SHREC 2017 dataset has already been downloaded. Would you like to download it again?' ): print('Downloading SHREC 2017 dataset..') run_command_line_command( 'wget --output-document SHREC17.7z https://data.mendeley.com/public-files/datasets/ysh8p862v2/files/607f79cd-74c9-4bfc-9bf1-6d75527ae516/file_downloaded', 'input/download/') print() os.makedirs('input/SHREC17', exist_ok=True) run_command_line_command('p7zip -k -d download/SHREC17.7z', 'input/') print( 'Download and extraction complete. You may now delete the file input/download/SHREC17.7z if you need the disk space.' ) print() if choice == 1: if not os.path.isfile( 'input/download/results_computed_by_authors.7z' ) or ask_for_confirmation( 'It appears the results archive file has already been downloaded. Would you like to download it again?' ): print('Downloading results archive file..') run_command_line_command( 'wget --output-document results_computed_by_authors.7z https://data.mendeley.com/public-files/datasets/p7g8fz82rk/files/29a722cc-b7b5-456a-a096-5d8ac55d6881/file_downloaded', 'input/download/') print() run_command_line_command( 'p7zip -k -d download/results_computed_by_authors.7z', 'input/') print() if not os.path.isfile( 'input/download/clutter_estimated_by_authors.7z' ) or ask_for_confirmation( 'It appears the clutter estimates file has already been downloaded. Would you like to download it again?' ): print('Downloading clutter estimates file..') run_command_line_command( 'wget --output-document clutter_estimated_by_authors.7z https://data.mendeley.com/public-files/datasets/p7g8fz82rk/files/37d353c5-7fd4-4488-a94a-97bb58dc722d/file_downloaded', 'input/download/') print() run_command_line_command( 'p7zip -k -d download/clutter_estimated_by_authors.7z', 'input/') if choice == 2: return
def ask_for_confirmation(message): confirmation_menu = TerminalMenu(["yes", "no"], title=message) choice = confirmation_menu.show() return choice == 0
def runDistanceFunctionEvaluation(): similarDistanceSeedFileMap = {} baselineDistanceSeedFileMap = {} similarSeedList = [] baselineSeedList = [] os.makedirs('output/distance_function_evaluation/nominal', exist_ok=True) os.makedirs('output/distance_function_evaluation/similar', exist_ok=True) if not os.path.isdir('input/distances_computed_by_authors'): print( 'Warning: The distance function values dataset appears to be missing.' ) print('Please download it before trying to replicate them.') else: similarSeedDirectory = 'input/distances_computed_by_authors/run12_quicci_distance_functions_rerun/output' for file in os.listdir(similarSeedDirectory): seed = file.split('.')[0].split('_')[3] similarDistanceSeedFileMap[seed] = os.path.join( similarSeedDirectory, file) similarSeedList.append(seed) baselineSeedDirectory = 'input/distances_computed_by_authors/run14_quicci_distance_functions_baseline' for file in os.listdir(baselineSeedDirectory): seed = file.split('.')[0].split('_')[3] baselineDistanceSeedFileMap[seed] = os.path.join( baselineSeedDirectory, file) baselineSeedList.append(seed) while True: distanceFunctionEvaluation_menu = TerminalMenu( [ "Compute 'nominal' result selected at random", "Compute 'nominal' result with specific index", "Compute 'similar' result selected at random", "Compute 'similar' result with specific index", "Compile results computed by authors into heatmaps and charts shown in Figure 13", "back" ], title='------------ Run Distance Functions Evaluation ------------' ) choice = distanceFunctionEvaluation_menu.show() if choice == 0: chosenSeed = random.choice(baselineSeedList) runDistanceFunctionBenchmark( chosenSeed, 'output/distance_function_evaluation/nominal', ['0'], 'baseline', baselineDistanceSeedFileMap[chosenSeed]) print() if choice == 1: chosenSeedIndex = input( 'Specify the index of the random seed to use (must be between 0 and ' + str(len(baselineSeedList)) + '): ') chosenSeed = baselineSeedList[int(chosenSeedIndex)] runDistanceFunctionBenchmark( chosenSeed, 'output/distance_function_evaluation/nominal', ['0'], 'baseline', baselineDistanceSeedFileMap[chosenSeed]) print() if choice == 2: chosenSeed = random.choice(similarSeedList) runDistanceFunctionBenchmark( chosenSeed, 'output/distance_function_evaluation/similar', [str(x) for x in range(0, 510, 10)], 'similar', similarDistanceSeedFileMap[chosenSeed]) print() if choice == 3: chosenSeedIndex = input( 'Specify the index of the random seed to use (must be between 0 and ' + str(len(similarSeedList)) + '): ') chosenSeed = similarSeedList[int(chosenSeedIndex)] runDistanceFunctionBenchmark( chosenSeed, 'output/distance_function_evaluation/similar', [str(x) for x in range(0, 510, 10)], 'similar', similarDistanceSeedFileMap[chosenSeed]) print() if choice == 4: run_command_line_command( 'python3 buildDistanceFunctionsSpreadsheet.py', 'scripts/') print() if choice == 5: return
def runHammingTreeEvaluation(): quicciDumpDir = 'output/hamming_tree/quicci_images' indexTreeDir = 'output/hamming_tree/hamming_tree' queryTimingsDir = 'output/hamming_tree/query_timings' indexRootDir = 'output/hamming_tree' os.makedirs(quicciDumpDir, exist_ok=True) os.makedirs(indexTreeDir, exist_ok=True) os.makedirs(queryTimingsDir, exist_ok=True) shrecDir = 'input/SHREC17/' OBJFiles = os.listdir(shrecDir) while True: run_menu = TerminalMenu([ "Render QUICCI images", "Compute index over computed images", "Benchmark query times", "Compile query times computed by authors into spreadsheet (Figure 7)", "back" ], title='------- Hamming Tree Evaluation -------' ) choice = run_menu.show() if choice == 0: print() objectCount = int( input( 'How many objects would you like to render images for? ')) startIndex = random.randint(0, len(OBJFiles) - objectCount) for objectIndex in range(startIndex, startIndex + objectCount): inFileName = OBJFiles[objectIndex] outFileName = inFileName.replace('.obj', '.dat') print() print( 'Rendering images for object', str(objectIndex - startIndex + 1) + '/' + str(objectCount) + ':', inFileName) run_command_line_command( 'src/clutterbox/build/libSpinImage/quiccidumper ' '--input-obj-file="' + os.path.join(shrecDir, inFileName) + '" ' '--output-dump-file="' + os.path.join(quicciDumpDir, outFileName) + '" ' '--fit-object-in-unit-sphere ' '--spin-image-width=0.3') if choice == 1: print('Removing any pre-existing index tree..') run_command_line_command('rm -rf ' + indexTreeDir + '/*') print() imageDumpFileCount = len(os.listdir(quicciDumpDir)) run_command_line_command( 'src/clutterbox/build/libSpinImage/buildindex ' '--index-directory="' + indexTreeDir + '" ' '--quicci-dump-directory="' + quicciDumpDir + '" ' '--runtime-json-file="' + indexRootDir + '" ' '--from-file-index=0 ' '--to-file-index=' + str(imageDumpFileCount) + ' ' '--cache-node-limit=100000 ' '--cache-image-limit=10000000') print() print('Index has been written to:', indexTreeDir) print() if choice == 2: print() run_command_line_command( 'src/clutterbox/build/libSpinImage/benchmarkindex ' '--index-directory="' + indexTreeDir + '" ' '--index-quicci-dump-directory="' + quicciDumpDir + '" ' '--query-quicci-dump-directory="' + quicciDumpDir + '" ' '--output-directory="' + queryTimingsDir + '" ' '--random-seed=0') print() if choice == 3: print() run_command_line_command('python3 analyseQueryTimes.py', 'scripts/') print() print('Done.') print() print( 'Results have been written to: output/figure_7_query_times.csv' ) print() if choice == 4: return
def downloadDatasetsMenu(): download_menu = TerminalMenu([ "Download all", "Download SHREC 2017 3D shape dataset (7.9GB download, ~52.5GB extracted, needed for all Figures)", "Download experiment results generated by authors (~1.6GB download, 13.8GB extracted, needed for Figures 8-11)", "Download distance function values computed by authors (8.0GB download, 51.2GB extracted, needed for Figure 13)", "back" ], title= '------------------ Download Datasets ------------------' ) while True: choice = download_menu.show() os.makedirs('input/download/', exist_ok=True) if choice == 0 or choice == 1: if not os.path.isfile( 'input/download/SHREC17.7z' ) or ask_for_confirmation( 'It appears the SHREC 2017 dataset has already been downloaded. Would you like to download it again?' ): print('Downloading SHREC 2017 dataset..') run_command_line_command( 'wget --output-document SHREC17.7z https://data.mendeley.com/public-files/datasets/ysh8p862v2/files/607f79cd-74c9-4bfc-9bf1-6d75527ae516/file_downloaded', 'input/download/') print() os.makedirs('input/SHREC17', exist_ok=True) run_command_line_command('p7zip -k -d download/SHREC17.7z', 'input/') print( 'Download and extraction complete. You may now delete the file input/download/SHREC17.7z if you need the disk space.' ) print() if choice == 0 or choice == 2: if not os.path.isfile( 'input/download/results_computed_by_authors.7z' ) or ask_for_confirmation( 'It appears the results archive file has already been downloaded. Would you like to download it again?' ): print('Downloading results archive file..') run_command_line_command( 'wget --output-document results_computed_by_authors.7z https://data.mendeley.com/public-files/datasets/p7g8fz82rk/files/29a722cc-b7b5-456a-a096-5d8ac55d6881/file_downloaded', 'input/download/') print() run_command_line_command( 'p7zip -k -d download/results_computed_by_authors.7z', 'input/') print() if not os.path.isfile( 'input/download/results_computed_by_authors_quicci_fpfh.7z' ) or ask_for_confirmation( 'It appears the second results archive file has already been downloaded. Would you like to download it again?' ): print('Downloading results archive file..') run_command_line_command( 'wget --output-document results_computed_by_authors_quicci_fpfh.7z https://data.mendeley.com/public-files/datasets/k9j5ymry29/files/519b9cab-71a7-40fa-924e-10cf9b7905d7/file_downloaded', 'input/download/') print() run_command_line_command( 'p7zip -k -d download/results_computed_by_authors_quicci_fpfh.7z', 'input/') print() if not os.path.isfile( 'input/download/clutter_estimated_by_authors.7z' ) or ask_for_confirmation( 'It appears the clutter estimates file has already been downloaded. Would you like to download it again?' ): print('Downloading clutter estimates file..') run_command_line_command( 'wget --output-document clutter_estimated_by_authors.7z https://data.mendeley.com/public-files/datasets/p7g8fz82rk/files/37d353c5-7fd4-4488-a94a-97bb58dc722d/file_downloaded', 'input/download/') print() run_command_line_command( 'p7zip -k -d download/clutter_estimated_by_authors.7z', 'input/') print() print( 'Download and extraction complete. You may now delete the following files if you need the disk space:' ) print('- input/download/results_computed_by_authors.7z') print( '- input/download/results_computed_by_authors_quicci_fpfh.7z') print('- input/download/clutter_estimated_by_authors.7z') print() if choice == 0 or choice == 3: if not os.path.isfile( 'input/download/distances_computed_by_authors.7z' ) or ask_for_confirmation( 'It appears the computed distances archive file has already been downloaded. Would you like to download it again?' ): print( 'Downloading distance function distances computed by authors..' ) run_command_line_command( 'wget --output-document distances_computed_by_authors.7z https://data.mendeley.com/public-files/datasets/k9j5ymry29/files/b3fe4f65-bf36-4fa7-9d26-217a59e35e54/file_downloaded', 'input/download/') print() os.makedirs('input/SHREC17', exist_ok=True) run_command_line_command( 'p7zip -k -d download/distances_computed_by_authors.7z', 'input/') print( 'Download and extraction complete. You may now delete the file input/download/distances_computed_by_authors.7z if you need the disk space.' ) print() if choice == 4: return