cdcseacave / openMVS

open Multi-View Stereo reconstruction library
http://cdcseacave.github.io
GNU Affero General Public License v3.0
3.18k stars 890 forks source link

How to convert my own depth map into '.dmap' format for use? #1065

Open 834810269 opened 9 months ago

834810269 commented 9 months ago

I have performed sparse reconstruction using COLMAP and depth estimation using another method. Now, I want to use the openMVS library for point cloud fusion and mesh reconstruction. How can I convert a depth map or a '.dmb' file into a '.dmap' format for further processing?

ghost commented 8 months ago

I used a '.dmb' file from DAISY: A Fast Local Descriptor for Dense Matching as an example. The '.dmb' file I used might differ from yours but hopefully helps you understand how to read it.

from argparse import ArgumentParser
import numpy as np
import pyvips
import os

def loadDMB(dmb_path):
  with open(dmb_path, 'rb') as dmb:
    type = np.frombuffer(dmb.read(4), dtype=np.dtype('I'))[0]
    height, width = np.frombuffer(dmb.read(8), dtype=np.dtype('I'))

    depth_map = np.roll(np.frombuffer(dmb.read(4 * width * height), dtype=np.dtype('f')).reshape(height, width), -1)
    string_length = np.frombuffer(dmb.read(4), dtype=np.dtype('I'))[0]
    string = dmb.read(string_length).decode().replace(' \n', '\n').split('\n')

    calibration = {
      'name': string[0].split(' ')[1],
      'id': int(string[1].split(' ')[1]),
      'k': np.asarray(tuple(map(float, string[2].split(' ')[1:]))).reshape(3,3),
      'r': np.asarray(tuple(map(float, string[3].split(' ')[1:]))).reshape(3,3),
      'c': np.asarray(tuple(map(float, string[4].split(' ')[1:]))).reshape(3,1),
      'p': np.asarray(tuple(map(float, string[5].split(' ')[1:]))).reshape(3,4),
      'd': np.asarray(tuple(map(float, string[6].split(' ')[1:]))),
      'w': int(string[7].split(' ')[1]),
      'h': int(string[8].split(' ')[1]),
      't': np.asarray(tuple(map(float, string[9].split(' ')[1:]))).reshape(3,1),
      'fov': string[10].split(' ')[1],
      'range': np.asarray(tuple(map(float, string[11].split(' ')[1:])))
    }

    data = {
      'depth_map': depth_map,
      'calibration': calibration
    }

    return data

def main():
  parser = ArgumentParser()
  parser.add_argument('-i', '--input', type=str, required=True, help='path to the dmb file')
  args = parser.parse_args()

  data = loadDMB(args.input)

  pyvips.Image.new_from_array(np.uint8(data['depth_map'] * (1 / data['calibration']['range'][1]) * 255)).invert().write_to_file('{}_depth_map.png'.format(os.path.splitext(data['calibration']['name'])[0]))
  print(data['calibration'])

if __name__ == '__main__':
  main()