diff --git a/evaltest/combination1.json b/evaltest/combination1.json new file mode 100644 index 0000000..79a4cf0 --- /dev/null +++ b/evaltest/combination1.json @@ -0,0 +1,345 @@ +{ + "defaults": { + "downsample": 0.05, + "curvature_radius": 0.25, + "pca_radius": 0.25, + "density_radius": 0.15, + "pca_max_nn": 10000, + "tree_count": 100, + "tree_depth": 10 + }, + "tests": [ + { + "name": "PC + Eigenvalues", + "features": [ + "Curvature 1", + "Curvature 2", + "Eigen 1", + "Eigen 2", + "Eigen 3" + ] + }, + { + "name": "PC + Intensity", + "features": [ + "Curvature 1", + "Curvature 2", + "Intensity" + ] + }, + { + "name": "PC + Eigenvalue derivatives", + "features": [ + "Curvature 1", + "Curvature 2", + "Linearity", + "Planarity", + "Sphericity", + "Anisotrophy", + "Eigenentrophy", + "Omnivariance" + ] + }, + { + "name": "PC + Normals", + "features": [ + "Curvature 1", + "Curvature 2", + "X Normal", + "Y Normal", + "Z Normal" + ] + }, + { + "name": "PC + Density", + "features": [ + "Curvature 1", + "Curvature 2", + "Density" + ] + }, + + + + + + { + "name": "PC + Eigenvalues + Intensity", + "features": [ + "Curvature 1", + "Curvature 2", + "Eigen 1", + "Eigen 2", + "Eigen 3", + "Intensity" + ] + }, + { + "name": "PC + Eigenvalue derivatives + Intensity", + "features": [ + "Curvature 1", + "Curvature 2", + "Linearity", + "Planarity", + "Sphericity", + "Anisotrophy", + "Eigenentrophy", + "Omnivariance", + "Intensity" + ] + }, + { + "name": "PC + Normals + Intensity", + "features": [ + "Curvature 1", + "Curvature 2", + "X Normal", + "Y Normal", + "Z Normal", + "Intensity" + ] + }, + { + "name": "PC + Density + Intensity", + "features": [ + "Curvature 1", + "Curvature 2", + "Density", + "Intensity" + ] + }, + + + + + + { + "name": "PC + Eigenvalues + Intensity + Eigenvalue derivatives", + "features": [ + "Curvature 1", + "Curvature 2", + "Eigen 1", + "Eigen 2", + "Eigen 3", + "Intensity", + "Linearity", + "Planarity", + "Sphericity", + "Anisotrophy", + "Eigenentrophy", + "Omnivariance" + ] + }, + { + "name": "PC + Normals + Intensity + Eigenvalue derivatives", + "features": [ + "Curvature 1", + "Curvature 2", + "X Normal", + "Y Normal", + "Z Normal", + "Intensity", + "Linearity", + "Planarity", + "Sphericity", + "Anisotrophy", + "Eigenentrophy", + "Omnivariance" + ] + }, + { + "name": "PC + Density + Intensity + Eigenvalue derivatives", + "features": [ + "Curvature 1", + "Curvature 2", + "Density", + "Intensity", + "Linearity", + "Planarity", + "Sphericity", + "Anisotrophy", + "Eigenentrophy", + "Omnivariance" + ] + }, + + + + + + { + "name": "PC + Eigenvalues + Intensity + Eigenvalue derivatives + Normals", + "features": [ + "Curvature 1", + "Curvature 2", + "Eigen 1", + "Eigen 2", + "Eigen 3", + "Intensity", + "Linearity", + "Planarity", + "Sphericity", + "Anisotrophy", + "Eigenentrophy", + "Omnivariance", + "X Normal", + "Y Normal", + "Z Normal" + ] + }, + { + "name": "PC + Density + Intensity + Eigenvalue derivatives", + "features": [ + "Curvature 1", + "Curvature 2", + "Density", + "Intensity", + "Linearity", + "Planarity", + "Sphericity", + "Anisotrophy", + "Eigenentrophy", + "Omnivariance", + "X Normal", + "Y Normal", + "Z Normal" + ] + }, + + + + + { + "name": "PC + Eigenvalues + Intensity + Eigenvalue derivatives + Normals + Density", + "features": [ + "Curvature 1", + "Curvature 2", + "Eigen 1", + "Eigen 2", + "Eigen 3", + "Intensity", + "Linearity", + "Planarity", + "Sphericity", + "Anisotrophy", + "Eigenentrophy", + "Omnivariance", + "X Normal", + "Y Normal", + "Z Normal", + "Density" + ] + }, + + + + { + "name": "PC + Eigenvalues + Intensity + Eigenvalue derivatives + Normals + Density + XYZ", + "features": [ + "Curvature 1", + "Curvature 2", + "Eigen 1", + "Eigen 2", + "Eigen 3", + "Intensity", + "Linearity", + "Planarity", + "Sphericity", + "Anisotrophy", + "Eigenentrophy", + "Omnivariance", + "X Normal", + "Y Normal", + "Z Normal", + "Density", + "X", + "Y", + "Z" + ] + }, + + + + { + "name": "PC + Eigenvalues + Intensity + Eigenvalue derivatives + Normals + Density + XYZ + Distance from origin", + "features": [ + "Curvature 1", + "Curvature 2", + "Eigen 1", + "Eigen 2", + "Eigen 3", + "Intensity", + "Linearity", + "Planarity", + "Sphericity", + "Anisotrophy", + "Eigenentrophy", + "Omnivariance", + "X Normal", + "Y Normal", + "Z Normal", + "Density", + "X", + "Y", + "Z", + "Distance from origin" + ] + }, + + + + { + "name": "PC + Eigenvalues + Intensity + Eigenvalue derivatives + Normals + Density + XYZ + Distance from origin + Curvature", + "features": [ + "Curvature 1", + "Curvature 2", + "Eigen 1", + "Eigen 2", + "Eigen 3", + "Intensity", + "Linearity", + "Planarity", + "Sphericity", + "Anisotrophy", + "Eigenentrophy", + "Omnivariance", + "X Normal", + "Y Normal", + "Z Normal", + "Density", + "X", + "Y", + "Z", + "Distance from origin", + "Curvature" + ] + }, + + + + { + "name": "Eigenvalues + Intensity + Eigenvalue derivatives + Normals + Density + XYZ + Distance from origin + Curvature", + "features": [ + "Eigen 1", + "Eigen 2", + "Eigen 3", + "Intensity", + "Linearity", + "Planarity", + "Sphericity", + "Anisotrophy", + "Eigenentrophy", + "Omnivariance", + "X Normal", + "Y Normal", + "Z Normal", + "Density", + "X", + "Y", + "Z", + "Distance from origin", + "Curvature" + ] + } + ] +} diff --git a/evaltest/combination2.json b/evaltest/combination2.json new file mode 100644 index 0000000..3cc596e --- /dev/null +++ b/evaltest/combination2.json @@ -0,0 +1,425 @@ +{ + "defaults": { + "downsample": 0.05, + "curvature_radius": 0.25, + "pca_radius": 0.25, + "density_radius": 0.15, + "pca_max_nn": 10000, + "tree_count": 100, + "tree_depth": 10 + }, + "tests": [ + { + "name": "PC + Eigenvalues", + "features": [ + "Curvature 1", + "Curvature 2", + "Eigen 1", + "Eigen 2", + "Eigen 3" + ] + }, + { + "name": "PC + Intensity", + "features": [ + "Curvature 1", + "Curvature 2", + "Intensity" + ] + }, + { + "name": "PC + Eigenvalue derivatives", + "features": [ + "Curvature 1", + "Curvature 2", + "Linearity", + "Planarity", + "Sphericity", + "Anisotrophy", + "Eigenentrophy", + "Omnivariance" + ] + }, + { + "name": "PC + Normals", + "features": [ + "Curvature 1", + "Curvature 2", + "X Normal", + "Y Normal", + "Z Normal" + ] + }, + { + "name": "PC + Density", + "features": [ + "Curvature 1", + "Curvature 2", + "Density" + ] + }, + + + + + + { + "name": "PC + Eigenvalues + Intensity", + "features": [ + "Curvature 1", + "Curvature 2", + "Eigen 1", + "Eigen 2", + "Eigen 3", + "Intensity" + ] + }, + { + "name": "PC + Eigenvalue derivatives + Intensity", + "features": [ + "Curvature 1", + "Curvature 2", + "Linearity", + "Planarity", + "Sphericity", + "Anisotrophy", + "Eigenentrophy", + "Omnivariance", + "Intensity" + ] + }, + { + "name": "PC + Normals + Intensity", + "features": [ + "Curvature 1", + "Curvature 2", + "X Normal", + "Y Normal", + "Z Normal", + "Intensity" + ] + }, + { + "name": "PC + Density + Intensity", + "features": [ + "Curvature 1", + "Curvature 2", + "Density", + "Intensity" + ] + }, + + + + + + { + "name": "PC + Eigenvalues + Intensity + Eigenvalue derivatives", + "features": [ + "Curvature 1", + "Curvature 2", + "Eigen 1", + "Eigen 2", + "Eigen 3", + "Intensity", + "Linearity", + "Planarity", + "Sphericity", + "Anisotrophy", + "Eigenentrophy", + "Omnivariance" + ] + }, + { + "name": "PC + Normals + Intensity + Eigenvalue derivatives", + "features": [ + "Curvature 1", + "Curvature 2", + "X Normal", + "Y Normal", + "Z Normal", + "Intensity", + "Linearity", + "Planarity", + "Sphericity", + "Anisotrophy", + "Eigenentrophy", + "Omnivariance" + ] + }, + { + "name": "PC + Density + Intensity + Eigenvalue derivatives", + "features": [ + "Curvature 1", + "Curvature 2", + "Density", + "Intensity", + "Linearity", + "Planarity", + "Sphericity", + "Anisotrophy", + "Eigenentrophy", + "Omnivariance" + ] + }, + + + + + + { + "name": "PC + Eigenvalues + Intensity + Eigenvalue derivatives + Normals", + "features": [ + "Curvature 1", + "Curvature 2", + "Eigen 1", + "Eigen 2", + "Eigen 3", + "Intensity", + "Linearity", + "Planarity", + "Sphericity", + "Anisotrophy", + "Eigenentrophy", + "Omnivariance", + "X Normal", + "Y Normal", + "Z Normal" + ] + }, + { + "name": "PC + Density + Intensity + Eigenvalue derivatives", + "features": [ + "Curvature 1", + "Curvature 2", + "Density", + "Intensity", + "Linearity", + "Planarity", + "Sphericity", + "Anisotrophy", + "Eigenentrophy", + "Omnivariance", + "X Normal", + "Y Normal", + "Z Normal" + ] + }, + + + + + { + "name": "PC + Eigenvalues + Intensity + Eigenvalue derivatives + Normals + Density", + "features": [ + "Curvature 1", + "Curvature 2", + "Eigen 1", + "Eigen 2", + "Eigen 3", + "Intensity", + "Linearity", + "Planarity", + "Sphericity", + "Anisotrophy", + "Eigenentrophy", + "Omnivariance", + "X Normal", + "Y Normal", + "Z Normal", + "Density" + ] + }, + + + + { + "name": "PC + Eigenvalues + Intensity + Eigenvalue derivatives + Normals + Density + XYZ", + "features": [ + "Curvature 1", + "Curvature 2", + "Eigen 1", + "Eigen 2", + "Eigen 3", + "Intensity", + "Linearity", + "Planarity", + "Sphericity", + "Anisotrophy", + "Eigenentrophy", + "Omnivariance", + "X Normal", + "Y Normal", + "Z Normal", + "Density", + "X", + "Y", + "Z" + ] + }, + + + + { + "name": "PC + Eigenvalues + Intensity + Eigenvalue derivatives + Normals + Density + XYZ + Distance from origin", + "features": [ + "Curvature 1", + "Curvature 2", + "Eigen 1", + "Eigen 2", + "Eigen 3", + "Intensity", + "Linearity", + "Planarity", + "Sphericity", + "Anisotrophy", + "Eigenentrophy", + "Omnivariance", + "X Normal", + "Y Normal", + "Z Normal", + "Density", + "X", + "Y", + "Z", + "Distance from origin" + ] + }, + + + + { + "name": "PC + Eigenvalues + Intensity + Eigenvalue derivatives + Normals + Density + XYZ + Distance from origin + Curvature", + "features": [ + "Curvature 1", + "Curvature 2", + "Eigen 1", + "Eigen 2", + "Eigen 3", + "Intensity", + "Linearity", + "Planarity", + "Sphericity", + "Anisotrophy", + "Eigenentrophy", + "Omnivariance", + "X Normal", + "Y Normal", + "Z Normal", + "Density", + "X", + "Y", + "Z", + "Distance from origin", + "Curvature" + ] + }, + + + + { + "name": "Eigenvalues + Intensity + Eigenvalue derivatives + Normals + Density + XYZ + Distance from origin + Curvature", + "features": [ + "Eigen 1", + "Eigen 2", + "Eigen 3", + "Intensity", + "Linearity", + "Planarity", + "Sphericity", + "Anisotrophy", + "Eigenentrophy", + "Omnivariance", + "X Normal", + "Y Normal", + "Z Normal", + "Density", + "X", + "Y", + "Z", + "Distance from origin", + "Curvature" + ] + }, + + + { + "name": "PC + Eigenvalues + Intensity + Eigenvalue derivatives + Normals + Density + XYZ + Curvature", + "features": [ + "Curvature 1", + "Curvature 2", + "Eigen 1", + "Eigen 2", + "Eigen 3", + "Intensity", + "Linearity", + "Planarity", + "Sphericity", + "Anisotrophy", + "Eigenentrophy", + "Omnivariance", + "X Normal", + "Y Normal", + "Z Normal", + "Density", + "X", + "Y", + "Z", + "Curvature" + ] + }, + + + { + "name": "PC + Eigenvalues + Intensity + Eigenvalue derivatives + Normals + XYZ + Curvature", + "features": [ + "Curvature 1", + "Curvature 2", + "Eigen 1", + "Eigen 2", + "Eigen 3", + "Intensity", + "Linearity", + "Planarity", + "Sphericity", + "Anisotrophy", + "Eigenentrophy", + "Omnivariance", + "X Normal", + "Y Normal", + "Z Normal", + "X", + "Y", + "Z", + "Curvature" + ] + }, + + + { + "name": "PC + Eigenvalues + Intensity + Eigenvalue derivatives + Normals + XYZ", + "features": [ + "Curvature 1", + "Curvature 2", + "Eigen 1", + "Eigen 2", + "Eigen 3", + "Intensity", + "Linearity", + "Planarity", + "Sphericity", + "Anisotrophy", + "Eigenentrophy", + "Omnivariance", + "X Normal", + "Y Normal", + "Z Normal", + "X", + "Y", + "Z" + ] + } + + + ] +} diff --git a/evaltest/combination3.json b/evaltest/combination3.json new file mode 100644 index 0000000..21beb9a --- /dev/null +++ b/evaltest/combination3.json @@ -0,0 +1,74 @@ +{ + "defaults": { + "downsample": 0.05, + "curvature_radius": 0.25, + "pca_radius": 0.25, + "density_radius": 0.15, + "pca_max_nn": 10000, + "tree_count": 100, + "tree_depth": 10 + }, + "tests": [ + { + "name": "PC + Eigenvalues + Intensity + Normals + XYZ", + "features": [ + "Curvature 1", + "Curvature 2", + "Eigen 1", + "Eigen 2", + "Eigen 3", + "Intensity", + "X Normal", + "Y Normal", + "Z Normal", + "X", + "Y", + "Z" + ] + }, + { + "name": "Eigenvalues + Intensity + Normals + XYZ", + "features": [ + "Eigen 1", + "Eigen 2", + "Eigen 3", + "Intensity", + "X Normal", + "Y Normal", + "Z Normal", + "X", + "Y", + "Z" + ] + }, + { + "name": "PC + Intensity + Normals + XYZ", + "features": [ + "Curvature 1", + "Curvature 2", + "Eigen 1", + "Eigen 2", + "Eigen 3", + "Intensity", + "X Normal", + "Y Normal", + "Z Normal", + "X", + "Y", + "Z" + ] + }, + { + "name": "PC + Intensity + XYZ", + "features": [ + "Curvature 1", + "Curvature 2", + "Intensity", + "X", + "Y", + "Z" + ] + } + + ] +} diff --git a/tests.json b/evaltest/tests.json similarity index 92% rename from tests.json rename to evaltest/tests.json index f74ab9d..a3eaab4 100644 --- a/tests.json +++ b/evaltest/tests.json @@ -1,7 +1,13 @@ { + "scans": [ + "/home/rickert/testdata/featureeval/noise.ccp", + "/home/rickert/testdata/featureeval/people_facades_ground.ccp", + "/home/rickert/testdata/featureeval/tools.ccp", + "/home/rickert/testdata/featureeval/tree_ground-facade.ccp" + ], "defaults": { "downsample": 0.05, - "curvature_radius": 0.25, + "curvature_radius": 0.2, "pca_radius": 0.25, "density_radius": 0.25, "pca_max_nn": 1000, @@ -124,10 +130,6 @@ "name": "Density r=0.25", "features": ["Number of neighbours"], "density_radius": 0.25 - }, { - "name": "Density r=0.5", - "features": ["Number of neighbours"], - "density_radius": 0.5 }, { "name": "Distance from origin", "features": ["Distance from origin"] diff --git a/tests2.json b/evaltest/tests2.json similarity index 100% rename from tests2.json rename to evaltest/tests2.json diff --git a/tests3.json b/evaltest/tests3.json similarity index 100% rename from tests3.json rename to evaltest/tests3.json diff --git a/evaltest2/del/combinations.json b/evaltest2/del/combinations.json new file mode 100644 index 0000000..e97a43e --- /dev/null +++ b/evaltest2/del/combinations.json @@ -0,0 +1,31 @@ +{ + "scans": [ + { + "path": "/home/rickert/testdata/featureeval/tree_ground-facade.ccp", + "targetLayerName": "New Layer 37", + "resultSelection": 1 + } + ], + "defaults": { + "downsample": 0.02, + "curvature_radius": 0.2, + "pca_radius": 0.2, + "density_radius": 0.2, + "pca_max_nn": 1000, + "tree_count": 100, + "tree_depth": 10 + }, + "tests": [{ + "name": "Eigenvalues r=0.1", + "features": ["Eigen 1", "Eigen 2", "Eigen 3"], + "pca_radius": 0.1 + }, { + "name": "Eigenvalues r=0.2", + "features": ["Eigen 1", "Eigen 2", "Eigen 3"], + "pca_radius": 0.2 + }, { + "name": "Eigenvalues r=0.3", + "features": ["Eigen 1", "Eigen 2", "Eigen 3"], + "pca_radius": 0.3 + }] +} diff --git a/evaltest2/del/combo-features (copy).json b/evaltest2/del/combo-features (copy).json new file mode 100644 index 0000000..a67c19f --- /dev/null +++ b/evaltest2/del/combo-features (copy).json @@ -0,0 +1,72 @@ +{ + "scans": [ + { + "path": "/home/rickert/testdata/featureeval/noise.ccp", + "targetLayerName": "noise", + "resultSelection": 0 + }, + { + "path": "/home/rickert/testdata/featureeval/people_facades_ground.ccp", + "targetLayerName": "people", + "resultSelection": 1 + }, + { + "path": "/home/rickert/testdata/featureeval/tools.ccp", + "targetLayerName": "tools", + "resultSelection": 0 + }, + { + "path": "/home/rickert/testdata/featureeval/tree_ground-facade.ccp", + "targetLayerName": "New Layer 37", + "resultSelection": 1 + } + ], + "defaults": { + "downsample": 0.02, + "curvature_radius": 0.3, + "pca_radius": 0.2, + "density_radius": 0.2, + "pca_max_nn": 1000, + "tree_count": 100, + "tree_depth": 10 + }, + "tests": [ + { + "name": "Principal curvatures ", + "features": ["Curvature 1", "Curvature 2"] + }, { + "name": "Eigenvalues", + "features": ["Eigen 1", "Eigen 2", "Eigen 3"] + }, { + "name": "Intensity", + "features": ["Intensity"] + }, { + "name": "Omnivariance", + "features": ["Omnivariance"] + }, { + "name": "Normals", + "features": ["X Normal", "Y Normal", "Z Normal"] + }, { + "name": "Curvature", + "features": ["Curvature"] + }, { + "name": "Anisotrophy", + "features": ["Anisotrophy"] + }, { + "name": "Sphericity", + "features": ["Sphericity"] + }, { + "name": "Linearity", + "features": ["Linearity"] + }, { + "name": "Planarity ", + "features": ["Planarity"] + }, { + "name": "Eigenentrophy", + "features": ["Eigenentrophy"] + }, { + "name": "XYZ", + "features": ["X", "Y", "Z"] + } + ] +} diff --git a/evaltest2/del/combo-features.json b/evaltest2/del/combo-features.json new file mode 100644 index 0000000..9da1f91 --- /dev/null +++ b/evaltest2/del/combo-features.json @@ -0,0 +1,67 @@ +{ + "scans": [ + { + "path": "/home/rickert/testdata/featureeval/noise.ccp", + "targetLayerName": "noise", + "resultSelection": 0 + }, + { + "path": "/home/rickert/testdata/featureeval/people_facades_ground.ccp", + "targetLayerName": "people", + "resultSelection": 1 + }, + { + "path": "/home/rickert/testdata/featureeval/tools.ccp", + "targetLayerName": "tools", + "resultSelection": 0 + }, + { + "path": "/home/rickert/testdata/featureeval/tree_ground-facade.ccp", + "targetLayerName": "New Layer 37", + "resultSelection": 1 + } + ], + "defaults": { + "downsample": 0.02, + "curvature_radius": 0.3, + "pca_radius": 0.2, + "density_radius": 0.2, + "pca_max_nn": 1000, + "tree_count": 100, + "tree_depth": 10 + }, + "tests": [ + { + "name": "Principal curvatures + Eigenvalues", + "features": ["Curvature 1", "Curvature 2", "Eigen 1", "Eigen 2", "Eigen 3"] + }, { + "name": "Principal curvatures + Eigenvalues + Intensity", + "features": ["Curvature 1", "Curvature 2", "Eigen 1", "Eigen 2", "Eigen 3", "Intensity"] + }, { + "name": "Principal curvatures + Eigenvalues + Intensity + Omnivariance", + "features": ["Curvature 1", "Curvature 2", "Eigen 1", "Eigen 2", "Eigen 3", "Intensity", "Omnivariance"] + }, { + "name": "Principal curvatures + Eigenvalues + Intensity + Omnivariance + Normals", + "features": ["Curvature 1", "Curvature 2", "Eigen 1", "Eigen 2", "Eigen 3", "Intensity", "Omnivariance", "X Normal", "Y Normal", "Z Normal"] + }, { + "name": "Principal curvatures + Eigenvalues + Intensity + Omnivariance + Normals + Curvature", + "features": ["Curvature 1", "Curvature 2", "Eigen 1", "Eigen 2", "Eigen 3", "Intensity", "Omnivariance", "X Normal", "Y Normal", "Z Normal", "Curvature"] + }, { + "name": "Principal curvatures + Eigenvalues + Intensity + Omnivariance + Normals + Curvature + Anisotrophy", + "features": ["Curvature 1", "Curvature 2", "Eigen 1", "Eigen 2", "Eigen 3", "Intensity", "Omnivariance", "X Normal", "Y Normal", "Z Normal", "Curvature", "Anisotrophy"] + }, { + "name": "Principal curvatures + Eigenvalues + Intensity + Omnivariance + Normals + Curvature + Anisotrophy + Sphericity", + "features": ["Curvature 1", "Curvature 2", "Eigen 1", "Eigen 2", "Eigen 3", "Intensity", "Omnivariance", "X Normal", "Y Normal", "Z Normal", "Curvature", "Anisotrophy", "Sphericity"] + }, { + "name": "Principal curvatures + Eigenvalues + Intensity + Omnivariance + Normals + Curvature + Anisotrophy + Sphericity + Linearity", + "features": ["Curvature 1", "Curvature 2", "Eigen 1", "Eigen 2", "Eigen 3", "Intensity", "Omnivariance", "X Normal", "Y Normal", "Z Normal", "Curvature", "Anisotrophy", "Sphericity", "Linearity"] + }, { + "name": "Principal curvatures + Eigenvalues + Intensity + Omnivariance + Normals + Curvature + Anisotrophy + Sphericity + Linearity + Planarity", + "features": ["Curvature 1", "Curvature 2", "Eigen 1", "Eigen 2", "Eigen 3", "Intensity", "Omnivariance", "X Normal", "Y Normal", "Z Normal", "Curvature", "Anisotrophy", "Sphericity", "Linearity", "Planarity"] + }, { + "name": "Principal curvatures + Eigenvalues + Intensity + Omnivariance + Normals + Curvature + Anisotrophy + Sphericity + Linearity + Planarity + Eigenentrophy", + "features": ["Curvature 1", "Curvature 2", "Eigen 1", "Eigen 2", "Eigen 3", "Intensity", "Omnivariance", "X Normal", "Y Normal", "Z Normal", "Curvature", "Anisotrophy", "Sphericity", "Linearity", "Planarity"] + } + + ] +} diff --git a/evaltest2/downsample-features.json b/evaltest2/downsample-features.json new file mode 100644 index 0000000..173a820 --- /dev/null +++ b/evaltest2/downsample-features.json @@ -0,0 +1,257 @@ +{ + "scans": [ + { + "path": "/home/rickert/testdata/featureeval/noise.ccp", + "targetLayerName": "noise", + "resultSelection": 0 + }, + { + "path": "/home/rickert/testdata/featureeval/people_facades_ground.ccp", + "targetLayerName": "people", + "resultSelection": 1 + }, + { + "path": "/home/rickert/testdata/featureeval/tools.ccp", + "targetLayerName": "tools", + "resultSelection": 0 + }, + { + "path": "/home/rickert/testdata/featureeval/tree_ground-facade.ccp", + "targetLayerName": "New Layer 37", + "resultSelection": 1 + } + ], + "defaults": { + "downsample": 0.02, + "curvature_radius": 0.3, + "pca_radius": 0.2, + "density_radius": 0.2, + "pca_max_nn": 1000, + "tree_count": 100, + "tree_depth": 10, + "tree_counter_threshold": 140, + "tree_random_tests": 20 + }, + "tests": [ + + { + "name": "Eigenvalues dr=0.02", + "features": ["Eigen 1", "Eigen 2", "Eigen 3"], + "downsample": 0.02 + }, { + "name": "Linearity dr=0.02", + "features": ["Linearity"], + "downsample": 0.02 + }, { + "name": "Planarity dr=0.02", + "features": ["Planarity"], + "downsample": 0.02 + }, { + "name": "Sphericity dr=0.02", + "features": ["Sphericity"], + "downsample": 0.02 + }, { + "name": "Anisotrophy dr=0.02", + "features": ["Anisotrophy"], + "downsample": 0.02 + }, { + "name": "Eigenentrophy dr=0.02", + "features": ["Eigenentrophy"], + "downsample": 0.02 + }, { + "name": "Omnivariance dr=0.02", + "features": ["Omnivariance"], + "downsample": 0.02 + }, { + "name": "Principal curvatures dr=0.02", + "features": ["Curvature 1", "Curvature 2"], + "downsample": 0.02 + }, { + "name": "Curvature dr=0.02", + "features": ["Curvature"], + "downsample": 0.02 + }, { + "name": "Distance from origin dr=0.02", + "features": ["Distance from origin"], + "downsample": 0.02 + }, { + "name": "XYZ dr=0.02", + "features": ["X", "Y", "Z"], + "downsample": 0.02 + }, { + "name": "Intensity dr=0.02", + "features": ["Intensity"], + "downsample": 0.02 + }, { + "name": "Normals dr=0.02", + "features": ["X Normal", "Y Normal", "Z Normal"], + "downsample": 0.02 + }, + + + { + "name": "Eigenvalues dr=0.04", + "features": ["Eigen 1", "Eigen 2", "Eigen 3"], + "downsample": 0.04 + }, { + "name": "Linearity dr=0.04", + "features": ["Linearity"], + "downsample": 0.04 + }, { + "name": "Planarity dr=0.04", + "features": ["Planarity"], + "downsample": 0.04 + }, { + "name": "Sphericity dr=0.04", + "features": ["Sphericity"], + "downsample": 0.04 + }, { + "name": "Anisotrophy dr=0.04", + "features": ["Anisotrophy"], + "downsample": 0.04 + }, { + "name": "Eigenentrophy dr=0.04", + "features": ["Eigenentrophy"], + "downsample": 0.04 + }, { + "name": "Omnivariance dr=0.04", + "features": ["Omnivariance"], + "downsample": 0.04 + }, { + "name": "Principal curvatures dr=0.04", + "features": ["Curvature 1", "Curvature 2"], + "downsample": 0.04 + }, { + "name": "Curvature dr=0.04", + "features": ["Curvature"], + "downsample": 0.04 + }, { + "name": "Distance from origin dr=0.04", + "features": ["Distance from origin"], + "downsample": 0.04 + }, { + "name": "XYZ dr=0.04", + "features": ["X", "Y", "Z"], + "downsample": 0.04 + }, { + "name": "Intensity dr=0.04", + "features": ["Intensity"], + "downsample": 0.04 + }, { + "name": "Normals dr=0.04", + "features": ["X Normal", "Y Normal", "Z Normal"], + "downsample": 0.04 + }, + + + { + "name": "Eigenvalues dr=0.06", + "features": ["Eigen 1", "Eigen 2", "Eigen 3"], + "downsample": 0.06 + }, { + "name": "Linearity dr=0.06", + "features": ["Linearity"], + "downsample": 0.06 + }, { + "name": "Planarity dr=0.06", + "features": ["Planarity"], + "downsample": 0.06 + }, { + "name": "Sphericity dr=0.06", + "features": ["Sphericity"], + "downsample": 0.06 + }, { + "name": "Anisotrophy dr=0.06", + "features": ["Anisotrophy"], + "downsample": 0.06 + }, { + "name": "Eigenentrophy dr=0.06", + "features": ["Eigenentrophy"], + "downsample": 0.06 + }, { + "name": "Omnivariance dr=0.06", + "features": ["Omnivariance"], + "downsample": 0.06 + }, { + "name": "Principal curvatures dr=0.06", + "features": ["Curvature 1", "Curvature 2"], + "downsample": 0.06 + }, { + "name": "Curvature dr=0.06", + "features": ["Curvature"], + "downsample": 0.06 + }, { + "name": "Distance from origin dr=0.06", + "features": ["Distance from origin"], + "downsample": 0.06 + }, { + "name": "XYZ dr=0.06", + "features": ["X", "Y", "Z"], + "downsample": 0.06 + }, { + "name": "Intensity dr=0.06", + "features": ["Intensity"], + "downsample": 0.06 + }, { + "name": "Normals dr=0.06", + "features": ["X Normal", "Y Normal", "Z Normal"], + "downsample": 0.06 + }, + + + { + "name": "Eigenvalues dr=0.08", + "features": ["Eigen 1", "Eigen 2", "Eigen 3"], + "downsample": 0.08 + }, { + "name": "Linearity dr=0.08", + "features": ["Linearity"], + "downsample": 0.08 + }, { + "name": "Planarity dr=0.08", + "features": ["Planarity"], + "downsample": 0.08 + }, { + "name": "Sphericity dr=0.08", + "features": ["Sphericity"], + "downsample": 0.08 + }, { + "name": "Anisotrophy dr=0.08", + "features": ["Anisotrophy"], + "downsample": 0.08 + }, { + "name": "Eigenentrophy dr=0.08", + "features": ["Eigenentrophy"], + "downsample": 0.08 + }, { + "name": "Omnivariance dr=0.08", + "features": ["Omnivariance"], + "downsample": 0.08 + }, { + "name": "Principal curvatures dr=0.08", + "features": ["Curvature 1", "Curvature 2"], + "downsample": 0.08 + }, { + "name": "Curvature dr=0.08", + "features": ["Curvature"], + "downsample": 0.08 + }, { + "name": "Distance from origin dr=0.08", + "features": ["Distance from origin"], + "downsample": 0.08 + }, { + "name": "XYZ dr=0.08", + "features": ["X", "Y", "Z"], + "downsample": 0.08 + }, { + "name": "Intensity dr=0.08", + "features": ["Intensity"], + "downsample": 0.08 + }, { + "name": "Normals dr=0.08", + "features": ["X Normal", "Y Normal", "Z Normal"], + "downsample": 0.08 + } + + ] +} diff --git a/evaltest2/features.json b/evaltest2/features.json new file mode 100644 index 0000000..aaca69e --- /dev/null +++ b/evaltest2/features.json @@ -0,0 +1,192 @@ +{ + "scans": [ + { + "path": "/home/rickert/testdata/featureeval/noise.ccp", + "targetLayerName": "noise", + "resultSelection": 0 + }, + { + "path": "/home/rickert/testdata/featureeval/people_facades_ground.ccp", + "targetLayerName": "people", + "resultSelection": 1 + }, + { + "path": "/home/rickert/testdata/featureeval/tools.ccp", + "targetLayerName": "tools", + "resultSelection": 0 + }, + { + "path": "/home/rickert/testdata/featureeval/tree_ground-facade.ccp", + "targetLayerName": "New Layer 37", + "resultSelection": 1 + } + ], + "defaults": { + "downsample": 0.02, + "curvature_radius": 0.2, + "pca_radius": 0.2, + "density_radius": 0.2, + "pca_max_nn": 1000, + "tree_count": 100, + "tree_depth": 10, + "tree_counter_threshold": 140, + "tree_random_tests": 20 + }, + "tests": [{ + "name": "Eigenvalues r=0.1", + "features": ["Eigen 1", "Eigen 2", "Eigen 3"], + "pca_radius": 0.1 + }, { + "name": "Eigenvalues r=0.2", + "features": ["Eigen 1", "Eigen 2", "Eigen 3"], + "pca_radius": 0.2 + }, { + "name": "Eigenvalues r=0.3", + "features": ["Eigen 1", "Eigen 2", "Eigen 3"], + "pca_radius": 0.3 + }, { + "name": "Eigenvalues r=0.4", + "features": ["Eigen 1", "Eigen 2", "Eigen 3"], + "pca_radius": 0.4 + }, { + "name": "Linearity r=0.10", + "features": ["Linearity"], + "pca_radius": 0.1 + }, { + "name": "Linearity r=0.2", + "features": ["Linearity"], + "pca_radius": 0.2 + }, { + "name": "Linearity r=0.3", + "features": ["Linearity"], + "pca_radius": 0.3 + }, { + "name": "Linearity r=0.4", + "features": ["Linearity"], + "pca_radius": 0.4 + }, { + "name": "Planarity r=0.1", + "features": ["Planarity"], + "pca_radius": 0.1 + }, { + "name": "Planarity r=0.2", + "features": ["Planarity"], + "pca_radius": 0.2 + }, { + "name": "Planarity r=0.3", + "features": ["Planarity"], + "pca_radius": 0.3 + }, { + "name": "Planarity r=0.4", + "features": ["Planarity"], + "pca_radius": 0.4 + }, { + "name": "Sphericity r=0.1", + "features": ["Sphericity"], + "pca_radius": 0.1 + }, { + "name": "Sphericity r=0.2", + "features": ["Sphericity"], + "pca_radius": 0.2 + }, { + "name": "Sphericity r=0.3", + "features": ["Sphericity"], + "pca_radius": 0.3 + }, { + "name": "Sphericity r=0.4", + "features": ["Sphericity"], + "pca_radius": 0.4 + }, { + "name": "Anisotrophy r=0.1", + "features": ["Anisotrophy"], + "pca_radius": 0.1 + }, { + "name": "Anisotrophy r=0.2", + "features": ["Anisotrophy"], + "pca_radius": 0.2 + }, { + "name": "Anisotrophy r=0.3", + "features": ["Anisotrophy"], + "pca_radius": 0.3 + }, { + "name": "Anisotrophy r=0.4", + "features": ["Anisotrophy"], + "pca_radius": 0.4 + }, { + "name": "Eigenentrophy r=0.1", + "features": ["Eigenentrophy"], + "pca_radius": 0.1 + }, { + "name": "Eigenentrophy r=0.2", + "features": ["Eigenentrophy"], + "pca_radius": 0.2 + }, { + "name": "Eigenentrophy r=0.3", + "features": ["Eigenentrophy"], + "pca_radius": 0.3 + }, { + "name": "Eigenentrophy r=0.4", + "features": ["Eigenentrophy"], + "pca_radius": 0.4 + }, { + "name": "Omnivariance r=0.1", + "features": ["Omnivariance"], + "pca_radius": 0.1 + }, { + "name": "Omnivariance r=0.2", + "features": ["Omnivariance"], + "pca_radius": 0.2 + }, { + "name": "Omnivariance r=0.3", + "features": ["Omnivariance"], + "pca_radius": 0.3 + }, { + "name": "Omnivariance r=0.4", + "features": ["Omnivariance"], + "pca_radius": 0.4 + }, { + "name": "Principal curvatures r=0.1", + "features": ["Curvature 1", "Curvature 2"], + "curvature_radius": 0.1 + }, { + "name": "Principal curvatures r=0.2", + "features": ["Curvature 1", "Curvature 2"], + "curvature_radius": 0.25 + }, { + "name": "Principal curvatures r=0.3", + "features": ["Curvature 1", "Curvature 2"], + "curvature_radius": 0.3 + }, { + "name": "Principal curvatures r=0.4", + "features": ["Curvature 1", "Curvature 2"], + "curvature_radius": 0.4 + }, { + "name": "Curvature r=0.1", + "features": ["Curvature"], + "pca_radius": 0.1 + }, { + "name": "Curvature r=0.2", + "features": ["Curvature"], + "pca_radius": 0.2 + }, { + "name": "Curvature r=0.3", + "features": ["Curvature"], + "pca_radius": 0.3 + }, { + "name": "Curvature r=0.4", + "features": ["Curvature"], + "pca_radius": 0.4 + }, { + "name": "Distance from origin", + "features": ["Distance from origin"] + }, { + "name": "XYZ", + "features": ["X", "Y", "Z"] + }, { + "name": "Intensity", + "features": ["Intensity"] + }, { + "name": "Normals", + "features": ["X Normal", "Y Normal", "Z Normal"] + }] +} diff --git a/evaltest2/omit-eigen.json b/evaltest2/omit-eigen.json new file mode 100644 index 0000000..03dcdfa --- /dev/null +++ b/evaltest2/omit-eigen.json @@ -0,0 +1,41 @@ +{ + "scans": [ + { + "path": "/home/rickert/testdata/featureeval/noise.ccp", + "targetLayerName": "noise", + "resultSelection": 0 + }, + { + "path": "/home/rickert/testdata/featureeval/people_facades_ground.ccp", + "targetLayerName": "people", + "resultSelection": 1 + }, + { + "path": "/home/rickert/testdata/featureeval/tools.ccp", + "targetLayerName": "tools", + "resultSelection": 0 + }, + { + "path": "/home/rickert/testdata/featureeval/tree_ground-facade.ccp", + "targetLayerName": "New Layer 37", + "resultSelection": 1 + } + ], + "defaults": { + "downsample": 0.02, + "curvature_radius": 0.2, + "pca_radius": 0.2, + "density_radius": 0.2, + "pca_max_nn": 1000, + "tree_count": 100, + "tree_depth": 10, + "tree_counter_threshold": 140, + "tree_random_tests": 20, + "features": ["X", "Y", "Z", "Curvature 1", "Curvature 2", "Intensity"] + }, + "tests": [ + { + "name": "XYZ + Principal curvatures + Eigenvalues + Intensity" + } + ] +} diff --git a/evaltest2/ordered-features.json b/evaltest2/ordered-features.json new file mode 100644 index 0000000..0950594 --- /dev/null +++ b/evaltest2/ordered-features.json @@ -0,0 +1,74 @@ +{ + "scans": [ + { + "path": "/home/rickert/testdata/featureeval/noise.ccp", + "targetLayerName": "noise", + "resultSelection": 0 + }, + { + "path": "/home/rickert/testdata/featureeval/people_facades_ground.ccp", + "targetLayerName": "people", + "resultSelection": 1 + }, + { + "path": "/home/rickert/testdata/featureeval/tools.ccp", + "targetLayerName": "tools", + "resultSelection": 0 + }, + { + "path": "/home/rickert/testdata/featureeval/tree_ground-facade.ccp", + "targetLayerName": "New Layer 37", + "resultSelection": 1 + } + ], + "defaults": { + "downsample": 0.02, + "curvature_radius": 0.2, + "pca_radius": 0.2, + "density_radius": 0.2, + "pca_max_nn": 1000, + "tree_count": 100, + "tree_depth": 10, + "tree_counter_threshold": 140, + "tree_random_tests": 20 + }, + "tests": [ + { + "name": "XYZ", + "features": ["X", "Y", "Z"] + }, { + "name": "Principal curvatures", + "features": ["Curvature 1", "Curvature 2"] + }, { + "name": "Eigenvalues", + "features": ["Eigen 1", "Eigen 2", "Eigen 3"] + }, { + "name": "Intensity", + "features": ["Intensity"] + }, { + "name": "Omnivariance", + "features": ["Omnivariance"] + }, { + "name": "Normals", + "features": ["X Normal", "Y Normal", "Z Normal"] + }, { + "name": "Curvature", + "features": ["Curvature"] + }, { + "name": "Anisotrophy", + "features": ["Anisotrophy"] + }, { + "name": "Sphericity", + "features": ["Sphericity"] + }, { + "name": "Linearity", + "features": ["Linearity"] + }, { + "name": "Planarity", + "features": ["Planarity"] + }, { + "name": "Eigenentrophy", + "features": ["Eigenentrophy"] + } + ] +} diff --git a/evaltest2/ordered-features2.json b/evaltest2/ordered-features2.json new file mode 100644 index 0000000..0950594 --- /dev/null +++ b/evaltest2/ordered-features2.json @@ -0,0 +1,74 @@ +{ + "scans": [ + { + "path": "/home/rickert/testdata/featureeval/noise.ccp", + "targetLayerName": "noise", + "resultSelection": 0 + }, + { + "path": "/home/rickert/testdata/featureeval/people_facades_ground.ccp", + "targetLayerName": "people", + "resultSelection": 1 + }, + { + "path": "/home/rickert/testdata/featureeval/tools.ccp", + "targetLayerName": "tools", + "resultSelection": 0 + }, + { + "path": "/home/rickert/testdata/featureeval/tree_ground-facade.ccp", + "targetLayerName": "New Layer 37", + "resultSelection": 1 + } + ], + "defaults": { + "downsample": 0.02, + "curvature_radius": 0.2, + "pca_radius": 0.2, + "density_radius": 0.2, + "pca_max_nn": 1000, + "tree_count": 100, + "tree_depth": 10, + "tree_counter_threshold": 140, + "tree_random_tests": 20 + }, + "tests": [ + { + "name": "XYZ", + "features": ["X", "Y", "Z"] + }, { + "name": "Principal curvatures", + "features": ["Curvature 1", "Curvature 2"] + }, { + "name": "Eigenvalues", + "features": ["Eigen 1", "Eigen 2", "Eigen 3"] + }, { + "name": "Intensity", + "features": ["Intensity"] + }, { + "name": "Omnivariance", + "features": ["Omnivariance"] + }, { + "name": "Normals", + "features": ["X Normal", "Y Normal", "Z Normal"] + }, { + "name": "Curvature", + "features": ["Curvature"] + }, { + "name": "Anisotrophy", + "features": ["Anisotrophy"] + }, { + "name": "Sphericity", + "features": ["Sphericity"] + }, { + "name": "Linearity", + "features": ["Linearity"] + }, { + "name": "Planarity", + "features": ["Planarity"] + }, { + "name": "Eigenentrophy", + "features": ["Eigenentrophy"] + } + ] +} diff --git a/evaltest2/time-test.json b/evaltest2/time-test.json new file mode 100644 index 0000000..c6f4562 --- /dev/null +++ b/evaltest2/time-test.json @@ -0,0 +1,53 @@ +{ + "scans": [ + { + "path": "/home/rickert/testdata/featureeval/noise.ccp", + "targetLayerName": "noise", + "resultSelection": 0 + } + ], + "defaults": { + "downsample": 0.02, + "curvature_radius": 0.2, + "pca_radius": 0.2, + "density_radius": 0.2, + "pca_max_nn": 1000, + "tree_count": 100, + "tree_depth": 10, + "tree_counter_threshold": 140, + "tree_random_tests": 20 + }, + "tests": [{ + "name": "Eigenvalues r=0.1", + "features": ["Eigen 1"], + "pca_radius": 0.1 + }, { + "name": "Eigenvalues r=0.2", + "features": ["Eigen 1"], + "pca_radius": 0.2 + }, { + "name": "Eigenvalues r=0.3", + "features": ["Eigen 1"], + "pca_radius": 0.3 + }, { + "name": "Eigenvalues r=0.4", + "features": ["Eigen 1"], + "pca_radius": 0.4 + }, { + "name": "Principal curvatures r=0.1", + "features": ["Curvature 1"], + "curvature_radius": 0.1 + }, { + "name": "Principal curvatures r=0.2", + "features": ["Curvature 1"], + "curvature_radius": 0.2 + }, { + "name": "Principal curvatures r=0.3", + "features": ["Curvature 1"], + "curvature_radius": 0.3 + }, { + "name": "Principal curvatures r=0.4", + "features": ["Curvature 1"], + "curvature_radius": 0.4 + }] +} diff --git a/evaltest2/timing-test.json b/evaltest2/timing-test.json new file mode 100644 index 0000000..aa35f4d --- /dev/null +++ b/evaltest2/timing-test.json @@ -0,0 +1,78 @@ +{ + "scans": [ + { + "path": "/home/rickert/testdata/featureeval/noise.ccp", + "targetLayerName": "noise", + "resultSelection": 0 + }, + { + "path": "/home/rickert/testdata/featureeval/people_facades_ground.ccp", + "targetLayerName": "people", + "resultSelection": 1 + }, + { + "path": "/home/rickert/testdata/featureeval/tools.ccp", + "targetLayerName": "tools", + "resultSelection": 0 + }, + { + "path": "/home/rickert/testdata/featureeval/tree_ground-facade.ccp", + "targetLayerName": "New Layer 37", + "resultSelection": 1 + } + ], + "defaults": { + "downsample": 0.02, + "curvature_radius": 0.2, + "pca_radius": 0.2, + "density_radius": 0.2, + "pca_max_nn": 1000, + "tree_count": 64, + "tree_depth": 8, + "tree_counter_threshold": 140, + "tree_random_tests": 16, + "features": ["X", "Y", "Z", "Curvature 1", "Curvature 2", "Intensity"] + }, + "tests": [ + + { + "name": "Current" + }, + + { + "name": "Downsample 0.03", + "downsample": 0.03 + }, + + { + "name": "Downsample 0.04", + "downsample": 0.04 + }, + + { + "name": "Downsample 0.05", + "downsample": 0.05 + }, + + { + "name": "Downsample 0.06", + "downsample": 0.06 + }, + + { + "name": "Tree count 32", + "tree_count": 32 + }, + + { + "name": "Tree count 16", + "tree_count": 16 + }, + + { + "name": "Tree count 8", + "tree_count": 8 + } + + ] +} diff --git a/evaltest2/treetest.json b/evaltest2/treetest.json new file mode 100644 index 0000000..44fe2c2 --- /dev/null +++ b/evaltest2/treetest.json @@ -0,0 +1,151 @@ +{ + "scans": [ + { + "path": "/home/rickert/testdata/featureeval/noise.ccp", + "targetLayerName": "noise", + "resultSelection": 0 + }, + { + "path": "/home/rickert/testdata/featureeval/people_facades_ground.ccp", + "targetLayerName": "people", + "resultSelection": 1 + }, + { + "path": "/home/rickert/testdata/featureeval/tools.ccp", + "targetLayerName": "tools", + "resultSelection": 0 + }, + { + "path": "/home/rickert/testdata/featureeval/tree_ground-facade.ccp", + "targetLayerName": "New Layer 37", + "resultSelection": 1 + } + ], + "defaults": { + "downsample": 0.02, + "curvature_radius": 0.2, + "pca_radius": 0.2, + "density_radius": 0.2, + "pca_max_nn": 1000, + "tree_count": 100, + "tree_depth": 10, + "tree_counter_threshold": 140, + "tree_random_tests": 20, + "features": ["X", "Y", "Z", "Curvature 1", "Curvature 2", "Intensity"] + }, + "tests": [ + { + "name": "Trees 100 Depth 1", + "tree_count": 100, + "tree_depth": 1 + }, { + "name": "Trees 100 Depth 2", + "tree_count": 100, + "tree_depth": 2 + }, { + "name": "Trees 100 Depth 4", + "tree_count": 100, + "tree_depth": 4 + }, { + "name": "Trees 100 Depth 8", + "tree_count": 100, + "tree_depth": 8 + }, { + "name": "Trees 100 Depth 16", + "tree_count": 100, + "tree_depth": 6 + }, { + "name": "Trees 100 Depth 32", + "tree_count": 100, + "tree_depth": 6 + }, { + "name": "Trees 100 Depth 64", + "tree_count": 100, + "tree_depth": 6 + }, { + "name": "Trees 10 Depth 10", + "tree_count": 10, + "tree_depth": 10 + }, { + "name": "Trees 1 Depth 10", + "tree_count": 10, + "tree_depth": 10 + }, { + "name": "Trees 2 Depth 10", + "tree_count": 10, + "tree_depth": 10 + }, { + "name": "Trees 4 Depth 10", + "tree_count": 4, + "tree_depth": 10 + }, { + "name": "Trees 8 Depth 10", + "tree_count": 8, + "tree_depth": 10 + }, { + "name": "Trees 16 Depth 10", + "tree_count": 16, + "tree_depth": 10 + }, { + "name": "Trees 32 Depth 10", + "tree_count": 32, + "tree_depth": 10 + }, { + "name": "Trees 64 Depth 10", + "tree_count": 64, + "tree_depth": 10 + }, { + "name": "Trees 128 Depth 10", + "tree_count": 128, + "tree_depth": 10 + }, { + "name": "Trees 256 Depth 10", + "tree_count": 256, + "tree_depth": 10 + }, { + "name": "Trees 512 Depth 10", + "tree_count": 512, + "tree_depth": 10 + }, { + "name": "Trees 1 Depth 8", + "tree_count": 10, + "tree_depth": 8 + }, { + "name": "Trees 2 Depth 8", + "tree_count": 10, + "tree_depth": 8 + }, { + "name": "Trees 4 Depth 8", + "tree_count": 4, + "tree_depth": 8 + }, { + "name": "Trees 8 Depth 8", + "tree_count": 8, + "tree_depth": 8 + }, { + "name": "Trees 16 Depth 8", + "tree_count": 16, + "tree_depth": 8 + }, { + "name": "Trees 32 Depth 8", + "tree_count": 32, + "tree_depth": 8 + }, { + "name": "Trees 64 Depth 8", + "tree_count": 64, + "tree_depth": 8 + }, { + "name": "Trees 128 Depth 8", + "tree_count": 128, + "tree_depth": 8 + }, { + "name": "Trees 256 Depth 8", + "tree_count": 256, + "tree_depth": 8 + }, { + "name": "Trees 512 Depth 8", + "tree_count": 512, + "tree_depth": 8 + } + ] +} diff --git a/evaltest2/treetest2.json b/evaltest2/treetest2.json new file mode 100644 index 0000000..44fe2c2 --- /dev/null +++ b/evaltest2/treetest2.json @@ -0,0 +1,151 @@ +{ + "scans": [ + { + "path": "/home/rickert/testdata/featureeval/noise.ccp", + "targetLayerName": "noise", + "resultSelection": 0 + }, + { + "path": "/home/rickert/testdata/featureeval/people_facades_ground.ccp", + "targetLayerName": "people", + "resultSelection": 1 + }, + { + "path": "/home/rickert/testdata/featureeval/tools.ccp", + "targetLayerName": "tools", + "resultSelection": 0 + }, + { + "path": "/home/rickert/testdata/featureeval/tree_ground-facade.ccp", + "targetLayerName": "New Layer 37", + "resultSelection": 1 + } + ], + "defaults": { + "downsample": 0.02, + "curvature_radius": 0.2, + "pca_radius": 0.2, + "density_radius": 0.2, + "pca_max_nn": 1000, + "tree_count": 100, + "tree_depth": 10, + "tree_counter_threshold": 140, + "tree_random_tests": 20, + "features": ["X", "Y", "Z", "Curvature 1", "Curvature 2", "Intensity"] + }, + "tests": [ + { + "name": "Trees 100 Depth 1", + "tree_count": 100, + "tree_depth": 1 + }, { + "name": "Trees 100 Depth 2", + "tree_count": 100, + "tree_depth": 2 + }, { + "name": "Trees 100 Depth 4", + "tree_count": 100, + "tree_depth": 4 + }, { + "name": "Trees 100 Depth 8", + "tree_count": 100, + "tree_depth": 8 + }, { + "name": "Trees 100 Depth 16", + "tree_count": 100, + "tree_depth": 6 + }, { + "name": "Trees 100 Depth 32", + "tree_count": 100, + "tree_depth": 6 + }, { + "name": "Trees 100 Depth 64", + "tree_count": 100, + "tree_depth": 6 + }, { + "name": "Trees 10 Depth 10", + "tree_count": 10, + "tree_depth": 10 + }, { + "name": "Trees 1 Depth 10", + "tree_count": 10, + "tree_depth": 10 + }, { + "name": "Trees 2 Depth 10", + "tree_count": 10, + "tree_depth": 10 + }, { + "name": "Trees 4 Depth 10", + "tree_count": 4, + "tree_depth": 10 + }, { + "name": "Trees 8 Depth 10", + "tree_count": 8, + "tree_depth": 10 + }, { + "name": "Trees 16 Depth 10", + "tree_count": 16, + "tree_depth": 10 + }, { + "name": "Trees 32 Depth 10", + "tree_count": 32, + "tree_depth": 10 + }, { + "name": "Trees 64 Depth 10", + "tree_count": 64, + "tree_depth": 10 + }, { + "name": "Trees 128 Depth 10", + "tree_count": 128, + "tree_depth": 10 + }, { + "name": "Trees 256 Depth 10", + "tree_count": 256, + "tree_depth": 10 + }, { + "name": "Trees 512 Depth 10", + "tree_count": 512, + "tree_depth": 10 + }, { + "name": "Trees 1 Depth 8", + "tree_count": 10, + "tree_depth": 8 + }, { + "name": "Trees 2 Depth 8", + "tree_count": 10, + "tree_depth": 8 + }, { + "name": "Trees 4 Depth 8", + "tree_count": 4, + "tree_depth": 8 + }, { + "name": "Trees 8 Depth 8", + "tree_count": 8, + "tree_depth": 8 + }, { + "name": "Trees 16 Depth 8", + "tree_count": 16, + "tree_depth": 8 + }, { + "name": "Trees 32 Depth 8", + "tree_count": 32, + "tree_depth": 8 + }, { + "name": "Trees 64 Depth 8", + "tree_count": 64, + "tree_depth": 8 + }, { + "name": "Trees 128 Depth 8", + "tree_count": 128, + "tree_depth": 8 + }, { + "name": "Trees 256 Depth 8", + "tree_count": 256, + "tree_depth": 8 + }, { + "name": "Trees 512 Depth 8", + "tree_count": 512, + "tree_depth": 8 + } + ] +} diff --git a/evaltest2/treetest4.json b/evaltest2/treetest4.json new file mode 100644 index 0000000..09ecbc3 --- /dev/null +++ b/evaltest2/treetest4.json @@ -0,0 +1,71 @@ +{ + "scans": [ + { + "path": "/home/rickert/testdata/featureeval/noise.ccp", + "targetLayerName": "noise", + "resultSelection": 0 + }, + { + "path": "/home/rickert/testdata/featureeval/people_facades_ground.ccp", + "targetLayerName": "people", + "resultSelection": 1 + }, + { + "path": "/home/rickert/testdata/featureeval/tools.ccp", + "targetLayerName": "tools", + "resultSelection": 0 + }, + { + "path": "/home/rickert/testdata/featureeval/tree_ground-facade.ccp", + "targetLayerName": "New Layer 37", + "resultSelection": 1 + } + ], + "defaults": { + "downsample": 0.02, + "curvature_radius": 0.2, + "pca_radius": 0.2, + "density_radius": 0.2, + "pca_max_nn": 1000, + "tree_count": 100, + "tree_depth": 10, + "tree_counter_threshold": 140, + "tree_random_tests": 20, + "features": ["X", "Y", "Z", "Curvature 1", "Curvature 2", "Intensity"] + }, + "tests": [ + { + "name": "Trees 8 Depth 1", + "tree_count": 8, + "tree_depth": 1 + }, { + "name": "Trees 8 Depth 2", + "tree_count": 8, + "tree_depth": 2 + }, { + "name": "Trees 8 Depth 4", + "tree_count": 8, + "tree_depth": 4 + }, { + "name": "Trees 8 Depth 8", + "tree_count": 8, + "tree_depth": 8 + }, { + "name": "Trees 8 Depth 16", + "tree_count": 8, + "tree_depth": 16 + }, { + "name": "Trees 8 Depth 32", + "tree_count": 8, + "tree_depth": 32 + }, { + "name": "Trees 8 Depth 8", + "tree_count": 8, + "tree_depth": 8 + }, { + "name": "Trees 8 Depth 128", + "tree_count": 8, + "tree_depth": 128 + } + ] +} diff --git a/evaltest2/treetest5.json b/evaltest2/treetest5.json new file mode 100644 index 0000000..cbe6943 --- /dev/null +++ b/evaltest2/treetest5.json @@ -0,0 +1,66 @@ +{ + "scans": [ + { + "path": "/home/rickert/testdata/featureeval/noise.ccp", + "targetLayerName": "noise", + "resultSelection": 0 + }, + { + "path": "/home/rickert/testdata/featureeval/people_facades_ground.ccp", + "targetLayerName": "people", + "resultSelection": 1 + }, + { + "path": "/home/rickert/testdata/featureeval/tools.ccp", + "targetLayerName": "tools", + "resultSelection": 0 + }, + { + "path": "/home/rickert/testdata/featureeval/tree_ground-facade.ccp", + "targetLayerName": "New Layer 37", + "resultSelection": 1 + } + ], + "defaults": { + "downsample": 0.02, + "curvature_radius": 0.2, + "pca_radius": 0.2, + "density_radius": 0.2, + "pca_max_nn": 1000, + "tree_count": 64, + "tree_depth": 16, + "tree_counter_threshold": 140, + "tree_random_tests": 20, + "features": ["X", "Y", "Z", "Curvature 1", "Curvature 2", "Intensity"] + }, + "tests": [ + { + "name": "1 tests", + "tree_random_tests": 1 + }, { + "name": "2 tests", + "tree_random_tests": 2 + }, { + "name": "4 tests", + "tree_random_tests": 4 + }, { + "name": "8 tests", + "tree_random_tests": 8 + }, { + "name": "16 tests", + "tree_random_tests": 16 + }, { + "name": "32 tests", + "tree_random_tests": 32 + }, { + "name": "64 tests", + "tree_random_tests": 64 + }, { + "name": "128 tests", + "tree_random_tests": 128 + }, { + "name": "256 tests", + "tree_random_tests": 256 + } + ] +} diff --git a/evaltest2/treetest6.json b/evaltest2/treetest6.json new file mode 100644 index 0000000..c43faf5 --- /dev/null +++ b/evaltest2/treetest6.json @@ -0,0 +1,69 @@ +{ + "scans": [ + { + "path": "/home/rickert/testdata/featureeval/noise.ccp", + "targetLayerName": "noise", + "resultSelection": 0 + }, + { + "path": "/home/rickert/testdata/featureeval/people_facades_ground.ccp", + "targetLayerName": "people", + "resultSelection": 1 + }, + { + "path": "/home/rickert/testdata/featureeval/tools.ccp", + "targetLayerName": "tools", + "resultSelection": 0 + }, + { + "path": "/home/rickert/testdata/featureeval/tree_ground-facade.ccp", + "targetLayerName": "New Layer 37", + "resultSelection": 1 + } + ], + "defaults": { + "downsample": 0.02, + "curvature_radius": 0.2, + "pca_radius": 0.2, + "density_radius": 0.2, + "pca_max_nn": 1000, + "tree_count": 64, + "tree_depth": 16, + "tree_counter_threshold": 140, + "tree_random_tests": 16, + "features": ["X", "Y", "Z", "Curvature 1", "Curvature 2", "Intensity"] + }, + "tests": [ + { + "name": "1", + "tree_counter_threshold": 1 + }, { + "name": "2", + "tree_counter_threshold": 2 + }, { + "name": "4", + "tree_counter_threshold": 4 + }, { + "name": "8", + "tree_counter_threshold": 8 + }, { + "name": "16", + "tree_counter_threshold": 16 + }, { + "name": "32", + "tree_counter_threshold": 32 + }, { + "name": "64", + "tree_counter_threshold": 64 + }, { + "name": "128", + "tree_counter_threshold": 128 + }, { + "name": "256", + "tree_counter_threshold": 256 + }, { + "name": "512", + "tree_counter_threshold": 512 + } + ] +} diff --git a/evaltest2/treetest7.json b/evaltest2/treetest7.json new file mode 100644 index 0000000..1d5fc8a --- /dev/null +++ b/evaltest2/treetest7.json @@ -0,0 +1,143 @@ +{ + "scans": [ + { + "path": "/home/rickert/testdata/featureeval/noise.ccp", + "targetLayerName": "noise", + "resultSelection": 0 + }, + { + "path": "/home/rickert/testdata/featureeval/people_facades_ground.ccp", + "targetLayerName": "people", + "resultSelection": 1 + }, + { + "path": "/home/rickert/testdata/featureeval/tools.ccp", + "targetLayerName": "tools", + "resultSelection": 0 + }, + { + "path": "/home/rickert/testdata/featureeval/tree_ground-facade.ccp", + "targetLayerName": "New Layer 37", + "resultSelection": 1 + } + ], + "defaults": { + "downsample": 0.02, + "curvature_radius": 0.2, + "pca_radius": 0.2, + "density_radius": 0.2, + "pca_max_nn": 1000, + "tree_count": 64, + "tree_depth": 16, + "tree_counter_threshold": 140, + "tree_random_tests": 16, + "features": ["X", "Y", "Z", "Curvature 1", "Curvature 2", "Intensity"] + }, + "tests": [ + + { + "name": "tree_counter_threshold 1", + "tree_counter_threshold": 1 + }, { + "name": "tree_counter_threshold 12", + "tree_counter_threshold": 2 + }, { + "name": "tree_counter_threshold 14", + "tree_counter_threshold": 4 + }, { + "name": "tree_counter_threshold 8", + "tree_counter_threshold": 8 + }, { + "name": "tree_counter_threshold 16", + "tree_counter_threshold": 16 + }, { + "name": "tree_counter_threshold 32", + "tree_counter_threshold": 32 + }, { + "name": "tree_counter_threshold 64", + "tree_counter_threshold": 64 + }, { + "name": "tree_counter_threshold 128", + "tree_counter_threshold": 128 + }, { + "name": "tree_counter_threshold 256", + "tree_counter_threshold": 256 + }, { + "name": "tree_counter_threshold 512", + "tree_counter_threshold": 512 + }, { + "name": "tree_counter_threshold 1024", + "tree_counter_threshold": 1024 + }, { + "name": "tree_counter_threshold 2048", + "tree_counter_threshold": 2048 + }, + + + { + "name": "1 tests", + "tree_random_tests": 1 + }, { + "name": "2 tests", + "tree_random_tests": 2 + }, { + "name": "4 tests", + "tree_random_tests": 4 + }, { + "name": "8 tests", + "tree_random_tests": 8 + }, { + "name": "16 tests", + "tree_random_tests": 16 + }, { + "name": "32 tests", + "tree_random_tests": 32 + }, { + "name": "64 tests", + "tree_random_tests": 64 + }, { + "name": "128 tests", + "tree_random_tests": 128 + }, { + "name": "256 tests", + "tree_random_tests": 256 + }, + + + { + "name": "Trees 64 Depth 1", + "tree_count": 64, + "tree_depth": 1 + }, { + "name": "Trees 64 Depth 2", + "tree_count": 64, + "tree_depth": 2 + }, { + "name": "Trees 64 Depth 4", + "tree_count": 64, + "tree_depth": 4 + }, { + "name": "Trees 64 Depth 8", + "tree_count": 64, + "tree_depth": 8 + }, { + "name": "Trees 64 Depth 16", + "tree_count": 64, + "tree_depth": 16 + }, { + "name": "Trees 64 Depth 32", + "tree_count": 64, + "tree_depth": 32 + }, { + "name": "Trees 64 Depth 64", + "tree_count": 64, + "tree_depth": 64 + }, { + "name": "Trees 64 Depth 128", + "tree_count": 64, + "tree_depth": 128 + } + + + ] +} diff --git a/plugintool/README.md b/plugintool/README.md index e69de29..34db9a5 100755 --- a/plugintool/README.md +++ b/plugintool/README.md @@ -0,0 +1,18 @@ +Install: +-------- + +python plugintool/setup.py develop + +Usage: +------ + +cd cloudclean/src/plugins +createplugin MyPluginName filter + +or + +createplugin MyPluginName interactive + +Finally: +-------- +Update cloudclean/src/plugins/CMakeLists.txt to include "mypluginname" diff --git a/scansubsample/subsample b/scansubsample/subsample new file mode 100755 index 0000000..c05a0ae Binary files /dev/null and b/scansubsample/subsample differ diff --git a/scansubsample/subsample.cpp b/scansubsample/subsample.cpp new file mode 100755 index 0000000..8b690be --- /dev/null +++ b/scansubsample/subsample.cpp @@ -0,0 +1,164 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define IS_NAN(num) (num!=num) + + +void resize_ptx(const char* filename, const char* out_filename, int factor, bool discard_reg = false){ + int width = -1; + int height = -1; + std::string tmp; + std::string tmp_str; + + // Makes things faster apparently + //std::cin.sync_with_stdio(false); + std::ifstream ptx_file(filename, std::ios_base::binary); + assert(ptx_file.is_open()); + std::ofstream out_ptx_file(out_filename); + assert(out_ptx_file.is_open()); + + // Dimentions + ptx_file >> width; + ptx_file >> height; + out_ptx_file << width/factor << std::endl; + out_ptx_file << height/factor << std::endl; + + if (discard_reg) { + + for(int i = 0; i < 28; i++){ + ptx_file >> tmp; + } + + out_ptx_file << 0 << " " << 0 << " "<< 0 << std::endl; + + out_ptx_file << 1 << " " << 0 << " "<< 0 << std::endl; + out_ptx_file << 0 << " " << 1 << " "<< 0 << std::endl; + out_ptx_file << 0 << " " << 0 << " "<< 1 << std::endl; + + out_ptx_file << 1 << " " << 0 << " "<< 0 << " "<< 0 << std::endl; + out_ptx_file << 0 << " " << 1 << " "<< 0 << " "<< 0 << std::endl; + out_ptx_file << 0 << " " << 0 << " "<< 1 << " "<< 0 << std::endl; + out_ptx_file << 0 << " " << 0 << " "<< 0 << " "<< 1 << std::endl; + + } else { + + // Camera offset + for(int i = 0; i < 3; i++){ + ptx_file >> tmp; + out_ptx_file << tmp << (i == 3 ? "": " "); + } + + + out_ptx_file << std::endl; + + for(int i = 0; i < 9; i++){ + ptx_file >> tmp; + out_ptx_file << tmp; + if((i+1) % 3 != 0) { + out_ptx_file << " "; + } else { + out_ptx_file << std::endl; + } + } + + for(int i = 0; i < 16; i++){ + ptx_file >> tmp; + out_ptx_file << tmp; + if((i+1) % 4 != 0) { + out_ptx_file << " "; + } else { + out_ptx_file << std::endl; + } + } + + } + + + ptx_file >> std::ws; + + // Read points + std::string line; + std::string x, y, z, intensity; + std::string r, g, b; + + // Determine format + getline( ptx_file, line); + int tokens = 1; + for(int i = 0; i< line.length(); i++){ + if(line[i] == ' ') tokens++; + } + + // Read first line + std::stringstream ss(std::stringstream::in | std::stringstream::out); + ss << line; + ss >> x >> y >> z >> intensity; + + if(tokens == 7){ + ss >> r >> g >> b; + // Write first line + out_ptx_file << x << " " << y << " " << z << " " << intensity << " " << r << " " << g << " " << b << std::endl; + } else { + // Write first line + out_ptx_file << x << " " << y << " " << z << " " << intensity << std::endl; + } + + + + const int status_interval = width*height/100; + + for(int i = 1; i < width*height; i++){ + + if(tokens == 7){ + ptx_file >> x >> y >> z >> intensity >> r >> g >> b; + } else { + ptx_file >> x >> y >> z >> intensity; + } + + if(i % status_interval == 0){ + printf("%0.f percent done\n", (100.0*i)/(width*height)); + } + + int iy = i%height; + int ix = i/height; + + if((iy+1)%factor != 0) + continue; + if((ix+1)%factor != 0) + continue; + + // WRITE OUT + + if(tokens == 7){ + out_ptx_file << x << " " << y << " " << z << " " << intensity << " " << r << " " << g << " " << b << std::endl; + } else { + out_ptx_file << x << " " << y << " " << z << " " << intensity << std::endl; + } + } + + ptx_file.close(); + out_ptx_file.close(); + +} + + +int main(int argc, char**argv){ + assert(argc > 3 && "Too few pareters.\n Usage: ./subsample in.ptx out.ptx factor [noreg]"); + + const char* in_file_name = argv[1]; + const char* out_file_name = argv[2]; + int factor = atoi(argv[3]); + + bool discard_reg = argc == 5 && std::string(argv[4]) == std::string("noreg"); + + resize_ptx(in_file_name, out_file_name, factor, discard_reg); +} diff --git a/src/gui/cloudgldata.cpp b/src/gui/cloudgldata.cpp index 388139a..5c6a395 100755 --- a/src/gui/cloudgldata.cpp +++ b/src/gui/cloudgldata.cpp @@ -19,9 +19,21 @@ CloudGLData::CloudGLData(boost::shared_ptr pc) { point_buffer_->setUsagePattern(QGLBuffer::StreamDraw); point_buffer_->create(); CE(); point_buffer_->bind(); CE(); - size_t vb_size = sizeof(pcl::PointXYZI)*pc->size(); + size_t vb_size = 4*4*pc->size(); point_buffer_->allocate(vb_size); CE(); point_buffer_->release(); CE(); + + + // Color buffer setup + + color_buffer_.reset(new QGLBuffer(QGLBuffer::VertexBuffer)); CE(); + color_buffer_->setUsagePattern(QGLBuffer::StreamDraw); + color_buffer_->create(); CE(); + color_buffer_->bind(); CE(); + size_t cb_size = 3*pc->size(); + color_buffer_->allocate(cb_size); CE(); + color_buffer_->release(); CE(); + // // Label buffer setup // @@ -69,45 +81,9 @@ CloudGLData::~CloudGLData() { this, SLOT(syncLabels(boost::shared_ptr >))); } -/* -void CloudGLData::setVAO(GLuint vao){ - glBindVertexArray(vao); - - // Point buffer - point_buffer_->bind(); CE(); - glEnableVertexAttribArray(0); CE(); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float)*4, 0); CE(); - glEnableVertexAttribArray(1); CE(); - int offset = sizeof(float)*3; - glVertexAttribPointer(1, 1, GL_FLOAT, GL_FALSE, sizeof(float)*4, - reinterpret_cast(offset)); CE(); - point_buffer_->release(); CE(); - - // Label buffer - label_buffer_->bind(); CE(); - glEnableVertexAttribArray(2); CE(); CE(); - glVertexAttribIPointer(2, 1, GL_SHORT, 0, 0); CE(); - label_buffer_->release(); CE(); - - // Flag buffer - flag_buffer_->bind(); CE(); - glEnableVertexAttribArray(3); CE(); - glVertexAttribIPointer(3, 1, GL_BYTE, 0, 0); CE(); - flag_buffer_->release(); CE(); - - // Grid pos buffer - grid_buffer_->bind(); CE(); - glEnableVertexAttribArray(4); CE(); - glVertexAttribPointer(4, 2, GL_FLOAT, GL_FALSE, 0, 0); CE(); - grid_buffer_->release(); CE(); - - glBindVertexArray(0); -} -*/ - void CloudGLData::copyCloud(){ point_buffer_->bind(); CE(); - size_t vb_size = sizeof(pcl::PointXYZI)*pc_->size(); + size_t vb_size = 4*4*pc_->size(); point_buffer_->allocate(vb_size); CE(); float * pointbuff = static_cast(glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY)); CE(); @@ -116,17 +92,28 @@ void CloudGLData::copyCloud(){ pointbuff[i*4] = (*pc_)[i].x; pointbuff[i*4+1] = (*pc_)[i].y; pointbuff[i*4+2] = (*pc_)[i].z; - pointbuff[i*4+3] = (*pc_)[i].intensity; + pointbuff[i*4+3] = (*pc_)[i].data[3]; } glUnmapBuffer(GL_ARRAY_BUFFER); + point_buffer_->release(); CE(); -// for(uint i = 0; i < pc_->size(); i++) { -// point_buffer_->write(i*sizeof(float)*4, (*pc_)[i].data, sizeof(float)*3); -// point_buffer_->write(i*sizeof(float)*4, &((*pc_)[i].intensity), sizeof(float)); -// } - point_buffer_->release(); CE(); + // Color data + color_buffer_->bind(); CE(); + size_t cb_size = 3*pc_->size(); + color_buffer_->allocate(cb_size); CE(); + uint8_t * colorbuff = + static_cast(glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY)); CE(); + + for(uint i = 0; i < pc_->size(); i++) { + colorbuff[i*3] = (*pc_)[i].r; + colorbuff[i*3+1] = (*pc_)[i].g; + colorbuff[i*3+2] = (*pc_)[i].b; + } + + glUnmapBuffer(GL_ARRAY_BUFFER); + color_buffer_->release(); CE(); } void CloudGLData::copyLabels(){ diff --git a/src/gui/cloudgldata.h b/src/gui/cloudgldata.h index dcd0da4..917bc1d 100755 --- a/src/gui/cloudgldata.h +++ b/src/gui/cloudgldata.h @@ -35,6 +35,7 @@ class GUI_API CloudGLData : public QObject{ boost::shared_ptr pc_; std::unique_ptr label_buffer_; std::unique_ptr point_buffer_; + std::unique_ptr color_buffer_; std::unique_ptr flag_buffer_; std::unique_ptr grid_buffer_; diff --git a/src/gui/cloudlistview.cpp b/src/gui/cloudlistview.cpp index 9a737d7..487512c 100755 --- a/src/gui/cloudlistview.cpp +++ b/src/gui/cloudlistview.cpp @@ -131,6 +131,30 @@ void CloudListView::selectAllPoints(){ us_->endMacro(); } +void CloudListView::countVisible() { + + boost::shared_ptr > hidden_labels = ll_->getHiddenLabels(); + + uint count = 0; + + for(boost::shared_ptr cloud : cl_->clouds_){ + for(uint16_t label : cloud->labels_){ + bool is_visible = true; + for(uint16_t & hlabel : *hidden_labels) { + if (label == hlabel) { + is_visible = false; + } + } + + if (is_visible) { + count++; + } + } + } + + qDebug() << "visible points: " << count; +} + void CloudListView::invertSelection(){ us_->beginMacro("Invert selection"); for(boost::shared_ptr cloud : cl_->clouds_){ diff --git a/src/gui/cloudlistview.h b/src/gui/cloudlistview.h index e309032..4ad8f8a 100755 --- a/src/gui/cloudlistview.h +++ b/src/gui/cloudlistview.h @@ -30,6 +30,7 @@ class CloudListView : public QDockWidget public slots: void deselectAllPoints(); void selectAllPoints(); + void countVisible(); void invertSelection(); private: diff --git a/src/gui/flatview.cpp b/src/gui/flatview.cpp index d3fc6c5..7f6bc23 100755 --- a/src/gui/flatview.cpp +++ b/src/gui/flatview.cpp @@ -338,6 +338,12 @@ void FlatView::paintEvent(QPaintEvent *event) { glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, 0, 0); CE(); cd->grid_buffer_->release(); CE(); + // Color buffer + cd->color_buffer_->bind(); CE(); + glEnableVertexAttribArray(4); CE(); + glVertexAttribPointer(4, 3, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(uint8_t)*3, 0); CE(); + cd->color_buffer_->release(); CE(); + cd->draw(vao_); CE(); glBindVertexArray(0); CE(); diff --git a/src/gui/glwidget.cpp b/src/gui/glwidget.cpp index 9877721..14622c6 100755 --- a/src/gui/glwidget.cpp +++ b/src/gui/glwidget.cpp @@ -248,6 +248,12 @@ void GLWidget::paintEvent(QPaintEvent *event) { glVertexAttribIPointer(3, 1, GL_BYTE, 0, 0); CE(); cd->flag_buffer_->release(); CE(); + // Color buffer + cd->color_buffer_->bind(); CE(); + glEnableVertexAttribArray(4); CE(); + glVertexAttribPointer(4, 3, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(uint8_t)*3, 0); CE(); + cd->color_buffer_->release(); CE(); + glUniformMatrix4fv(uni_modelview_, 1, GL_FALSE, (camera_.modelviewMatrix()*pc->modelview()) .data());CE(); @@ -260,9 +266,6 @@ void GLWidget::paintEvent(QPaintEvent *event) { glBindTexture(GL_TEXTURE_BUFFER, 0); CE(); -// p.endNativePainting(); -// p.end(); - emit pluginPaint(camera_.projectionMatrix(), camera_.modelviewMatrix()); glFinish(); swapBuffers(); diff --git a/src/gui/mainwindow.cpp b/src/gui/mainwindow.cpp index 44c132a..6abb3fb 100755 --- a/src/gui/mainwindow.cpp +++ b/src/gui/mainwindow.cpp @@ -141,14 +141,7 @@ MainWindow::MainWindow(QUndoStack *us, CloudList * cl, LayerList * ll, QWidget * //file_menu_->addAction(save); QAction * reset = new QAction(tr("Reset"), this); - connect(reset, &QAction::triggered, [this](){ - ll_->reset(); - gld_->reloadColorLookupBuffer(); - for(boost::shared_ptr cloud : cl_->clouds_) { - gld_->deleteCloud(cloud); - } - cl_->reset(); - }); + connect(reset, &QAction::triggered, this, &MainWindow::reset); file_menu_->addAction(reset); @@ -342,6 +335,14 @@ MainWindow::~MainWindow() { delete gld_; } +void MainWindow::reset() { + ll_->reset(); + gld_->reloadColorLookupBuffer(); + for(boost::shared_ptr cloud : cl_->clouds_) { + gld_->deleteCloud(cloud); + } + cl_->reset(); +} void MainWindow::setSelectMask(uint8_t mask){ int pos = 0; @@ -438,7 +439,7 @@ void MainWindow::contextMenu(const QPoint &pos) { menu.addAction("Deselect all", clv_, SLOT(deselectAllPoints())); menu.addAction("Select all", clv_, SLOT(selectAllPoints())); menu.addAction("Invert selection", clv_, SLOT(invertSelection())); - + menu.addAction("Count visible", clv_, SLOT(countVisible())); if(flatview_->isVisible()) menu.addAction("Rotate", flatview_, SLOT(rotate90())); diff --git a/src/gui/mainwindow.h b/src/gui/mainwindow.h index b872e10..212b78c 100755 --- a/src/gui/mainwindow.h +++ b/src/gui/mainwindow.h @@ -50,6 +50,9 @@ class GUI_API MainWindow : public QMainWindow { tabs_->removeTab(idx); } + + void reset(); + public slots: void loadFile(); void saveLayer(); diff --git a/src/gui/resources/flatview.vs.glsl b/src/gui/resources/flatview.vs.glsl index 9b2c3c1..e0346cd 100755 --- a/src/gui/resources/flatview.vs.glsl +++ b/src/gui/resources/flatview.vs.glsl @@ -3,6 +3,7 @@ layout(location = 0) in float intensity; layout(location = 1) in int color_index; layout(location = 2) in int flags; layout(location = 3) in vec2 position; +layout(location = 4) in vec3 rgb; uniform samplerBuffer sampler; uniform mat3 camera; @@ -24,7 +25,8 @@ void main( void ) { vec4 layer_colour = texelFetch(sampler, color_index); // Adjust the colour intensity - colour = layer_colour * intensity; +// colour = layer_colour * intensity; + colour = layer_colour * vec4(rgb, 1); int select_count = 0; vec4 select_colour = vec4(0.0f, 0.0f, 0.0f, 0.0f); diff --git a/src/gui/resources/points.vert b/src/gui/resources/points.vert index 2b8c6cb..b864804 100755 --- a/src/gui/resources/points.vert +++ b/src/gui/resources/points.vert @@ -4,6 +4,8 @@ layout(location = 0) in vec4 vertex; layout(location = 1) in float intensity; layout(location = 2) in int color_index; layout(location = 3) in int flags; +layout(location = 4) in vec3 rgb; + uniform samplerBuffer sampler; uniform mat4 projection; uniform mat4 modelview; @@ -25,7 +27,8 @@ void main( void ) { vec4 layer_colour = texelFetch(sampler, color_index); // Adjust the colour intensity - colour = layer_colour * intensity; +// colour = layer_colour * intensity; + colour = layer_colour * vec4(rgb, 1); int select_count = 0; vec4 select_colour = vec4(0.0f, 0.0f, 0.0f, 0.0f); diff --git a/src/model/pointcloud.cpp b/src/model/pointcloud.cpp index fe95b89..d5e9651 100755 --- a/src/model/pointcloud.cpp +++ b/src/model/pointcloud.cpp @@ -30,7 +30,7 @@ inline bool isNaN(float val){ } PointCloud::PointCloud() - : pcl::PointCloud() { + : pcl::PointCloud() { pc_mutex.reset(new std::mutex()); frame_ = CoordinateFrame::Laser; @@ -99,20 +99,26 @@ bool PointCloud::save_ptx(const char* filename, std::vector labels){ emit progress(100*grid_idx/static_cast(point_count)); if(next_grid_idx != grid_idx) { - fprintf(pfile, "%f %f %f %f\n", 0.0f, 0.0f, 0.0f, 0.0f); + fprintf(pfile, "%f %f %f %f %hhd %hhd %hhd\n", 0.0f, 0.0f, 0.0f, 0.0f, 0, 0, 0); continue; } next_grid_idx = this->cloud_to_grid_map_[++cloud_idx]; if(labels.size() != 0 && !point_matches_label(cloud_idx, labels)) { - fprintf(pfile, "%f %f %f %f\n", 0.0f, 0.0f, 0.0f, 0.0f); + fprintf(pfile, "%f %f %f %f %hhd %hhd %hhd\n", 0.0f, 0.0f, 0.0f, 0.0f, 0, 0, 0); continue; } - fprintf(pfile, "%f %f %f %f\n", this->points[cloud_idx].x, - this->points[cloud_idx].y, this->points[cloud_idx].z, - this->points[cloud_idx].intensity); + fprintf(pfile, "%f %f %f %f %hhd %hhd %hhd\n", + this->points[cloud_idx].x, + this->points[cloud_idx].y, + this->points[cloud_idx].z, + this->points[cloud_idx].data[3], + this->points[cloud_idx].r, + this->points[cloud_idx].g, + this->points[cloud_idx].b + ); } @@ -144,7 +150,7 @@ bool PointCloud::load_ptx(const char* filename, int decimation_factor) { // Contains nans this->is_dense = false; - // Matrix dimentions + // Matrix dimensions int file_width, file_height; fscanf(pfile, "%d %d", &file_width, &file_height); @@ -188,11 +194,14 @@ bool PointCloud::load_ptx(const char* filename, int decimation_factor) { if(update_interval == 0) update_interval = 1; - pcl::PointXYZI point; + pcl::PointXYZRGB point; float & x = point.x; float & y = point.y; float & z = point.z; - float & intensity = point.intensity; + float & intensity = point.data[3]; + uint8_t & r = point.r; + uint8_t & g = point.g; + uint8_t & b = point.b; // Tokenize the first line char * ch; @@ -211,8 +220,9 @@ bool PointCloud::load_ptx(const char* filename, int decimation_factor) { // Check if rgb channels are present bool has_rgb = false; - if(tokens == 7) + if(tokens == 7) { has_rgb = true; + } // Move reset the reading pos in file fseek(pfile, file_pos, SEEK_SET); @@ -228,31 +238,28 @@ bool PointCloud::load_ptx(const char* filename, int decimation_factor) { col = file_sample_idx % file_width; file_sample_idx++; - // Only process every decimation_factor-ith row and column - if((row+1)%decimation_factor != 0 || (col+1)%decimation_factor != 0){ - //for(int i = 0; i < tokens; i++ ) - // fscanf(pfile, "%f", &ign); - qDebug() << "Skiped point"; - fgets(buff, 1024, pfile); - continue; - } - if(ferror (pfile) || feof(pfile)){ qDebug() << "File read fail at line " << file_sample_idx << "with sample idx:" << sampled_idx; return false; } - //file_pos = ftell(pfile); - int filled = fscanf(pfile, "%f %f %f %f\n", &x, &y, &z, &intensity); + int filled; - if(filled != 4) { + if(has_rgb) { + filled = fscanf(pfile, "%f %f %f %f %hhd %hhd %hhd", &x, &y, &z, &intensity, &r, &g, &b); + } else { + filled = fscanf(pfile, "%f %f %f %f", &x, &y, &z, &intensity); + r = intensity * 255, g = intensity * 255, b = intensity * 255; + } + + if(filled != (has_rgb ? 7 : 4 )) { qDebug() << "File parse fail at line " << file_sample_idx << "with sample idx" << sampled_idx; qDebug() << "File pos: " << file_pos; if(ferror(pfile)) qDebug() << "File read fail."; else { - //fgets(buff, 1024, pfile); - //qDebug("Could not parse '%s'", buff); + fgets(buff, 1024, pfile); + qDebug("Could not parse '%s'", buff); continue; } @@ -265,13 +272,13 @@ bool PointCloud::load_ptx(const char* filename, int decimation_factor) { } // skip the rest of the line - if(has_rgb) { +// if(has_rgb) { fgets(buff, 1024, pfile); - } +// } sampled_idx++; - // Skip points that are invalid + // Skip points that are not returned if((x == 0) && (y == 0) && (z == 0)) { continue; } @@ -291,8 +298,6 @@ bool PointCloud::load_ptx(const char* filename, int decimation_factor) { if(z > max_bounding_box_.z()) min_bounding_box_.z() = z; - point.data_c[2] = cloud_to_grid_map_.size(); - point.data_c[3] = sampled_idx-1; // Store the index in the cloud, new hack this->points.push_back(point); this->cloud_to_grid_map_.push_back(sampled_idx-1); // Undo the increment } @@ -314,7 +319,7 @@ bool PointCloud::load_ptx(const char* filename, int decimation_factor) { qDebug() << "Start octree"; Octree::Ptr octree = Octree::Ptr(new Octree(resolution)); assert(this->size()); - pcl::PointCloud::ConstPtr cptr(this, boost::serialization::null_deleter()); + pcl::PointCloud::ConstPtr cptr(this, boost::serialization::null_deleter()); octree->setInputCloud(cptr); octree->defineBoundingBox(); octree->addPointsFromInputCloud(); @@ -355,10 +360,6 @@ Eigen::Affine3f PointCloud::modelview() { Translation3f tr(sensor_origin_.x(), sensor_origin_.y(), sensor_origin_.z()); AngleAxis rotation(-M_PI/2, Vector3f::UnitX()); -// if(frame_ == CoordinateFrame::Camera){ -// rotation = AngleAxis(-M_PI/2, Vector3f(0, 0, 1)); -// } - return rotation * sensor_orientation_ * tr * Affine3f::Identity(); } diff --git a/src/model/pointcloud.h b/src/model/pointcloud.h index 208c710..c410fd9 100755 --- a/src/model/pointcloud.h +++ b/src/model/pointcloud.h @@ -13,7 +13,7 @@ #include #include "model/export.h" -typedef pcl::octree::OctreePointCloudSearch Octree; +typedef pcl::octree::OctreePointCloudSearch Octree; enum class MODEL_API PointFlags : int8_t { selected = 0x001, @@ -30,7 +30,7 @@ enum class MODEL_API CoordinateFrame: bool { Laser }; -class MODEL_API PointCloud : public QObject, public pcl::PointCloud { +class MODEL_API PointCloud : public QObject, public pcl::PointCloud { Q_OBJECT public: explicit PointCloud(); diff --git a/src/plugins/accuracy/accuracy.cpp b/src/plugins/accuracy/accuracy.cpp index bebdde7..15bd19f 100755 --- a/src/plugins/accuracy/accuracy.cpp +++ b/src/plugins/accuracy/accuracy.cpp @@ -48,8 +48,8 @@ void Accuracy::initialize(Core *core){ QHBoxLayout * dock_layout2 = new QHBoxLayout(); dock_layout->addWidget(new QLabel("Target:")); - QListWidget * l1 = new QListWidget(); - dock_layout->addWidget(l1); + target_layers_ = new QListWidget(); + dock_layout->addWidget(target_layers_); QHBoxLayout * split1 = new QHBoxLayout(); dock_layout->addLayout(split1); QPushButton * add1 = new QPushButton("Add selected layers"); @@ -90,14 +90,14 @@ void Accuracy::initialize(Core *core){ } if(!found){ target_.push_back(s); - l1->addItem(s.lock()->getName()); + target_layers_->addItem(s.lock()->getName()); } } }); connect(clear1, &QPushButton::clicked, [=] (){ - l1->clear(); + target_layers_->clear(); target_.clear(); }); diff --git a/src/plugins/accuracy/accuracy.h b/src/plugins/accuracy/accuracy.h index 6925d9d..2975a28 100755 --- a/src/plugins/accuracy/accuracy.h +++ b/src/plugins/accuracy/accuracy.h @@ -24,6 +24,7 @@ class QLabel; class QDoubleSpinBox; class QDockWidget; class QPushButton; +class QListWidget; class ACCURACY_API Accuracy : public IPlugin { Q_INTERFACES(IPlugin) @@ -70,7 +71,6 @@ class ACCURACY_API Accuracy : public IPlugin { QDoubleSpinBox * target_accuracy_input_; - std::vector > target_; QTimer timer_; QTime time_; @@ -84,6 +84,10 @@ class ACCURACY_API Accuracy : public IPlugin { bool started_ = false; std::vector> time_accuracy_precision_recall_; + +public: + std::vector > target_; + QListWidget * target_layers_; }; #endif // ACCURACY_H diff --git a/src/plugins/autotest/autotest.cpp b/src/plugins/autotest/autotest.cpp index c6dbcd1..e9c840d 100755 --- a/src/plugins/autotest/autotest.cpp +++ b/src/plugins/autotest/autotest.cpp @@ -1,5 +1,7 @@ #include "plugins/autotest/autotest.h" #include +#include +#include #include #include #include @@ -21,6 +23,8 @@ #include #include #include +#include +#include #include "model/layerlist.h" #include "model/cloudlist.h" #include "gui/glwidget.h" @@ -33,6 +37,7 @@ #include "plugins/project/project.h" #include "plugins/markov/markov.h" #include "plugins/accuracy/accuracy.h" +#include "utilities/utils.h" QString AutoTest::getName(){ return "AutoTest"; @@ -51,7 +56,8 @@ void AutoTest::initialize(Core *core){ dock_widget_ = new QWidget(); dock_ = new QDockWidget(); - + radius_spinner_ = new QDoubleSpinBox(); + radius_ = 0.25; enable_ = new QAction(QIcon(":/autotest.png"), "Enable AutoTest", 0); enable_->setCheckable(true); @@ -60,7 +66,7 @@ void AutoTest::initialize(Core *core){ } void AutoTest::initialize2(PluginManager *pm){ -// project_ = pm->findPlugin(); + project_ = pm->findPlugin(); markov_ = pm->findPlugin(); accuracy_ = pm->findPlugin(); @@ -69,7 +75,10 @@ void AutoTest::initialize2(PluginManager *pm){ QPushButton * open_button = new QPushButton("Open test"); QPushButton * run_button = new QPushButton("Run test"); + QPushButton * run_feature_eval_button = new QPushButton("Run feature eval"); + QPushButton * run_knn_button = new QPushButton("Run knn test"); + run_feature_eval_button->setDisabled(true); run_button->setDisabled(true); connect(open_button, &QPushButton::clicked, [=] (){ @@ -83,14 +92,17 @@ void AutoTest::initialize2(PluginManager *pm){ settings.setValue("load/lasttestlocation", QFileInfo(filename).absolutePath()); settings.sync(); + run_feature_eval_button->setDisabled(false); run_button->setDisabled(false); test_path_ = filename; }); + connect(run_feature_eval_button, &QPushButton::clicked, (std::function) std::bind(&AutoTest::run_feature_selection, this)); connect(run_button, &QPushButton::clicked, (std::function) std::bind(&AutoTest::runtests, this)); -// connect(run_button, &QPushButton::clicked, [&](){ + connect(run_knn_button, &QPushButton::clicked, (std::function) std::bind(&AutoTest::knntest, this)); +// connect(run_knn_button, &QPushButton::clicked, [&](){ // }); @@ -105,6 +117,8 @@ void AutoTest::initialize2(PluginManager *pm){ dock_layout->addWidget(new QLabel("GAR!")); dock_layout->addWidget(open_button); dock_layout->addWidget(run_button); + dock_layout->addWidget(run_feature_eval_button); + dock_layout->addWidget(run_knn_button); dock_layout->setStretch(100, 100); @@ -113,7 +127,100 @@ void AutoTest::initialize2(PluginManager *pm){ dock_->setWidget(dock_widget_); } -std::tuple AutoTest::runTest( +void AutoTest::knntest() { + boost::shared_ptr cloud = core_->cl_->active_; + if(cloud == nullptr) + return; + + QFile report_file("knnreport.csv"); + report_file.open(QIODevice::Append | QIODevice::Text); + QDebug report(&report_file); + report.setAutoInsertSpaces(false); + + + report << "voxel size,knn radius,original size,downsampled cloud size,avg points,downsample seconds,knn seconds,total seconds\n"; + + qDebug() << "voxel size,knn radius,original size,downsampled cloud size,avg points,downsample seconds,knn seconds,total seconds"; + + for(float voxel_size = 0.005f; voxel_size <= 0.1; voxel_size+=0.005) { + + std::vector big_to_small; + + clock_t downsample_start = std::clock(); + pcl::PointCloud::Ptr smallcloud_ = octreeDownsample(cloud.get(), voxel_size, big_to_small); + double downsample_elapsed = double(std::clock() - downsample_start) / CLOCKS_PER_SEC; + + for(float nn_radius = 0; nn_radius <= 0.5; nn_radius+=0.05) { + + if (nn_radius < voxel_size) continue; + + clock_t nn_search_start = std::clock(); + double total = 0; + + typename pcl::PointCloud::ConstPtr cptr(smallcloud_.get(), boost::serialization::null_deleter()); + pcl::KdTreeFLANN search; + search.setInputCloud(cptr); + + std::vector kDist; + std::vector kIdxs; + + bool stopped_early = false; + + for(uint i = 0; i < smallcloud_->size(); i++){ + search.radiusSearch(i, nn_radius, kIdxs, kDist); + total+=kIdxs.size(); + + if (i % 500 == 0) { + double nn_search_elapsed = double(std::clock() - nn_search_start) / CLOCKS_PER_SEC; + if (nn_search_elapsed > 60) { + stopped_early = true; + break; + } + } + } + + if (stopped_early) { + qDebug() << "stopped early: " << voxel_size << "," << nn_radius; + break; + } + + double nn_search_elapsed = double(std::clock() - nn_search_start) / CLOCKS_PER_SEC; + + report << voxel_size << "," << + nn_radius << "," << + cloud->size() << "," << + smallcloud_->size() << "," << + double(total)/smallcloud_->size() << "," << + downsample_elapsed << "," << + nn_search_elapsed << "," << + nn_search_elapsed + downsample_elapsed << "\n"; + + qDebug() << voxel_size << "," << + nn_radius << "," << + cloud->size() << "," << + smallcloud_->size() << "," << + double(total)/smallcloud_->size() << "," << + downsample_elapsed << "," << + nn_search_elapsed << "," << + nn_search_elapsed + downsample_elapsed; + +// clock_t upsample_start = std::clock(); + +// std::vector trash; +// for(int idx = 0; idx < cloud->size(); idx++) { +// trash.push_back(big_to_small[idx]); +// } + +// double upsample_elapsed = double(std::clock() - upsample_start) / CLOCKS_PER_SEC; + +// qDebug() << "upsample time" << upsample_elapsed << "trash: " << trash.size(); + } + } + + +} + +std::tuple AutoTest::runTest( std::vector features, float downsample, float curvature_radius, @@ -121,7 +228,9 @@ std::tuple AutoTest::runTest( float density_radius, int pca_max_nn, int tree_count, - int tree_depth){ + int tree_depth, + int tree_counter_threshold, + int tree_random_tests){ markov_->pca_radius_spinner_->setValue(pca_radius); markov_->curvature_radius_spinner_->setValue(curvature_radius); @@ -132,11 +241,36 @@ std::tuple AutoTest::runTest( markov_->tree_depth_spinner_->setValue(tree_depth); markov_->max_nn_spinner_->setValue(pca_max_nn);; + markov_->tree_counter_threshold_spinner_->setValue(tree_counter_threshold); + markov_->tree_random_tests_spinner_->setValue(tree_random_tests); + markov_->feature_list_->selectOnly(features); QCoreApplication::processEvents(); // Need this for settings to take effect? - markov_->randomforest(); + double downsample_elapsed; + double pca_elapsed; + double curvature_elapsed; + double density_elapsed; + double get_selections_elapsed; + double feature_compute_elapsed; + double train_elapsed; + double feature_compute_2_elapsed; + double classify_elapsed; + double result_select_elapsed; + double action_elapsed; + + std::tie(downsample_elapsed, + pca_elapsed, + curvature_elapsed, + density_elapsed, + get_selections_elapsed, + feature_compute_elapsed, + train_elapsed, + feature_compute_2_elapsed, + classify_elapsed, + result_select_elapsed, + action_elapsed) = markov_->randomforest(); float accuracy, precision, recall; std::tie(accuracy, precision, recall) = accuracy_->sample(); @@ -146,7 +280,20 @@ std::tuple AutoTest::runTest( QCoreApplication::processEvents(); qDebug() << "Results" << accuracy << precision << recall; - return std::make_tuple(accuracy, precision, recall); + return std::make_tuple(accuracy, + precision, + recall, + downsample_elapsed, + pca_elapsed, + curvature_elapsed, + density_elapsed, + get_selections_elapsed, + feature_compute_elapsed, + train_elapsed, + feature_compute_2_elapsed, + classify_elapsed, + result_select_elapsed, + action_elapsed); } void AutoTest::runtests() { @@ -171,65 +318,364 @@ void AutoTest::runtests() { QJsonObject defaults = root["defaults"].toObject(); QJsonArray tests = root["tests"].toArray(); + QJsonArray scans = root["scans"].toArray(); // Setup reporting QFile report_file("report.csv"); report_file.open(QIODevice::Append | QIODevice::Text); - QDebug report(&report_file); - report.setAutoInsertSpaces(false); + QTextStream report(&report_file); + + for(QJsonValueRef s : scans){ + QJsonObject scan = s.toObject(); + QString path = scan["path"].toString(); + QString target_layer_name = scan["targetLayerName"].toString(); + uint8_t result_selection = scan["resultSelection"].toInt(); + + mw_->reset(); + project_->load(path); + accuracy_->target_layers_->clear(); + accuracy_->target_layers_->addItem(target_layer_name); + + for(const boost::shared_ptr & l : ll_->getLayers()){ + if(l->getName() == target_layer_name) { + accuracy_->target_.push_back(l); + } + } + + mw_->setSelectMask(1 << result_selection); + + report << "File:" << test_path_ << ", Project: " << path << "\n"; + report << "Feature,accuracy,accuracy_std,precision,precision_std,recall,recall_std," << + "downsample_elapsed," << + "pca_elapsed," << + "curvature_elapsed," << + "density_elapsed," << + "get_selections_elapsed," << + "feature_compute_elapsed," << + "train_elapsed," << + "feature_compute_2_elapsed," << + "classify_elapsed," << + "result_select_elapsed," << + "action_elapsed\n"; + + + qDebug() << "Starting: " << path << "\n"; + + report.flush(); + + for(QJsonValueRef test : tests){ + QJsonObject t = test.toObject(); + + QJsonArray featuresArray = t.contains("features") ? t["features"].toArray() : defaults["features"].toArray(); + + qDebug() << "Test:" << t["name"].toString(); + + std::vector features; + for(QJsonValueRef nameRef : featuresArray){ + features.push_back(nameRef.toString().toStdString()); + } + + QString name = t["name"].toString(); + float downsample = t.contains("downsample") ? t["downsample"].toDouble() : defaults["downsample"].toDouble(); + float curvature_radius = t.contains("curvature_radius") ? t["curvature_radius"].toDouble() : defaults["curvature_radius"].toDouble(); + float pca_radius = t.contains("pca_radius") ? t["pca_radius"].toDouble() : defaults["pca_radius"].toDouble(); + float density_radius = t.contains("downsample") ? t["density_radius"].toDouble() : defaults["density_radius"].toDouble(); + int pca_max_nn = t.contains("pca_max_nn") ? t["pca_max_nn"].toInt() : defaults["pca_max_nn"].toInt(); + int tree_count = t.contains("tree_count") ? t["tree_count"].toInt() : defaults["tree_count"].toInt(); + int tree_depth = t.contains("tree_depth") ? t["tree_depth"].toInt() : defaults["tree_depth"].toInt(); + int tree_counter_threshold = t.contains("tree_counter_threshold") ? t["tree_counter_threshold"].toInt() : defaults["tree_counter_threshold"].toInt(); + int tree_random_tests = t.contains("tree_random_tests") ? t["tree_random_tests"].toInt() : defaults["tree_random_tests"].toInt(); + + std::vector accuracies; + std::vector precisions; + std::vector recalls; + + float accuracy = 0, precision = 0, recall = 0; + float accuracy_std = 0, precision_std = 0, recall_std = 0; + double downsample_elapsed; + double pca_elapsed; + double curvature_elapsed; + double density_elapsed; + double get_selections_elapsed; + double feature_compute_elapsed; + double train_elapsed; + double feature_compute_2_elapsed; + double classify_elapsed; + double result_select_elapsed; + double action_elapsed; + + const int iterations = 5; + + for (int i = 0; i < iterations; i++) { + float _accuracy, _precision, _recall; + double _downsample_elapsed; + double _pca_elapsed; + double _curvature_elapsed; + double _density_elapsed; + double _get_selections_elapsed; + double _feature_compute_elapsed; + double _train_elapsed; + double _feature_compute_2_elapsed; + double _classify_elapsed; + double _result_select_elapsed; + double _action_elapsed; + + std::tie(_accuracy, + _precision, + _recall, + _downsample_elapsed, + _pca_elapsed, + _curvature_elapsed, + _density_elapsed, + _get_selections_elapsed, + _feature_compute_elapsed, + _train_elapsed, + _feature_compute_2_elapsed, + _classify_elapsed, + _result_select_elapsed, + _action_elapsed) = runTest( + features, + downsample, + curvature_radius, + pca_radius, + density_radius, + pca_max_nn, + tree_count, + tree_depth, + tree_counter_threshold, + tree_random_tests); + + accuracy += _accuracy; + precision += _precision; + recall += _recall; + + accuracies.push_back(accuracy); + precisions.push_back(precision); + recalls.push_back(recall); + + if (i == 0) { + downsample_elapsed = _downsample_elapsed; + pca_elapsed = _pca_elapsed; + curvature_elapsed = _curvature_elapsed; + density_elapsed = _density_elapsed; + get_selections_elapsed = _get_selections_elapsed; + feature_compute_elapsed = _feature_compute_elapsed; + train_elapsed = _train_elapsed; + feature_compute_2_elapsed = _feature_compute_2_elapsed; + classify_elapsed = _classify_elapsed; + result_select_elapsed = _result_select_elapsed; + action_elapsed = _action_elapsed; + } + } + + accuracy /= iterations; + precision /= iterations; + recall /= iterations; + + float a_sum = 0; + float p_sum = 0; + float r_sum = 0; + + for (int i = 0; i < iterations; i++) { + a_sum += pow(accuracies[i] - accuracy_std, 2); + p_sum += pow(precisions[i] - precision_std, 2); + r_sum += pow(recalls[i] - recall_std, 2); + } + + accuracy_std = sqrt(a_sum/(iterations-1)); + precision_std = sqrt(p_sum/(iterations-1)); + recall_std = sqrt(r_sum/(iterations-1)); + + report << name << "," + << accuracy << "," + << accuracy_std << "," + << precision << "," + << precision_std << "," + << recall << "," + << recall_std << "," + << downsample_elapsed << "," + << pca_elapsed << "," + << curvature_elapsed << "," + << density_elapsed << "," + << get_selections_elapsed << "," + << feature_compute_elapsed << "," + << train_elapsed << "," + << feature_compute_2_elapsed << "," + << classify_elapsed << "," + << result_select_elapsed << "," + << action_elapsed << "\n"; + + report.flush(); + report_file.flush(); + + } + + } - report << "File:" << test_path_ << "\n"; + report_file.close(); +} + + +void AutoTest::run_feature_selection() { + + qDebug() << "Opening file: " << test_path_; + QFile file(test_path_); + file.open(QIODevice::ReadOnly | QIODevice::Text); + if(!file.isOpen()){ + qDebug() << "Could not open file"; + return; + } + + QJsonParseError err; + QJsonDocument doc = QJsonDocument::fromJson(file.readAll(), &err); + file.close(); + + if(doc.isNull()){ + qDebug() << "No test data: " << err.errorString(); + } + + QJsonObject root = doc.object(); + + QJsonObject defaults = root["defaults"].toObject(); + QJsonArray ordered_feature_sets = root["tests"].toArray(); + QJsonArray scans = root["scans"].toArray(); + + // Setup reporting + QFile report_file("feature-selection-report.csv"); + report_file.open(QIODevice::Append | QIODevice::Text); + QTextStream report(&report_file); + + report << "features,noise,people,tools,tree,mean\n"; -// report << "Feature,downsample,curvature radius,pca radius,density_radius,tree_count,tree_depth,accuracy,precision,recall" << "\n"; - report << "Feature,accuracy,precision,recall" << "\n"; + // setup defaults + float downsample = defaults["downsample"].toDouble(); + float curvature_radius = defaults["curvature_radius"].toDouble(); + float pca_radius = defaults["pca_radius"].toDouble(); + float density_radius = defaults["density_radius"].toDouble(); + int pca_max_nn = defaults["pca_max_nn"].toInt(); + int tree_count = defaults["tree_count"].toInt(); + int tree_depth = defaults["tree_depth"].toInt(); + int tree_counter_threshold = defaults["tree_counter_threshold"].toInt(); + int tree_random_tests = defaults["tree_random_tests"].toInt(); - for(QJsonValueRef test : tests){ - QJsonObject t = test.toObject(); - QJsonArray featuresArray = t["features"].toArray(); - qDebug() << "Test:" << t["name"].toString(); + float max_accuracy = 0; + std::set included_feature_sets_idxs = {}; + + // here we try to add the next feature + + for(uint i = 0; i < ordered_feature_sets.size(); i++){ std::vector features; - for(QJsonValueRef nameRef : featuresArray){ - features.push_back(nameRef.toString().toStdString()); + float feature_accuracy = 0; + + std::set candidate_feature_sets_idxs = included_feature_sets_idxs; + candidate_feature_sets_idxs.insert(i); + + QString candidate_feature_name; + + for(uint idx : candidate_feature_sets_idxs) { + QJsonObject f = ordered_feature_sets[idx].toObject(); + + + for(QJsonValueRef nameRef : f["features"].toArray()){ + features.push_back(nameRef.toString().toStdString()); + } + + candidate_feature_name += f["name"].toString() + " + "; } - QString name = t["name"].toString(); - float downsample = t.contains("downsample") ? t["downsample"].toDouble() : defaults["downsample"].toDouble(); - float curvature_radius = t.contains("curvature_radius") ? t["curvature_radius"].toDouble() : defaults["curvature_radius"].toDouble();; - float pca_radius = t.contains("pca_radius") ? t["pca_radius"].toDouble() : defaults["pca_radius"].toDouble();; - float density_radius = t.contains("downsample") ? t["density_radius"].toDouble() : defaults["density_radius"].toDouble();; - int pca_max_nn = t.contains("pca_max_nn") ? t["pca_max_nn"].toInt() : defaults["pca_max_nn"].toInt();; - int tree_count = t.contains("tree_count") ? t["tree_count"].toInt() : defaults["tree_count"].toInt();; - int tree_depth = t.contains("tree_depth") ? t["tree_depth"].toInt() : defaults["tree_depth"].toInt();; + report << candidate_feature_name << ","; + + // Should I add previously viewed features? float accuracy, precision, recall; - std::tie(accuracy, precision, recall) = runTest( - features, - downsample, - curvature_radius, - pca_radius, - density_radius, - pca_max_nn, - tree_count, - tree_depth); - - report << name << "," -// << downsample << "," -// << curvature_radius << "," -// << pca_radius << "," -// << density_radius << "," -// << tree_count << "," -// << tree_depth << "," - << accuracy << "," - << precision << "," - << recall << "\n"; + double downsample_elapsed; + double pca_elapsed; + double curvature_elapsed; + double density_elapsed; + double get_selections_elapsed; + double feature_compute_elapsed; + double train_elapsed; + double feature_compute_2_elapsed; + double classify_elapsed; + double result_select_elapsed; + double action_elapsed; + + for(QJsonValueRef s : scans){ + QJsonObject scan = s.toObject(); + QString path = scan["path"].toString(); + QString target_layer_name = scan["targetLayerName"].toString(); + uint8_t result_selection = scan["resultSelection"].toInt(); + + mw_->reset(); + project_->load(path); + accuracy_->target_layers_->clear(); + accuracy_->target_layers_->addItem(target_layer_name); + + for(const boost::shared_ptr & l : ll_->getLayers()){ + if(l->getName() == target_layer_name) { + accuracy_->target_.push_back(l); + } + } + + mw_->setSelectMask(1 << result_selection); + + // after setup... + + float iteration_accuracy_sum = 0; + + for (int k = 0; k < 3; k++) { + std::tie(accuracy, + precision, + recall, + downsample_elapsed, + pca_elapsed, + curvature_elapsed, + density_elapsed, + get_selections_elapsed, + feature_compute_elapsed, + train_elapsed, + feature_compute_2_elapsed, + classify_elapsed, + result_select_elapsed, + action_elapsed) = runTest( + features, + downsample, + curvature_radius, + pca_radius, + density_radius, + pca_max_nn, + tree_count, + tree_depth, + tree_counter_threshold, + tree_random_tests); + + iteration_accuracy_sum += accuracy; + } + + feature_accuracy += iteration_accuracy_sum/3.0f; + report << iteration_accuracy_sum/3.0f << ","; + report.flush(); + report_file.flush(); + } + + feature_accuracy /= 4; + + report << feature_accuracy << "\n"; + + if(feature_accuracy > (max_accuracy + 0.01)) { + max_accuracy = feature_accuracy; + included_feature_sets_idxs = candidate_feature_sets_idxs; + } + } report_file.close(); } + void AutoTest::cleanup(){ disable(); mw_->toolbar_->removeAction(enable_); diff --git a/src/plugins/autotest/autotest.h b/src/plugins/autotest/autotest.h index 39d6a6c..e653d75 100755 --- a/src/plugins/autotest/autotest.h +++ b/src/plugins/autotest/autotest.h @@ -14,6 +14,7 @@ class MainWindow; class Project; class Markov; class Accuracy; +class QDoubleSpinBox; class AutoTest : public IPlugin { Q_INTERFACES(IPlugin) @@ -23,8 +24,9 @@ class AutoTest : public IPlugin { QString getName(); void initialize(Core * core); void initialize2(PluginManager *pm); - std::tuple runTest(std::vector features, float downsample, float curvature_radius, float pca_radius, float density_radius, int pca_max_nn, int tree_count, int tree_depth); + std::tuple runTest(std::vector features, float downsample, float curvature_radius, float pca_radius, float density_radius, int pca_max_nn, int tree_count, int tree_depth, int tree_counter_threshold, int tree_random_tests); void cleanup(); + void knntest(); ~AutoTest(); signals: @@ -34,6 +36,7 @@ class AutoTest : public IPlugin { void enable(); void disable(); void runtests(); + void run_feature_selection(); private: Core * core_; @@ -47,6 +50,8 @@ class AutoTest : public IPlugin { QWidget * dock_widget_; bool is_enabled_; + QDoubleSpinBox * radius_spinner_; + float radius_; Project * project_; Accuracy * accuracy_; diff --git a/src/plugins/brush3d/brush3d.cpp b/src/plugins/brush3d/brush3d.cpp index bab8658..8da6e7c 100755 --- a/src/plugins/brush3d/brush3d.cpp +++ b/src/plugins/brush3d/brush3d.cpp @@ -350,7 +350,7 @@ bool Brush3D::mouseMoveEvent(QMouseEvent * event) { Eigen::Vector3f p = p1 + dist*dir; dist+=last_rad_/4; - pcl::PointXYZI q; + pcl::PointXYZRGB q; q.getVector3fMap() = p; // calculate radius diff --git a/src/plugins/flood/flood.cpp b/src/plugins/flood/flood.cpp index 32c83aa..ce40fea 100755 --- a/src/plugins/flood/flood.cpp +++ b/src/plugins/flood/flood.cpp @@ -264,7 +264,7 @@ void Flood::flood(int source_idx){ pcl::PointCloud::Ptr normals = ne_->getNormals(cl_->active_); // zip and downsample - pcl::PointCloud::Ptr smallcloud = zipNormals(cl_->active_, normals); + pcl::PointCloud::Ptr smallcloud = zipNormals(cl_->active_, normals); std::vector & big_to_small = cache2_[cl_->active_]; cache_[cl_->active_] = octreeDownsample(smallcloud.get(), 0.01, big_to_small); @@ -277,7 +277,7 @@ void Flood::flood(int source_idx){ } } - pcl::PointCloud::Ptr smallcloud = cache_[cl_->active_]; + pcl::PointCloud::Ptr smallcloud = cache_[cl_->active_]; std::vector & big_to_small = cache2_[cl_->active_]; std::vector> & small_to_big = cache3_[cl_->active_]; @@ -286,12 +286,12 @@ void Flood::flood(int source_idx){ for(int big_idx = 0; big_idx < normals->size(); ++big_idx){ int small_idx = big_to_small[big_idx]; pcl::Normal & n = normals->points[big_idx]; - pcl::PointXYZINormal & pn = smallcloud->points[small_idx]; + pcl::PointXYZRGBNormal & pn = smallcloud->points[small_idx]; n.getNormalVector4fMap() = pn.getNormalVector4fMap(); } */ - pcl::PointXYZINormal & n = (*smallcloud)[big_to_small[source_idx]]; + pcl::PointXYZRGBNormal & n = (*smallcloud)[big_to_small[source_idx]]; Eigen::Map source_normal(&n.normal_x); qDebug() << "Source normal: " << source_normal.x() << source_normal.y() << source_normal.z(); @@ -303,7 +303,7 @@ void Flood::flood(int source_idx){ //boost::shared_ptr > indices = getLayerIndices(); //Octree search = *(cl_->active_->octree()); - pcl::KdTreeFLANN search; + pcl::KdTreeFLANN search; search.setInputCloud(smallcloud); std::set visited; @@ -327,7 +327,7 @@ void Flood::flood(int source_idx){ search.nearestKSearch(current_idx, k_, idxs, dists); for (int idx : idxs) { - pcl::PointXYZINormal & n = (*smallcloud)[idx]; + pcl::PointXYZRGBNormal & n = (*smallcloud)[idx]; Eigen::Map normal(&n.normal_x); float dist = (normal-source_normal).norm(); @@ -383,14 +383,14 @@ void Flood::global_flood(){ pcl::PointCloud::Ptr normals = ne_->getNormals(cl_->active_); // zip and downsample - pcl::PointCloud::Ptr ptr(cl_->active_.get(), boost::serialization::null_deleter()); - pcl::PointCloud::Ptr smallcloud = zipNormals(ptr, normals); + pcl::PointCloud::Ptr ptr(cl_->active_.get(), boost::serialization::null_deleter()); + pcl::PointCloud::Ptr smallcloud = zipNormals(ptr, normals); std::vector big_to_small; smallcloud = octreeDownsample(smallcloud.get(), 0.05, big_to_small); - pcl::search::Search::Ptr tree = boost::shared_ptr > (new pcl::search::KdTree); + pcl::search::Search::Ptr tree = boost::shared_ptr > (new pcl::search::KdTree); - pcl::RegionGrowing reg; + pcl::RegionGrowing reg; reg.setMinClusterSize (1000); reg.setMaxClusterSize (10000000); reg.setSearchMethod (tree); @@ -445,8 +445,8 @@ void Flood::global_flood2(){ pcl::PointCloud::Ptr normals = ne_->getNormals(cl_->active_); // zip and downsample - pcl::PointCloud::Ptr ptr(cl_->active_.get(), boost::serialization::null_deleter()); - pcl::PointCloud::Ptr smallcloud = zipNormals(ptr, normals); + pcl::PointCloud::Ptr ptr(cl_->active_.get(), boost::serialization::null_deleter()); + pcl::PointCloud::Ptr smallcloud = zipNormals(ptr, normals); std::vector big_to_small; smallcloud = octreeDownsample(smallcloud.get(), subsample_density, big_to_small); @@ -462,12 +462,12 @@ void Flood::global_flood2(){ // Setup the principal curvatures computation - pcl::PrincipalCurvaturesEstimation principal_curvatures_estimation; + pcl::PrincipalCurvaturesEstimation principal_curvatures_estimation; principal_curvatures_estimation.setInputCloud (smallcloud); principal_curvatures_estimation.setInputNormals (smallcloud); - pcl::search::KdTree::Ptr tree (new pcl::search::KdTree); + pcl::search::KdTree::Ptr tree (new pcl::search::KdTree); principal_curvatures_estimation.setSearchMethod (tree); principal_curvatures_estimation.setRadiusSearch (0.5); @@ -517,7 +517,7 @@ void Flood::global_flood2(){ // keep track of points that are in regions already std::set seen; - pcl::KdTreeFLANN search; + pcl::KdTreeFLANN search; search.setInputCloud(smallcloud); auto fill = [&] (int source_idx) { @@ -594,7 +594,7 @@ void Flood::global_flood2(){ // Remove the regoin if it doesnt look planar - pcl::PCA pcEstimator(true); + pcl::PCA pcEstimator(true); pcEstimator.setInputCloud(smallcloud); pcEstimator.setIndices(boost::shared_ptr>(®ion, boost::serialization::null_deleter())); diff --git a/src/plugins/flood/flood.h b/src/plugins/flood/flood.h index 4422532..8f5a9cb 100755 --- a/src/plugins/flood/flood.h +++ b/src/plugins/flood/flood.h @@ -80,7 +80,7 @@ class Flood : public IPlugin { int k_; - std::map, pcl::PointCloud::Ptr> cache_; + std::map, pcl::PointCloud::Ptr> cache_; std::map, std::vector> cache2_; std::map, std::vector>> cache3_; }; diff --git a/src/plugins/graphcut/graphcut.cpp b/src/plugins/graphcut/graphcut.cpp index 4f3b1f3..de998c5 100755 --- a/src/plugins/graphcut/graphcut.cpp +++ b/src/plugins/graphcut/graphcut.cpp @@ -144,7 +144,7 @@ void GraphCut::segment(int idx){ MinCut mc; - pcl::PointCloud::Ptr ptr(cl_->active_.get(), boost::serialization::null_deleter()); + pcl::PointCloud::Ptr ptr(cl_->active_.get(), boost::serialization::null_deleter()); mc.setInputCloud(ptr); pcl::IndicesPtr source_indices(new std::vector); @@ -165,7 +165,7 @@ void GraphCut::segment(int idx){ mc.setIndices(source_indices); - pcl::PointCloud::Ptr foreground_points(new pcl::PointCloud ()); + pcl::PointCloud::Ptr foreground_points(new pcl::PointCloud ()); foreground_points->points.push_back(cl_->active_->points[idx]); // What? There can be more than one? mc.setForegroundPoints (foreground_points); diff --git a/src/plugins/graphcut/mincut.cpp b/src/plugins/graphcut/mincut.cpp index 55ca50f..a5c24e0 100755 --- a/src/plugins/graphcut/mincut.cpp +++ b/src/plugins/graphcut/mincut.cpp @@ -268,7 +268,7 @@ MinCut::setNumberOfNeighbours (unsigned int neighbour_number) } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - std::vector > + std::vector > MinCut::getForegroundPoints () const { return (foreground_points_); @@ -276,7 +276,7 @@ MinCut::getForegroundPoints () const ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void -MinCut::setForegroundPoints ( pcl::PointCloud::Ptr foreground_points) +MinCut::setForegroundPoints ( pcl::PointCloud::Ptr foreground_points) { foreground_points_.clear (); foreground_points_.reserve (foreground_points->points.size ()); @@ -287,7 +287,7 @@ MinCut::setForegroundPoints ( pcl::PointCloud::Ptr foreground_po } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - std::vector > + std::vector > MinCut::getBackgroundPoints () const { return (background_points_); @@ -295,7 +295,7 @@ MinCut::getBackgroundPoints () const ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void -MinCut::setBackgroundPoints ( pcl::PointCloud::Ptr background_points) +MinCut::setBackgroundPoints ( pcl::PointCloud::Ptr background_points) { background_points_.clear (); background_points_.reserve (background_points->points.size ()); @@ -405,7 +405,7 @@ MinCut::buildGraph () return (false); if (search_ == 0) - search_ = boost::shared_ptr > (new pcl::search::KdTree); + search_ = boost::shared_ptr > (new pcl::search::KdTree); graph_.reset (); graph_ = boost::shared_ptr< mGraph > (new mGraph ()); diff --git a/src/plugins/graphcut/mincut.h b/src/plugins/graphcut/mincut.h index f9a7695..2d6743f 100755 --- a/src/plugins/graphcut/mincut.h +++ b/src/plugins/graphcut/mincut.h @@ -14,9 +14,9 @@ class MinCut { public: - typedef pcl::search::Search KdTree; + typedef pcl::search::Search KdTree; typedef KdTree::Ptr KdTreePtr; - typedef pcl::PointCloud< pcl::PointXYZI > PointCloud; + typedef pcl::PointCloud< pcl::PointXYZRGB > PointCloud; typedef PointCloud::ConstPtr PointCloudConstPtr; @@ -125,24 +125,24 @@ class MinCut setNumberOfNeighbours (unsigned int neighbour_number); /** \brief Returns the points that must belong to foreground. */ - std::vector > + std::vector > getForegroundPoints () const; /** \brief Allows to specify points which are known to be the points of the object. * \param[in] foreground_points point cloud that contains foreground points. At least one point must be specified. */ void - setForegroundPoints ( pcl::PointCloud::Ptr foreground_points); + setForegroundPoints ( pcl::PointCloud::Ptr foreground_points); /** \brief Returns the points that must belong to background. */ - std::vector > + std::vector > getBackgroundPoints () const; /** \brief Allows to specify points which are known to be the points of the background. * \param[in] background_points point cloud that contains background points. */ void - setBackgroundPoints ( pcl::PointCloud::Ptr background_points); + setBackgroundPoints ( pcl::PointCloud::Ptr background_points); /** \brief This method launches the segmentation algorithm and returns the clusters that were * obtained during the segmentation. The indices of points that belong to the object will be stored @@ -316,10 +316,10 @@ class MinCut bool graph_is_valid_; /** \brief Stores the points that are known to be in the foreground. */ - std::vector > foreground_points_; + std::vector > foreground_points_; /** \brief Stores the points that are known to be in the background. */ - std::vector > background_points_; + std::vector > background_points_; /** \brief After the segmentation it will contain the segments. */ std::vector clusters_; diff --git a/src/plugins/markov/featurelist.h b/src/plugins/markov/featurelist.h index 1180617..90d47b2 100644 --- a/src/plugins/markov/featurelist.h +++ b/src/plugins/markov/featurelist.h @@ -74,20 +74,23 @@ class FeatureList : public QAbstractListModel { Feature("Y Normal", 4), Feature("Z Normal", 5), Feature("Intensity", 6), - Feature("Eigen 1", 7), - Feature("Eigen 2", 8), - Feature("Eigen 3", 9), + Feature("Eigen 1", 7, false), + Feature("Eigen 2", 8, false), + Feature("Eigen 3", 9, false), Feature("Curvature 1", 10), Feature("Curvature 2", 11), - Feature("Anisotrophy", 12), - Feature("Planarity", 13), - Feature("Sphericity", 14), - Feature("Linearity", 15), - Feature("Omnivariance", 16), - Feature("Curvature", 17), - Feature("Eigenentrophy", 18), - Feature("Distance from origin", 19), - Feature("Number of neighbours", 20), + Feature("Anisotrophy", 12, false), + Feature("Planarity", 13, false), + Feature("Sphericity", 14, false), + Feature("Linearity", 15, false), + Feature("Omnivariance", 16, false), + Feature("Curvature", 17, false), + Feature("Eigenentrophy", 18, false), + Feature("Distance from origin", 19, false), + Feature("Number of neighbours", 20, false), + Feature("R", 21), + Feature("G", 22), + Feature("B", 23) }; signals: diff --git a/src/plugins/markov/markov.cpp b/src/plugins/markov/markov.cpp index 0c6c869..cd4c153 100755 --- a/src/plugins/markov/markov.cpp +++ b/src/plugins/markov/markov.cpp @@ -45,12 +45,14 @@ void Markov::initialize(Core *core){ flatview_ = core_->mw_->flatview_; mw_ = core_->mw_; - pca_radius_ = 0.5f; - curvature_radius_ = 0.1; - octree_cell_size_ = 0.05; - - tree_count_ = 100; - tree_depth_ = 10; + pca_radius_ = 0.2f; + curvature_radius_ = 0.2; + octree_cell_size_ = 0.02; + + tree_count_ = 16; + tree_depth_ = 8; + tree_counter_threshold_ = 140; + tree_random_tests_ = 16; max_nn_ = 100000; density_radius_ = 0.25; @@ -69,6 +71,8 @@ void Markov::initialize(Core *core){ tree_count_spinner_ = new QSpinBox(); tree_depth_spinner_ = new QSpinBox(); + tree_counter_threshold_spinner_ = new QSpinBox(); + tree_random_tests_spinner_ = new QSpinBox(); max_nn_spinner_ = new QSpinBox(); pca_radius_spinner_->setDecimals(3); @@ -76,7 +80,10 @@ void Markov::initialize(Core *core){ octree_cell_size_spinner_->setDecimals(3); tree_count_spinner_->setRange(1, 5000); - tree_depth_spinner_->setRange(1, 100); + tree_depth_spinner_->setRange(1, 5000); + tree_counter_threshold_spinner_->setRange(1, 5000); + tree_random_tests_spinner_->setRange(1, 5000); + max_nn_spinner_->setRange(1, 100000); pca_radius_spinner_->setValue(pca_radius_); @@ -85,6 +92,10 @@ void Markov::initialize(Core *core){ tree_count_spinner_->setValue(tree_count_); tree_depth_spinner_->setValue(tree_depth_); + + tree_counter_threshold_spinner_->setValue(tree_counter_threshold_); + tree_random_tests_spinner_->setValue(tree_random_tests_); + max_nn_spinner_->setValue(max_nn_); connect(cl_, &CloudList::updatedActive, [&](){ @@ -122,6 +133,14 @@ void Markov::initialize(Core *core){ tree_depth_ = value; }); + connect(tree_counter_threshold_spinner_, static_cast(&QSpinBox::valueChanged), [=] (int value){ + tree_counter_threshold_ = value; + }); + + connect(tree_random_tests_spinner_, static_cast(&QSpinBox::valueChanged), [=] (int value){ + tree_random_tests_ = value; + }); + connect(max_nn_spinner_, static_cast(&QSpinBox::valueChanged), [=] (int value){ max_nn_ = value; pca_dirty_ = true; @@ -166,6 +185,12 @@ void Markov::initialize2(PluginManager * pm) { dock_layout->addWidget(new QLabel("Max tree depth")); dock_layout->addWidget(tree_depth_spinner_); + + dock_layout->addWidget(new QLabel("Samples before split")); + dock_layout->addWidget(tree_counter_threshold_spinner_); + dock_layout->addWidget(new QLabel("Random tests per split")); + dock_layout->addWidget(tree_random_tests_spinner_); + dock_layout->addWidget(new QLabel("PCA max nn")); dock_layout->addWidget(max_nn_spinner_); dock_layout->addWidget(new QLabel("PCA radius")); @@ -235,10 +260,22 @@ void Markov::disable() { enabled_ = false; } -void Markov::randomforest(){ +std::tuple< + double, + double, + double, + double, + double, + double, + double, + double, + double, + double, + double> +Markov::randomforest(){ boost::shared_ptr cloud = core_->cl_->active_; if(cloud == nullptr) - return; + return std::make_tuple(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0); // pca_dirty_ = true; // curvatures_dirty_ = true; @@ -267,7 +304,9 @@ void Markov::randomforest(){ bool use_rc = feature_list_->hasFeature("Curvature"); bool use_odist = feature_list_->hasFeature("Distance from origin"); bool use_n_count = feature_list_->hasFeature("Number of neighbours"); - + bool use_r = feature_list_->hasFeature("R"); + bool use_g = feature_list_->hasFeature("G"); + bool use_b = feature_list_->hasFeature("B"); if(use_x) qDebug() << "using: " << "X"; if(use_y) qDebug() << "using: " << "Y"; @@ -290,7 +329,9 @@ void Markov::randomforest(){ if(use_rc) qDebug() << "using: " << "Curvature"; if(use_odist) qDebug() << "using: " << "Distance from origin"; if(use_n_count) qDebug() << "using: " << "Number of neighbours"; - + if(use_r) qDebug() << "using: " << "R"; + if(use_g) qDebug() << "using: " << "G"; + if(use_b) qDebug() << "using: " << "B"; clock_t action_start = std::clock(); @@ -301,7 +342,7 @@ void Markov::randomforest(){ // zip and downsample if(downsample_dirty_) { - pcl::PointCloud::Ptr zipped = zipNormals(cl_->active_, normals); + pcl::PointCloud::Ptr zipped = zipNormals(cl_->active_, normals); big_to_small_.clear(); smallcloud_ = octreeDownsample(zipped.get(), octree_cell_size_, big_to_small_); downsample_dirty_ = false; @@ -309,47 +350,6 @@ void Markov::randomforest(){ double downsample_elapsed = double(std::clock() - downsample_start) / CLOCKS_PER_SEC; - -// clock_t nn_search_start = std::clock(); -// double total = 0; - -// { -// typename pcl::PointCloud::ConstPtr cptr(smallcloud_.get(), boost::serialization::null_deleter()); -// pcl::KdTreeFLANN search; -// search.setInputCloud(cptr); - -// std::vector kDist; -// std::vector kIdxs; - -// for(uint i = 0; i < smallcloud_->size(); i++){ -// search.radiusSearch(i, 0.15, kIdxs, kDist); -// total+=kIdxs.size(); -// } -// } - -// qDebug() << "cloud size" << smallcloud_->size(); -// qDebug() << "total" << total; -// qDebug() << "avg" << double(total)/smallcloud_->size(); - -// double nn_search_elapsed = double(std::clock() - nn_search_start) / CLOCKS_PER_SEC; -// qDebug() << "time" << nn_search_elapsed << "avg" << double(nn_search_elapsed)/cloud->size(); - -// qDebug() << "downsample: " << downsample_elapsed; - - clock_t upsample_start = std::clock(); - - std::vector trash; - for(int idx = 0; idx < cloud->size(); idx++) { - trash.push_back(big_to_small_[idx]); - } - - double upsample_elapsed = double(std::clock() - upsample_start) / CLOCKS_PER_SEC; - - qDebug() << "upsample time" << upsample_elapsed << "trash: " << trash.size(); - - return; - - clock_t density_start = std::clock(); // density @@ -357,7 +357,7 @@ void Markov::randomforest(){ std::vector neighbour_count; if(use_n_count){ - pcl::KdTreeFLANN search; + pcl::KdTreeFLANN search; search.setInputCloud(smallcloud_); std::vector kDist; @@ -387,11 +387,11 @@ void Markov::randomforest(){ // Curvature // pcl::PointCloud::Ptr principal_curvatures_; if((use_pc1 || use_pc2) && curvatures_dirty_) { - pcl::PrincipalCurvaturesEstimation principalCurvaturesEstimation; + pcl::PrincipalCurvaturesEstimation principalCurvaturesEstimation; principalCurvaturesEstimation.setInputCloud(smallcloud_); principalCurvaturesEstimation.setInputNormals(smallcloud_); - pcl::search::KdTree::Ptr tree (new pcl::search::KdTree); + pcl::search::KdTree::Ptr tree (new pcl::search::KdTree); tree->setInputCloud(smallcloud_); principalCurvaturesEstimation.setSearchMethod (tree); principalCurvaturesEstimation.setRadiusSearch(curvature_radius_); @@ -419,7 +419,7 @@ void Markov::randomforest(){ if(use_z) vec(++featnum) = smallcloud_->at(idx).z; if(use_i) - vec(++featnum) = smallcloud_->at(idx).intensity; + vec(++featnum) = smallcloud_->at(idx).data[3]; if(use_nx) vec(++featnum) = smallcloud_->at(idx).normal_x; if(use_ny) @@ -474,13 +474,23 @@ void Markov::randomforest(){ if(use_rc) vec(++featnum) = pca[0] / (pca[0] + pca[1] + pca[2]); - if(use_odist) + if(use_odist) { vec(++featnum) = smallcloud_->at(idx).getVector3fMap().norm(); + } if(use_n_count && neighbour_count[idx]) { -// vec(++featnum) = double(neighbour_count[idx])/pow(smallcloud_->at(idx).getVector3fMap().norm(), 2); vec(++featnum) = double(neighbour_count[idx]); } + if(use_r) { + vec(++featnum) = double(smallcloud_->at(idx).r); + } + if(use_g) { + vec(++featnum) = double(smallcloud_->at(idx).g); + } + if(use_r) { + vec(++featnum) = double(smallcloud_->at(idx).b); + } + return vec; }; @@ -490,8 +500,8 @@ void Markov::randomforest(){ // Forest hp.maxDepth = tree_depth_; - hp.numRandomTests = 20; - hp.counterThreshold = 140; // Number of samples seen by tree? + hp.numRandomTests = tree_random_tests_; + hp.counterThreshold = tree_counter_threshold_; // Number of samples seen by tree? hp.numTrees = tree_count_; // Experimenter @@ -519,7 +529,7 @@ void Markov::randomforest(){ if(selection_sources.size() < 2) { qDebug() << "Not enough data"; - return; + return std::make_tuple(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0); } // Creating the train data @@ -582,7 +592,7 @@ void Markov::randomforest(){ if(dataset_train.m_numSamples < 10){ qDebug() << "Not enough samples"; - return; + return std::make_tuple(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0); } double feature_compute_elapsed = double(std::clock() - feature_compute_start) / CLOCKS_PER_SEC; @@ -598,16 +608,27 @@ void Markov::randomforest(){ Result invalid(8); invalid.prediction = -1; - clock_t classify_start = std::clock(); + clock_t feature_compute_2_start = std::clock(); std::vector results(smallcloud_->points.size(), invalid); + std::vector point_features; + for(size_t idx = 0; idx < smallcloud_->points.size(); ++idx) { Sample sample; sample.id = idx; sample.w = 1.0; sample.x = mkFeatureVector(idx); - model.eval(sample, results[idx]); + point_features.push_back(sample); + + } + + double feature_compute_2_elapsed = double(std::clock() - feature_compute_2_start) / CLOCKS_PER_SEC; + + clock_t classify_start = std::clock(); + + for(size_t idx = 0; idx < smallcloud_->points.size(); ++idx) { + model.eval(point_features[idx], results[idx]); } double classify_elapsed = double(std::clock() - classify_start) / CLOCKS_PER_SEC; @@ -646,9 +667,23 @@ void Markov::randomforest(){ << "get_selections: "<< get_selections_elapsed << "\n" << "feature_compute: "<< feature_compute_elapsed << "\n" << "train: "<< train_elapsed << "\n" + << "feature_compute_2" << feature_compute_2_elapsed << "\n" << "classify: "<< classify_elapsed << "\n" << "result_select: "<< result_select_elapsed << "\n" << "total: "<< action_elapsed << "\n"; + + return std::make_tuple( + downsample_elapsed, + pca_elapsed, + curvature_elapsed, + density_elapsed, + get_selections_elapsed, + feature_compute_elapsed, + train_elapsed, + feature_compute_2_elapsed, + classify_elapsed, + result_select_elapsed, + action_elapsed); } diff --git a/src/plugins/markov/markov.h b/src/plugins/markov/markov.h index de69730..3d5441d 100755 --- a/src/plugins/markov/markov.h +++ b/src/plugins/markov/markov.h @@ -35,7 +35,7 @@ class MARKOV_API Markov : public IPlugin { ~Markov(); - void randomforest(); + std::tuple randomforest(); public: QDoubleSpinBox * pca_radius_spinner_; @@ -45,8 +45,12 @@ class MARKOV_API Markov : public IPlugin { QSpinBox * tree_count_spinner_; QSpinBox * tree_depth_spinner_; + QSpinBox * tree_counter_threshold_spinner_; + QSpinBox * tree_random_tests_spinner_; QSpinBox * max_nn_spinner_; + + FeatureList * feature_list_; signals: @@ -82,10 +86,12 @@ class MARKOV_API Markov : public IPlugin { int tree_count_; int tree_depth_; + int tree_counter_threshold_; + int tree_random_tests_; int max_nn_; double density_radius_; - pcl::PointCloud::Ptr smallcloud_; + pcl::PointCloud::Ptr smallcloud_; std::vector big_to_small_; boost::shared_ptr > pca_; pcl::PointCloud::Ptr principal_curvatures_; diff --git a/src/plugins/markov/mincut.cpp b/src/plugins/markov/mincut.cpp index c9844d8..90cba2f 100755 --- a/src/plugins/markov/mincut.cpp +++ b/src/plugins/markov/mincut.cpp @@ -400,7 +400,7 @@ MinCut::buildGraph () return (false); if (search_ == 0) - search_ = boost::shared_ptr > (new pcl::search::KdTree); + search_ = boost::shared_ptr > (new pcl::search::KdTree); graph_.reset (); graph_ = boost::shared_ptr< mGraph > (new mGraph ()); @@ -550,8 +550,8 @@ MinCut::calculateBinaryPotential (int source, int target) const double weight = 0.0; double distance = 0.0; - const pcl::PointXYZI & s = input_->points[source]; - const pcl::PointXYZI & t = input_->points[target]; + const pcl::PointXYZRGB & s = input_->points[source]; + const pcl::PointXYZRGB & t = input_->points[target]; distance = (s.getVector3fMap() - t.getVector3fMap()).squaredNorm(); distance *= inverse_sigma_; diff --git a/src/plugins/markov/mincut.h b/src/plugins/markov/mincut.h index d32ce81..0ebdd4d 100755 --- a/src/plugins/markov/mincut.h +++ b/src/plugins/markov/mincut.h @@ -14,9 +14,9 @@ class MinCut { public: - typedef pcl::search::Search KdTree; + typedef pcl::search::Search KdTree; typedef KdTree::Ptr KdTreePtr; - typedef pcl::PointCloud< pcl::PointXYZI > PointCloud; + typedef pcl::PointCloud< pcl::PointXYZRGB > PointCloud; typedef PointCloud::ConstPtr PointCloudConstPtr; diff --git a/src/plugins/normalestimation/normalestimation.cpp b/src/plugins/normalestimation/normalestimation.cpp index e335bd4..a578fac 100755 --- a/src/plugins/normalestimation/normalestimation.cpp +++ b/src/plugins/normalestimation/normalestimation.cpp @@ -425,7 +425,7 @@ NormalEstimator::estimateNormals(boost::shared_ptr cloud) { // Deal with missing normals here - pcl::KdTreeFLANN search; + pcl::KdTreeFLANN search; search.setInputCloud(cloud); int k = 50; diff --git a/src/plugins/outlierfilter/outlierfilter.cpp b/src/plugins/outlierfilter/outlierfilter.cpp index 6b2ce29..fc33f28 100755 --- a/src/plugins/outlierfilter/outlierfilter.cpp +++ b/src/plugins/outlierfilter/outlierfilter.cpp @@ -125,7 +125,7 @@ void OutlierFilter::filter() { // downsample std::vector big_to_small; - pcl::PointCloud::Ptr smallcloud = octreeDownsample(cloud.get(), (radius_*2)/100, big_to_small); + pcl::PointCloud::Ptr smallcloud = octreeDownsample(cloud.get(), (radius_*2)/100, big_to_small); // create small to big map std::vector> small_to_big(smallcloud->size()); @@ -146,7 +146,7 @@ void OutlierFilter::filter() { } } -// pcl::KdTreeFLANN search; +// pcl::KdTreeFLANN search; // search.setInputCloud(cloud); qDebug() << "radius:" << radius_; diff --git a/src/plugins/project/project.cpp b/src/plugins/project/project.cpp index bb94e42..9e5c068 100755 --- a/src/plugins/project/project.cpp +++ b/src/plugins/project/project.cpp @@ -266,13 +266,31 @@ void Project::load(QString filename){ if(version == 0) continue; + // just for rick + + std::vector selection_counts = {0, 0, 0, 0, 0, 0, 0, 0}; + // save selections uint8_t flags; for(int i = 0; i < labelcount; i++) { file >> flags; cloud->flags_[i] = PointFlags(flags); + + for(uint i = 0; i < 8; i++){ + if (flags & (1 << i)) { + selection_counts[i]++; + } + } + } + + uint sum = 0; + for(uint i = 0; i < 8; i++){ + qDebug() << i << ": " << selection_counts[i]; + sum += selection_counts[i]; } + qDebug() << "sum: " << sum; + } int layercount; diff --git a/src/pluginsystem/plugindeps.h b/src/pluginsystem/plugindeps.h index 1d4f23d..318478b 100755 --- a/src/pluginsystem/plugindeps.h +++ b/src/pluginsystem/plugindeps.h @@ -36,9 +36,9 @@ typedef boost::graph_traits< mGraph >::in_edge_iterator InEdgeIterator; void linkerhack(){ - pcl::search::KdTree wee; - pcl::search::Search * KdTree; + pcl::search::KdTree wee; + pcl::search::Search * KdTree; boost::shared_ptr graph_; graph_ = boost::shared_ptr< mGraph > (new mGraph ()); - pcl::PCA pc(false); + pcl::PCA pc(false); } diff --git a/src/utilities/cv.cpp b/src/utilities/cv.cpp index c589859..296ff21 100755 --- a/src/utilities/cv.cpp +++ b/src/utilities/cv.cpp @@ -29,7 +29,7 @@ boost::shared_ptr> makeDistmap( for(uint i = 0; i < cloud->size(); i++) { int grid_idx = cloud->cloudToGridMap()[i]; - pcl::PointXYZI & p = (*cloud)[i]; + pcl::PointXYZRGB & p = (*cloud)[i]; (*distmap)[grid_idx] = sqrt(pow(p.x, 2) + pow(p.y, 2) + pow(p.z, 2)); if((*distmap)[i] > max_dist) @@ -163,7 +163,7 @@ boost::shared_ptr > interpolate( return out_image; } -boost::shared_ptr > stdev_dist(pcl::PointCloud::Ptr cloud, +boost::shared_ptr > stdev_dist(pcl::PointCloud::Ptr cloud, const double radius, int max_nn, bool use_depth) { boost::shared_ptr> stdevs @@ -251,8 +251,8 @@ boost::shared_ptr > getHist(boost::shared_ptr > eigen_vals = boost::make_shared>(cloud->size()); - pcl::KdTreeFLANN search; - search.setInputCloud(pcl::PointCloud::ConstPtr(cloud.get(), boost::serialization::null_deleter())); + pcl::KdTreeFLANN search; + search.setInputCloud(pcl::PointCloud::ConstPtr(cloud.get(), boost::serialization::null_deleter())); QTime total; @@ -283,8 +283,8 @@ boost::shared_ptr > getHist(boost::shared_ptr pcEstimator(true); - pcl::PointCloud::ConstPtr const_cloud(cloud.get(), boost::serialization::null_deleter()); + pcl::PCA pcEstimator(true); + pcl::PointCloud::ConstPtr const_cloud(cloud.get(), boost::serialization::null_deleter()); pcEstimator.setInputCloud (const_cloud); pcEstimator.setIndices(kIdxs); (*eigen_vals)[i] = pcEstimator.getEigenValues(); diff --git a/src/utilities/cv.h b/src/utilities/cv.h index 81bbb2f..b9b85b3 100755 --- a/src/utilities/cv.h +++ b/src/utilities/cv.h @@ -64,7 +64,7 @@ UTIL_API boost::shared_ptr > interpolate( int w, int h, const int nsize, boost::shared_ptr> out_image = nullptr); -UTIL_API boost::shared_ptr > stdev_dist(pcl::PointCloud::Ptr cloud, +UTIL_API boost::shared_ptr > stdev_dist(pcl::PointCloud::Ptr cloud, const double radius, int max_nn = 0, bool use_depth = false); UTIL_API boost::shared_ptr> cloudToGrid(const std::vector & map, uint img_size, diff --git a/src/utilities/lasso.cpp b/src/utilities/lasso.cpp index 76074bc..db261fa 100755 --- a/src/utilities/lasso.cpp +++ b/src/utilities/lasso.cpp @@ -222,7 +222,7 @@ std::vector Lasso::getPoints() { void Lasso::getIndices(Eigen::Affine3f & proj, Eigen::Affine3f & mv, - pcl::PointCloud * cloud, + pcl::PointCloud * cloud, boost::shared_ptr > source_indices){ Eigen::Affine3f ndc_mat = proj * mv; @@ -240,7 +240,7 @@ void Lasso::getIndices(Eigen::Affine3f & proj, int view [4] = {0, 0, 1000, 1000}; - auto inside_lasso = [&] (pcl::PointXYZI & p) { + auto inside_lasso = [&] (pcl::PointXYZRGB & p) { /// project point Eigen::Vector4f p_4 = p.getVector4fMap(); p_4 = ndc_mat.matrix() * p_4; diff --git a/src/utilities/lasso.h b/src/utilities/lasso.h index 056eda0..4da5dd2 100755 --- a/src/utilities/lasso.h +++ b/src/utilities/lasso.h @@ -34,7 +34,7 @@ class UTIL_API Lasso std::vector getPolygon(); void getIndices(Eigen::Affine3f &proj, Eigen::Affine3f &mv, - pcl::PointCloud *cloud, + pcl::PointCloud *cloud, boost::shared_ptr > source_indices); void getIndices2D(int height, const Eigen::Affine2f & cam, const std::vector &cloud_to_grid_map, diff --git a/src/utilities/pointpicker.cpp b/src/utilities/pointpicker.cpp index acb0ce6..6daed7c 100755 --- a/src/utilities/pointpicker.cpp +++ b/src/utilities/pointpicker.cpp @@ -210,7 +210,7 @@ int pick(int win_x, int win_y, int win_width, int win_height, float max_dist, continue; } - pcl::PointXYZI & p = pc->points[i]; + pcl::PointXYZRGB & p = pc->points[i]; Eigen::Vector3f query_point = proj * mv * p.getVector3fMap(); query_point[2] = 0.0f; diff --git a/src/utilities/utils.cpp b/src/utilities/utils.cpp index 60176c2..b86b2f2 100755 --- a/src/utilities/utils.cpp +++ b/src/utilities/utils.cpp @@ -1,19 +1,21 @@ #include "utilities/utils.h" -pcl::PointCloud::Ptr zipNormals(pcl::PointCloud::Ptr cloud, +pcl::PointCloud::Ptr zipNormals(pcl::PointCloud::Ptr cloud, pcl::PointCloud::Ptr normals){ - pcl::PointCloud::Ptr zipped (new pcl::PointCloud()); + pcl::PointCloud::Ptr zipped (new pcl::PointCloud()); zipped->resize(cloud->size()); for(uint i = 0; i < cloud->size(); i ++){ - pcl::PointXYZI & p = (*cloud)[i]; + pcl::PointXYZRGB & p = (*cloud)[i]; pcl::Normal & n = (*normals)[i]; - pcl::PointXYZINormal & pn = (*zipped)[i]; + pcl::PointXYZRGBNormal & pn = (*zipped)[i]; pn.getNormalVector4fMap() = n.getNormalVector4fMap(); pn.getVector4fMap() = p.getVector4fMap(); - pn.intensity = p.intensity; + pn.r = p.r; + pn.g = p.g; + pn.b = p.b; } return zipped; diff --git a/src/utilities/utils.h b/src/utilities/utils.h index b76ead0..d5859b5 100755 --- a/src/utilities/utils.h +++ b/src/utilities/utils.h @@ -42,12 +42,9 @@ typename pcl::PointCloud::Ptr octreeDownsample( Eigen::Map pmap = Eigen::VectorXf::Map(&p.data[0], data_items); for(int idx : indices){ - - Eigen::Map pmap1 = Eigen::VectorXf::Map(reinterpret_cast(&((*input)[idx])), data_items); pmap += pmap1; sub_idxs[idx] = output->size(); - } float size_inv = 1.0/indices.size(); @@ -61,6 +58,78 @@ typename pcl::PointCloud::Ptr octreeDownsample( return output; } +pcl::PointCloud::Ptr octreeDownsample( + pcl::PointCloud * input, + float resolution, + std::vector & sub_idxs) { + + size_t data_items = sizeof(pcl::PointXYZRGBNormal)/sizeof(float); + + typename pcl::PointCloud::Ptr output(new pcl::PointCloud()); + sub_idxs.resize(input->size(), 0); + + typename pcl::PointCloud::Ptr ptr(input, boost::serialization::null_deleter()); + + typename pcl::octree::OctreePointCloud octree1(resolution); + octree1.setInputCloud (ptr); + octree1.addPointsFromInputCloud(); + + typename pcl::octree::OctreePointCloud::LeafNodeIterator it1; + typename pcl::octree::OctreePointCloud::LeafNodeIterator it1_end = octree1.leaf_end(); + + unsigned int leafNodeCounter = 0; + + for (it1 = octree1.leaf_begin(); it1 != it1_end; ++it1) { + std::vector & indices = it1.getLeafContainer().getPointIndicesVector(); + + int r = 0, g = 0, b = 0; + float x = 0.0f, y = 0.0f, z = 0.0f, intensity = 0.0f, nx = 0.0f, ny = 0.0f, nz = 0.0f; + + for(int idx : indices){ + + x += (*input)[idx].x; + y += (*input)[idx].y; + z += (*input)[idx].z; + intensity += (*input)[idx].data[3]; + nx += (*input)[idx].normal_x; + ny += (*input)[idx].normal_y; + nz += (*input)[idx].normal_z; + r += (*input)[idx].r; + g += (*input)[idx].g; + b += (*input)[idx].b; + + sub_idxs[idx] = output->size(); + } + + float size_inv = 1.0/indices.size(); + + pcl::PointXYZRGBNormal p; + + p.x = x*=size_inv; + p.y = y*=size_inv; + p.z = z*=size_inv; + p.data[3] = intensity*=size_inv; + p.normal_x = nx*=size_inv; + p.normal_y = ny*=size_inv; + p.normal_z = nz*=size_inv; + float t = sqrt(nx*nx + ny*ny + nz*nz); + p.normal_x /= t; + p.normal_y /= t; + p.normal_z /= t; + p.r = uint8_t(r*=size_inv); + p.g = uint8_t(g*=size_inv); + p.b = uint8_t(b*=size_inv); + + output->push_back(p); + + leafNodeCounter++; + } + + return output; +} + + + #undef small #ifdef small #error "small defined" @@ -86,7 +155,7 @@ void map_small_to_big( } -UTIL_API pcl::PointCloud::Ptr zipNormals(pcl::PointCloud::Ptr cloud, +UTIL_API pcl::PointCloud::Ptr zipNormals(pcl::PointCloud::Ptr cloud, pcl::PointCloud::Ptr normals); #endif // ULTILITIES_UTILS_H