kopia lustrzana https://github.com/OpenDroneMap/ODM
Point cloud, textured model transform
rodzic
7aec8925d7
commit
9a77a4e611
|
@ -1,15 +1,18 @@
|
||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
|
import json
|
||||||
import codem
|
import codem
|
||||||
import dataclasses
|
import dataclasses
|
||||||
|
import pdal
|
||||||
|
import numpy as np
|
||||||
from opendm import log
|
from opendm import log
|
||||||
|
|
||||||
def compute_alignment_matrix(input_laz, align_file, tmp_dir):
|
def compute_alignment_matrix(input_laz, align_file, stats_dir):
|
||||||
if os.path.exists(tmp_dir):
|
if os.path.exists(stats_dir):
|
||||||
shutil.rmtree(tmp_dir)
|
shutil.rmtree(stats_dir)
|
||||||
os.mkdir(tmp_dir)
|
os.mkdir(stats_dir)
|
||||||
|
|
||||||
conf = dataclasses.asdict(codem.CodemRunConfig(align_file, input_laz, MIN_RESOLUTION=0.2, OUTPUT_DIR=tmp_dir)) # TODO: how to compute this
|
conf = dataclasses.asdict(codem.CodemRunConfig(align_file, input_laz, OUTPUT_DIR=stats_dir))
|
||||||
fnd_obj, aoi_obj = codem.preprocess(conf)
|
fnd_obj, aoi_obj = codem.preprocess(conf)
|
||||||
fnd_obj.prep()
|
fnd_obj.prep()
|
||||||
aoi_obj.prep()
|
aoi_obj.prep()
|
||||||
|
@ -29,6 +32,30 @@ def compute_alignment_matrix(input_laz, align_file, tmp_dir):
|
||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
|
|
||||||
return app_reg.get_registration_transformation()
|
reg = app_reg.get_registration_transformation()
|
||||||
# if os.path.exists(tmp_dir):
|
matrix = np.fromstring(reg['matrix'], dtype=float, sep=' ').reshape((4, 4))
|
||||||
# shutil.rmtree(tmp_dir)
|
return matrix
|
||||||
|
|
||||||
|
def transform_point_cloud(input_laz, a_matrix, output_laz):
|
||||||
|
pipe = [
|
||||||
|
input_laz,
|
||||||
|
{
|
||||||
|
'type': 'filters.transformation',
|
||||||
|
'matrix': " ".join(list(map(str, a_matrix.flatten()))),
|
||||||
|
},
|
||||||
|
output_laz,
|
||||||
|
]
|
||||||
|
p = pdal.Pipeline(json.dumps(pipe))
|
||||||
|
p.execute()
|
||||||
|
|
||||||
|
def transform_obj(input_obj, a_matrix, output_obj):
|
||||||
|
with open(input_obj, 'r') as fin:
|
||||||
|
with open(output_obj, 'w') as fout:
|
||||||
|
lines = fin.readlines()
|
||||||
|
for line in lines:
|
||||||
|
if line.startswith("v "):
|
||||||
|
v = np.fromstring(line.strip()[2:] + " 1", sep=' ', dtype=float)
|
||||||
|
vt = v.dot(a_matrix)[:3]
|
||||||
|
fout.write("v " + " ".join(map(str, list(vt))) + '\n')
|
||||||
|
else:
|
||||||
|
fout.write(line)
|
|
@ -85,3 +85,7 @@ def path_or_json_string_to_dict(string):
|
||||||
raise ValueError("{0} is not a valid JSON file.".format(string))
|
raise ValueError("{0} is not a valid JSON file.".format(string))
|
||||||
else:
|
else:
|
||||||
raise ValueError("{0} is not a valid JSON file or string.".format(string))
|
raise ValueError("{0} is not a valid JSON file or string.".format(string))
|
||||||
|
|
||||||
|
def touch(file):
|
||||||
|
with open(file, 'w') as fout:
|
||||||
|
fout.write("Done!\n")
|
|
@ -18,7 +18,7 @@ from opendm import point_cloud
|
||||||
from opendm.multispectral import get_primary_band_name
|
from opendm.multispectral import get_primary_band_name
|
||||||
from opendm.osfm import OSFMContext
|
from opendm.osfm import OSFMContext
|
||||||
from opendm.boundary import as_polygon, export_to_bounds_files
|
from opendm.boundary import as_polygon, export_to_bounds_files
|
||||||
from opendm.align import compute_alignment_matrix
|
from opendm.align import compute_alignment_matrix, transform_point_cloud, transform_obj
|
||||||
|
|
||||||
class ODMGeoreferencingStage(types.ODM_Stage):
|
class ODMGeoreferencingStage(types.ODM_Stage):
|
||||||
def process(self, args, outputs):
|
def process(self, args, outputs):
|
||||||
|
@ -170,18 +170,44 @@ class ODMGeoreferencingStage(types.ODM_Stage):
|
||||||
|
|
||||||
|
|
||||||
if tree.odm_align_file is not None:
|
if tree.odm_align_file is not None:
|
||||||
tmp_dir = tree.path("odm_georeferencing", "codem")
|
alignment_file = os.path.join(tree.odm_georeferencing, 'alignment_done.txt')
|
||||||
a_matrix = compute_alignment_matrix(tree.odm_georeferencing_model_laz, tree.odm_align_file, tmp_dir)
|
|
||||||
if a_matrix is not None:
|
if not io.file_exists(alignment_file) or self.rerun():
|
||||||
print(a_matrix)
|
stats_dir = tree.path("opensfm", "stats", "codem")
|
||||||
exit(1)
|
a_matrix = compute_alignment_matrix(tree.odm_georeferencing_model_laz, tree.odm_align_file, stats_dir)
|
||||||
|
if a_matrix is not None:
|
||||||
|
log.ODM_INFO("Alignment matrix: %s" % a_matrix)
|
||||||
|
|
||||||
|
# Align point cloud
|
||||||
|
unaligned_model = io.related_file_path(tree.odm_georeferencing_model_laz, postfix="_unaligned")
|
||||||
|
if not os.path.isfile(unaligned_model):
|
||||||
|
os.rename(tree.odm_georeferencing_model_laz, unaligned_model)
|
||||||
|
try:
|
||||||
|
transform_point_cloud(unaligned_model, a_matrix, tree.odm_georeferencing_model_laz)
|
||||||
|
log.ODM_INFO("Transformed %s" % tree.odm_georeferencing_model_laz)
|
||||||
|
except Exception as e:
|
||||||
|
log.ODM_WARNING("Cannot transform point cloud: %s" % str(e))
|
||||||
|
os.rename(unaligned_model, tree.odm_georeferencing_model_laz)
|
||||||
|
|
||||||
|
# Align textured models
|
||||||
|
for texturing in [tree.odm_texturing, tree.odm_25dtexturing]:
|
||||||
|
obj = os.path.join(texturing, "odm_textured_model_geo.obj")
|
||||||
|
if os.path.isfile(obj):
|
||||||
|
unaligned_obj = io.related_file_path(obj, postfix="_unaligned")
|
||||||
|
if not os.path.isfile(unaligned_obj):
|
||||||
|
os.rename(obj, unaligned_obj)
|
||||||
|
try:
|
||||||
|
transform_obj(unaligned_obj, a_matrix, obj)
|
||||||
|
log.ODM_INFO("Transformed %s" % obj)
|
||||||
|
except Exception as e:
|
||||||
|
log.ODM_WARNING("Cannot transform textured model: %s" % str(e))
|
||||||
|
os.rename(unaligned_obj, obj)
|
||||||
|
else:
|
||||||
|
log.ODM_WARNING("Alignment to %s will be skipped." % tree.odm_align_file)
|
||||||
|
|
||||||
|
io.touch(alignment_file)
|
||||||
else:
|
else:
|
||||||
log.ODM_WARNING("Alignment to %s will be skipped." % tree.odm_align_file)
|
log.ODM_WARNING("Already computed alignment")
|
||||||
# Align
|
|
||||||
# - Compute alignment
|
|
||||||
# - Transform point cloud
|
|
||||||
# - Transform textured model(s)
|
|
||||||
#
|
|
||||||
|
|
||||||
point_cloud.post_point_cloud_steps(args, tree, self.rerun())
|
point_cloud.post_point_cloud_steps(args, tree, self.rerun())
|
||||||
else:
|
else:
|
||||||
|
|
Ładowanie…
Reference in New Issue