|
1
|
|
|
import pcl |
|
2
|
|
|
from patty.segmentation.dbscan import (get_largest_dbscan_clusters, |
|
3
|
|
|
_get_top_labels, dbscan_labels) |
|
4
|
|
|
import numpy as np |
|
5
|
|
|
import unittest |
|
6
|
|
|
from nose.tools import assert_equal, assert_equals |
|
7
|
|
|
|
|
8
|
|
|
|
|
9
|
|
|
def test_largest_dbscan_clusters(): |
|
10
|
|
|
"""get_largest_dbscan_clusters returns at least desired fragment of |
|
11
|
|
|
points""" |
|
12
|
|
|
# Arrange |
|
13
|
|
|
pc = get_one_big_and_10_small_clusters() |
|
14
|
|
|
desired_fragment = 0.7 |
|
15
|
|
|
expected = pc.size * desired_fragment |
|
16
|
|
|
|
|
17
|
|
|
# Act |
|
18
|
|
|
segmentedpc = get_largest_dbscan_clusters( |
|
19
|
|
|
pc, min_return_fragment=desired_fragment, epsilon=3., minpoints=5) |
|
20
|
|
|
segmented = segmentedpc.to_array() |
|
21
|
|
|
|
|
22
|
|
|
# Assert |
|
23
|
|
|
actual = segmented.shape[0] |
|
24
|
|
|
message = 'expected: %r, actual: %r' % (expected, actual) |
|
25
|
|
|
assert_equals(actual, expected, msg=message) |
|
26
|
|
|
|
|
27
|
|
|
|
|
28
|
|
|
def get_one_big_and_10_small_clusters(): |
|
29
|
|
|
'''Create clusters as advertised''' |
|
30
|
|
|
ar = np.empty([0, 3], dtype=np.float32) |
|
31
|
|
|
rn = np.random.RandomState(1234) |
|
32
|
|
|
big = rn.randn(100, 3) + 10 |
|
33
|
|
|
ar = np.vstack([ar, big]) |
|
34
|
|
|
for i in range(0, 10): |
|
35
|
|
|
small = rn.rand(10, 3) - (10 * i) |
|
36
|
|
|
ar = np.vstack([ar, small]) |
|
37
|
|
|
pc = pcl.PointCloud(ar.astype(np.float32)) |
|
38
|
|
|
return pc |
|
39
|
|
|
|
|
40
|
|
|
|
|
41
|
|
|
def test_get_top_labels(): |
|
42
|
|
|
'''Test _get_top_labels function from patty.segmentation.dbscan''' |
|
43
|
|
|
# With outliers |
|
44
|
|
|
labels = np.array([0, 0, 0, -1, -1, 0, 1, 1, 2, 3]) |
|
45
|
|
|
assert_equal(_get_top_labels(labels, .6), ([0, 1], 6)) |
|
46
|
|
|
|
|
47
|
|
|
# Without outliers |
|
48
|
|
|
labels = np.array([0, 1, 0, 0, 2, 2, 0, 0, 2, 2]) |
|
49
|
|
|
assert_equal(_get_top_labels(labels, .6), ([0, 2], 9)) |
|
50
|
|
|
|
|
51
|
|
|
|
|
52
|
|
|
class Dbscan_labels(unittest.TestCase): |
|
53
|
|
|
|
|
54
|
|
|
def setUp(self): |
|
55
|
|
|
self.pc = pcl.PointCloudXYZRGB( |
|
56
|
|
|
[[0.0, 0.0, 0.0, 1.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0, 0.0]]) |
|
57
|
|
|
|
|
58
|
|
|
def test_dbscan_labels(self): |
|
59
|
|
|
'''Points with different color should be one cluster with |
|
60
|
|
|
rgb_weight = 0''' |
|
61
|
|
|
labels = dbscan_labels(self.pc, 0.1, 1, rgb_weight=0) |
|
62
|
|
|
labelcount = len(np.unique(labels)) |
|
63
|
|
|
assert_equals(labelcount, 1) |
|
64
|
|
|
|
|
65
|
|
|
def test_dbscan_labels_colored(self): |
|
66
|
|
|
'''Points with different color should be two clusters with |
|
67
|
|
|
rgb_weight = 1''' |
|
68
|
|
|
labels = dbscan_labels(self.pc, 0.1, 1, rgb_weight=1) |
|
69
|
|
|
labelcount = len(np.unique(labels)) |
|
70
|
|
|
assert_equals(labelcount, 2) |
|
71
|
|
|
|