Skip to content

Commit

Permalink
Fixing typos + preprocessing params
Browse files Browse the repository at this point in the history
  • Loading branch information
HarryHeres committed Dec 22, 2024
1 parent 6fc85b4 commit f1748f2
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 43 deletions.
28 changes: 17 additions & 11 deletions SlicerBoneMorphing/Resources/UI/SlicerBoneMorphing.ui
Original file line number Diff line number Diff line change
Expand Up @@ -176,26 +176,29 @@
<item row="2" column="0">
<widget class="QLabel" name="preprocessingNormalsEstimationRadiusLabel">
<property name="toolTip">
<string>Maximum radius for calculating normals. Calculated as multiplier of the object's voxel size</string>
<string>Maximum radius for calculating normals. Calculated as percentage of the object's size</string>
</property>
<property name="text">
<string>Normals estimation radius: </string>
<string>Normals estimation radius [%]: </string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QDoubleSpinBox" name="preprocessingNormalsEstimationRadiusDoubleSpinBox">
<property name="toolTip">
<string>Maximum radius for calculating normals. Calculated as multiplier of the object's voxel size</string>
<string>Maximum radius for calculating normals. Calculated as percentage of the object's size</string>
</property>
<property name="decimals">
<number>3</number>
</property>
<property name="minimum">
<double>1.000000000000000</double>
<double>0.001000000000000</double>
</property>
<property name="maximum">
<double>100.000000000000000</double>
</property>
<property name="value">
<double>4.000000000000000</double>
<double>8.000000000000000</double>
</property>
</widget>
</item>
Expand All @@ -205,7 +208,7 @@
<string>Maximum amount of points considered neighbouring. Calculated as percentage of the lower count of initial points of the source or target mesh</string>
</property>
<property name="text">
<string>Normals estimation max neighbours:</string>
<string>Normals estimation max neighbours [%]:</string>
</property>
</widget>
</item>
Expand All @@ -228,26 +231,29 @@
<item row="4" column="0">
<widget class="QLabel" name="preprocessingFpfhRadiusLabel">
<property name="toolTip">
<string>Maximum radius for calculating fast point feature histograms. Calculated as a multiplier of the object's voxel size</string>
<string>Maximum radius for calculating fast-point-feature histograms. Calculated as percentage of the object's size</string>
</property>
<property name="text">
<string>FPFH search radius:</string>
<string>FPFH search radius [%]:</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QDoubleSpinBox" name="preprocessingFpfhRadiusDoubleSpinBox">
<property name="toolTip">
<string>Maximum radius for calculating fast point feature histograms. Calculated as a multiplier of the object's voxel size</string>
<string>Maximum radius for calculating fast-point-feature histograms. Calculated as percentage of the object's size</string>
</property>
<property name="decimals">
<number>3</number>
</property>
<property name="minimum">
<double>1.000000000000000</double>
<double>0.001000000000000</double>
</property>
<property name="maximum">
<double>100.000000000000000</double>
</property>
<property name="value">
<double>10.000000000000000</double>
<double>20.000000000000000</double>
</property>
</widget>
</item>
Expand Down
12 changes: 6 additions & 6 deletions SlicerBoneMorphing/src/logic/Constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,14 @@
PREPROCESSING_KEY_DOWNSAMPLING_TARGET_TO_SOURCE = "dtts"
PREPROCESSING_KEY_NORMALS_ESTIMATION_RADIUS = "ner"
PREPROCESSING_KEY_FPFH_ESTIMATION_RADIUS = "fer"
PREPROCESSING_KEY_MAX_NN_NORMALS = "mnnn"
PREPROCESSING_KEY_MAX_NN_FPFH = "mnf"
PREPROCESSING_KEY_NORMALS_MAX_NN = "mnnn"
PREPROCESSING_KEY_FPFH_MAX_NN = "mnf"

