convert.py 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. #
  2. # Copyright (C) 2023, Inria
  3. # GRAPHDECO research group, https://team.inria.fr/graphdeco
  4. # All rights reserved.
  5. #
  6. # This software is free for non-commercial, research and evaluation use
  7. # under the terms of the LICENSE.md file.
  8. #
  9. # For inquiries contact george.drettakis@inria.fr
  10. #
  11. import os
  12. import logging
  13. from argparse import ArgumentParser
  14. import shutil
  15. # This Python script is based on the shell converter script provided in the MipNerF 360 repository.
  16. parser = ArgumentParser("Colmap converter")
  17. parser.add_argument("--no_gpu", action='store_true')
  18. parser.add_argument("--skip_matching", action='store_true')
  19. parser.add_argument("--source_path", "-s", required=True, type=str)
  20. parser.add_argument("--camera", default="OPENCV", type=str)
  21. parser.add_argument("--colmap_executable", default="", type=str)
  22. parser.add_argument("--resize", action="store_true")
  23. parser.add_argument("--magick_executable", default="", type=str)
  24. args = parser.parse_args()
  25. colmap_command = '"{}"'.format(args.colmap_executable) if len(args.colmap_executable) > 0 else "colmap"
  26. magick_command = '"{}"'.format(args.magick_executable) if len(args.magick_executable) > 0 else "magick"
  27. use_gpu = 1 if not args.no_gpu else 0
  28. if not args.skip_matching:
  29. os.makedirs(args.source_path + "/distorted/sparse", exist_ok=True)
  30. ## Feature extraction
  31. feat_extracton_cmd = colmap_command + " feature_extractor "\
  32. "--database_path " + args.source_path + "/distorted/database.db \
  33. --image_path " + args.source_path + "/input \
  34. --ImageReader.single_camera 1 \
  35. --ImageReader.camera_model " + args.camera + " \
  36. --SiftExtraction.use_gpu " + str(use_gpu)
  37. exit_code = os.system(feat_extracton_cmd)
  38. if exit_code != 0:
  39. logging.error(f"Feature extraction failed with code {exit_code}. Exiting.")
  40. exit(exit_code)
  41. ## Feature matching
  42. feat_matching_cmd = colmap_command + " exhaustive_matcher \
  43. --database_path " + args.source_path + "/distorted/database.db \
  44. --SiftMatching.use_gpu " + str(use_gpu)
  45. exit_code = os.system(feat_matching_cmd)
  46. if exit_code != 0:
  47. logging.error(f"Feature matching failed with code {exit_code}. Exiting.")
  48. exit(exit_code)
  49. ### Bundle adjustment
  50. # The default Mapper tolerance is unnecessarily large,
  51. # decreasing it speeds up bundle adjustment steps.
  52. mapper_cmd = (colmap_command + " mapper \
  53. --database_path " + args.source_path + "/distorted/database.db \
  54. --image_path " + args.source_path + "/input \
  55. --output_path " + args.source_path + "/distorted/sparse \
  56. --Mapper.ba_global_function_tolerance=0.000001")
  57. exit_code = os.system(mapper_cmd)
  58. if exit_code != 0:
  59. logging.error(f"Mapper failed with code {exit_code}. Exiting.")
  60. exit(exit_code)
  61. ### Image undistortion
  62. ## We need to undistort our images into ideal pinhole intrinsics.
  63. img_undist_cmd = (colmap_command + " image_undistorter \
  64. --image_path " + args.source_path + "/input \
  65. --input_path " + args.source_path + "/distorted/sparse/0 \
  66. --output_path " + args.source_path + "\
  67. --output_type COLMAP")
  68. exit_code = os.system(img_undist_cmd)
  69. if exit_code != 0:
  70. logging.error(f"Mapper failed with code {exit_code}. Exiting.")
  71. exit(exit_code)
  72. files = os.listdir(args.source_path + "/sparse")
  73. os.makedirs(args.source_path + "/sparse/0", exist_ok=True)
  74. # Copy each file from the source directory to the destination directory
  75. for file in files:
  76. if file == '0':
  77. continue
  78. source_file = os.path.join(args.source_path, "sparse", file)
  79. destination_file = os.path.join(args.source_path, "sparse", "0", file)
  80. shutil.move(source_file, destination_file)
  81. if(args.resize):
  82. print("Copying and resizing...")
  83. # Resize images.
  84. os.makedirs(args.source_path + "/images_2", exist_ok=True)
  85. os.makedirs(args.source_path + "/images_4", exist_ok=True)
  86. os.makedirs(args.source_path + "/images_8", exist_ok=True)
  87. # Get the list of files in the source directory
  88. files = os.listdir(args.source_path + "/images")
  89. # Copy each file from the source directory to the destination directory
  90. for file in files:
  91. source_file = os.path.join(args.source_path, "images", file)
  92. destination_file = os.path.join(args.source_path, "images_2", file)
  93. shutil.copy2(source_file, destination_file)
  94. exit_code = os.system(magick_command + " mogrify -resize 50% " + destination_file)
  95. if exit_code != 0:
  96. logging.error(f"50% resize failed with code {exit_code}. Exiting.")
  97. exit(exit_code)
  98. destination_file = os.path.join(args.source_path, "images_4", file)
  99. shutil.copy2(source_file, destination_file)
  100. exit_code = os.system(magick_command + " mogrify -resize 25% " + destination_file)
  101. if exit_code != 0:
  102. logging.error(f"25% resize failed with code {exit_code}. Exiting.")
  103. exit(exit_code)
  104. destination_file = os.path.join(args.source_path, "images_8", file)
  105. shutil.copy2(source_file, destination_file)
  106. exit_code = os.system(magick_command + " mogrify -resize 12.5% " + destination_file)
  107. if exit_code != 0:
  108. logging.error(f"12.5% resize failed with code {exit_code}. Exiting.")
  109. exit(exit_code)
  110. print("Done.")