OpenDroneMap-ODM/opendm/dem/ground_rectification/extra_dimensions/distance_dimension.py

46 wiersze
1.7 KiB
Python
Executable File

import numpy as np
from sklearn.linear_model import RANSACRegressor
from .dimension import Dimension
class DistanceDimension(Dimension):
"""Assign each point the distance to the estimated ground"""
def __init__(self):
super(DistanceDimension, self).__init__()
def assign_default(self, point_cloud):
default = np.full(point_cloud.len(), -1)
super(DistanceDimension, self)._set_values(point_cloud, default)
def assign(self, *point_clouds, **kwargs):
for point_cloud in point_clouds:
xy = point_cloud.get_xy()
# Calculate RANSCAC model
model = RANSACRegressor().fit(xy, point_cloud.get_z())
# Calculate angle between estimated plane and XY plane
angle = self.__calculate_angle(model)
if angle >= 45:
# If the angle is higher than 45 degrees, then don't calculate the difference, since it will probably be way off
diff = np.full(point_cloud.len(), 0)
else:
predicted = model.predict(xy)
diff = point_cloud.get_z() - predicted
# Ignore the diff when the diff is below the ground
diff[diff < 0] = 0
super(DistanceDimension, self)._set_values(point_cloud, diff)
def get_name(self):
return 'distance_to_ground'
def get_las_type(self):
return 'float64'
def __calculate_angle(self, model):
"Calculate the angle between the estimated plane and the XY plane"
a = model.estimator_.coef_[0]
b = model.estimator_.coef_[1]
angle = np.arccos(1 / np.sqrt(a ** 2 + b ** 2 + 1))
return np.degrees(angle)