PREPROCESSING_DEFAULT_VALUE_DOWNSAMPLING_VOXEL_SIZE = 0.0
PREPROCESSING_DEFAULT_VALUE_RADIUS_NORMAL_SCALE = 4
PREPROCESSING_DEFAULT_VALUE_RADIUS_FEATURE_SCALE = 10
PREPROCESSING_DEFAULT_VALUE_MAX_NN_NORMALS = 25
PREPROCESSING_DEFAULT_VALUE_MAX_NN_FPFH = 50
PREPROCESSING_DEFAULT_VALUE_NORMALS_ESTIMATION_RADIUS = 8
PREPROCESSING_DEFAULT_VALUE_FPFPH_ESTIMATION_RADIUS = 20
PREPROCESSING_DEFAULT_VALUE_NORMALS_MAX_NN = 25
PREPROCESSING_DEFAULT_VALUE_FPFH_MAX_NN = 50

### REGISTRATION PARAMETERS ###
REGISTRATION_KEY_RANSAC_DISTANCE_THRESHOLD = "rrdt"
Expand Down
39 changes: 19 additions & 20 deletions SlicerBoneMorphing/src/logic/SlicerBoneMorphingLogic.py
Original file line number Diff line number Diff line change
Expand Up @@ -224,23 +224,23 @@ def __preprocess_model(
target_pcd = self.__convert_mesh_to_point_cloud(target_mesh)

points_min = np.min([len(source_pcd.points), len(target_pcd.points)])
max_nn_normals = int(points_min * (parameters[const.PREPROCESSING_KEY_MAX_NN_NORMALS] / 100))
max_nn_fpfh = int(points_min * (parameters[const.PREPROCESSING_KEY_MAX_NN_FPFH] / 100))
max_nn_normals = int(points_min * (parameters[const.PREPROCESSING_KEY_NORMALS_MAX_NN] / 100))
max_nn_fpfh = int(points_min * (parameters[const.PREPROCESSING_KEY_FPFH_MAX_NN] / 100))

voxel_size = 0.0
object_size = 0.0
if parameters[const.PREPROCESSING_KEY_DOWNSAMPLING] is True:
if parameters[const.PREPROCESSING_KEY_DOWNSAMPLING_SOURCE_TO_TARGET] is True:
voxel_size = self.__calculate_object_size(target_pcd)
object_size = self.__calculate_object_size(target_pcd)
elif parameters[const.PREPROCESSING_KEY_DOWNSAMPLING_TARGET_TO_SOURCE] is True:
voxel_size = self.__calculate_object_size(source_pcd)
object_size = self.__calculate_object_size(source_pcd)
else:
print("ERROR: Downsampling is enabled but neither of the downsampling options was selected")
return [const.EXIT_FAILURE, None]

print("Preprocessing source mesh...")
source_pcd_downsampled, source_pcd_fpfh = self.__preprocess_point_cloud(
source_pcd,
voxel_size,
object_size,
parameters[const.PREPROCESSING_KEY_NORMALS_ESTIMATION_RADIUS],
parameters[const.PREPROCESSING_KEY_FPFH_ESTIMATION_RADIUS],
max_nn_normals,
Expand All @@ -250,21 +250,20 @@ def __preprocess_model(
print("Preprocessing target mesh...")
target_pcd_downsampled, target_pcd_fpfh = self.__preprocess_point_cloud(
target_pcd,
voxel_size,
object_size,
parameters[const.PREPROCESSING_KEY_NORMALS_ESTIMATION_RADIUS],
parameters[const.PREPROCESSING_KEY_FPFH_ESTIMATION_RADIUS],
max_nn_normals,
max_nn_fpfh
)

voxel_size = np.max([self.__calculate_object_size(source_pcd), self.__calculate_object_size(target_pcd)])
print("Calculated voxel size: " + str(voxel_size))
object_size = np.max([self.__calculate_object_size(source_pcd), self.__calculate_object_size(target_pcd)])

try:
result_ransac = self.__ransac_pcd_registration(
source_pcd_downsampled, target_pcd_downsampled,
source_pcd_fpfh, target_pcd_fpfh,
voxel_size * (parameters[const.REGISTRATION_KEY_RANSAC_DISTANCE_THRESHOLD] / 100),
object_size * (parameters[const.REGISTRATION_KEY_RANSAC_DISTANCE_THRESHOLD] / 100),
parameters[const.REGISTRATION_KEY_FITNESS_THRESHOLD],
parameters[const.REGISTRATION_KEY_MAX_ITERATIONS]
)
Expand All @@ -276,7 +275,7 @@ def __preprocess_model(

result_icp = o3d.pipelines.registration.registration_icp(
source_pcd_downsampled, target_pcd_downsampled,
voxel_size * (parameters[const.REGISTRATION_KEY_ICP_DISTANCE_THRESHOLD] / 100),
object_size * (parameters[const.REGISTRATION_KEY_ICP_DISTANCE_THRESHOLD] / 100),
result_ransac.transformation,
o3d.pipelines.registration.TransformationEstimationPointToPlane()
)
Expand All @@ -302,7 +301,7 @@ def __calculate_object_size(self, source: o3d.geometry.Geometry) -> float:
def __preprocess_point_cloud(
self,
pcd: o3d.geometry.PointCloud,
downsampling_voxel_size: float,
downsampling_object_size: float,
normals_estimation_radius: float,
fpfh_estimation_radius: float,
max_nn_normals: int,
Expand All @@ -313,8 +312,8 @@ def __preprocess_point_cloud(
Parameters
----------
o3d.geometry.PointCloud pcd: Source point cloud
float downsampling_distance_threshold: Distance threshold for downsampling
o3d.geometry.PointCloud pcd: Point cloud to preprocess
float downsampling_object_size: Size of the object to downsample to
float normals_estimation_radius: Radius for estimating normals
float fpfh_estimation_radius: Radius for the FPFH computation
int max_nn_normals: Maximum number of neighbours considered for normals estimation
Expand All @@ -327,15 +326,15 @@ def __preprocess_point_cloud(
- [1] = FPFH
'''

pcd_voxel_size = self.__calculate_object_size(pcd)
if downsampling_voxel_size > 0.0 and downsampling_voxel_size != pcd_voxel_size and pcd_voxel_size > downsampling_voxel_size:
print("Downsampling point cloud with voxel size: " + str(pcd_voxel_size) + " to target voxel size: " + str(downsampling_voxel_size))
pcd = pcd.voxel_down_sample(downsampling_voxel_size)
pcd_object_size = self.__calculate_object_size(pcd)
if downsampling_object_size > 0.0 and downsampling_object_size != pcd_object_size and pcd_object_size > downsampling_object_size:
print("Downsampling point cloud with size: " + str(pcd_object_size) + " to target object size: " + str(downsampling_object_size))
pcd = pcd.object_down_sample(downsampling_object_size)
else:
print("Downsampling will not be performed. The target voxel size is either less than 0, equal to the calculated voxel size and/or larger, than current voxel size")

pcd.estimate_normals(o3d.geometry.KDTreeSearchParamHybrid(radius=(pcd_voxel_size * normals_estimation_radius), max_nn=max_nn_normals))
pcd_fpfh = o3d.pipelines.registration.compute_fpfh_feature(pcd, o3d.geometry.KDTreeSearchParamHybrid(radius=pcd_voxel_size * fpfh_estimation_radius, max_nn=max_nn_fpfh))
pcd.estimate_normals(o3d.geometry.KDTreeSearchParamHybrid(radius=(pcd_object_size * (normals_estimation_radius / 100)), max_nn=max_nn_normals))
pcd_fpfh = o3d.pipelines.registration.compute_fpfh_feature(pcd, o3d.geometry.KDTreeSearchParamHybrid(radius=pcd_object_size * (fpfh_estimation_radius / 100), max_nn=max_nn_fpfh))
return pcd, pcd_fpfh

def __ransac_pcd_registration(
Expand Down
12 changes: 6 additions & 6 deletions SlicerBoneMorphing/src/widget/SlicerBoneMorphingWidget.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,10 @@ def __reset_parameters_to_default(self) -> None:
## Preprocessing parameters ##
self.__ui.preprocessingDownsamplingCheckBox.checked = False
self.__ui.preprocessingDownsamplingSourceToTargetRadioButton.checked = True
self.__ui.preprocessingNormalsEstimationRadiusDoubleSpinBox.value = const.PREPROCESSING_DEFAULT_VALUE_RADIUS_NORMAL_SCALE
self.__ui.preprocessingNormalsEstimationMaxNeighboursSpinBox.value = const.PREPROCESSING_DEFAULT_VALUE_MAX_NN_NORMALS
self.__ui.preprocessingFpfhRadiusDoubleSpinBox.value = const.PREPROCESSING_DEFAULT_VALUE_RADIUS_FEATURE_SCALE
self.__ui.preprocessingFpfhMaxNeighboursSpinBox.value = const.PREPROCESSING_DEFAULT_VALUE_MAX_NN_FPFH
self.__ui.preprocessingNormalsEstimationRadiusDoubleSpinBox.value = const.PREPROCESSING_DEFAULT_VALUE_NORMALS_ESTIMATION_RADIUS
self.__ui.preprocessingNormalsEstimationMaxNeighboursSpinBox.value = const.PREPROCESSING_DEFAULT_VALUE_NORMALS_MAX_NN
self.__ui.preprocessingFpfhRadiusDoubleSpinBox.value = const.PREPROCESSING_DEFAULT_VALUE_FPFPH_ESTIMATION_RADIUS
self.__ui.preprocessingFpfhMaxNeighboursSpinBox.value = const.PREPROCESSING_DEFAULT_VALUE_FPFH_MAX_NN

## Registration parameters ##
self.__ui.registrationMaxIterationsSpinBox.value = const.REGISTRATION_DEFAULT_VALUE_MAX_ITERATIONS
Expand Down Expand Up @@ -182,9 +182,9 @@ def __parse_parameters_preprocessing(self) -> dict:
params[const.PREPROCESSING_KEY_DOWNSAMPLING_SOURCE_TO_TARGET] = self.__ui.preprocessingDownsamplingSourceToTargetRadioButton.checked
params[const.PREPROCESSING_KEY_DOWNSAMPLING_TARGET_TO_SOURCE] = self.__ui.preprocessingDownsamplingTargetToSourceRadioButton.checked
params[const.PREPROCESSING_KEY_NORMALS_ESTIMATION_RADIUS] = self.__ui.preprocessingNormalsEstimationRadiusDoubleSpinBox.value
params[const.PREPROCESSING_KEY_MAX_NN_NORMALS] = self.__ui.preprocessingNormalsEstimationMaxNeighboursSpinBox.value
params[const.PREPROCESSING_KEY_NORMALS_MAX_NN] = self.__ui.preprocessingNormalsEstimationMaxNeighboursSpinBox.value
params[const.PREPROCESSING_KEY_FPFH_ESTIMATION_RADIUS] = self.__ui.preprocessingFpfhRadiusDoubleSpinBox.value
params[const.PREPROCESSING_KEY_MAX_NN_FPFH] = self.__ui.preprocessingFpfhMaxNeighboursSpinBox.value
params[const.PREPROCESSING_KEY_FPFH_MAX_NN] = self.__ui.preprocessingFpfhMaxNeighboursSpinBox.value

# Registration
params[const.REGISTRATION_KEY_MAX_ITERATIONS] = self.__ui.registrationMaxIterationsSpinBox.value
Expand Down

0 comments on commit f1748f2

Please sign in to comment.