kopia lustrzana https://github.com/OpenDroneMap/ODM
46 wiersze
1.7 KiB
Python
Executable File
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)
|