tests.TestStickScale   A
last analyzed

Complexity

Total Complexity 2

Size/Duplication

Total Lines 13
Duplicated Lines 0 %
Metric Value
dl 0
loc 13
rs 10
wmc 2

2 Methods

Rating   Name   Duplication   Size   Complexity  
A test_stickscale_nocluster() 0 5 1
A test_stickscale_emptycloud() 0 5 1
1
from patty.registration import get_stick_scale
2
from patty.registration.stickscale import get_confidence_level
3
from patty.segmentation import get_red_mask
4
from patty import load, extract_mask
5
from nose_parameterized import parameterized
6
7
from nose.tools import assert_greater, assert_less
8
9
from helpers import make_red_stick, _add_noise
10
import pcl
11
import numpy as np
12
import unittest
13
14
15
# The ground truths for these tests was defined by measuring stick segments,
16
# either white or red, by hand, in Meshlab.
17
# Note: failing instances commented out. Uncomment them for testing out
18
# new methods.
19
# @parameterized.expand([
20
# ("SITE9", 'redstick_SITE_9.ply', 11.45),
21
# ("SITE11", 'redstick_SITE_11.ply', 2.925),
22
# ("SITE12", 'redstick_SITE_12.ply', 10.85),
23
24
# only one segment visible
25
# ("SITE13", 'redstick_SITE_13.ply', 4.35),
26
27
# hardly anything of a segment is visible
28
# ("SITE14", 'redstick_SITE_14.ply', 1.07),
29
30
# ("SITE15", 'redstick_SITE_15.ply', 2.0),
31
32
# no red segments completely visible
33
# ("SITE16", 'redstick_SITE_16.ply', 5.13),
34
35
# one complete stick segment, one partly that contains more points (!)
36
# ("SITE19", 'redstick_SITE_19.ply', 3.15),
37
38
# ("SITE20", 'redstick_SITE_20.ply', 5.55),
39
# ("SITE21", 'redstick_SITE_21.ply', 5.4),
40
# ])
41
42
43
def make_pointcloud(sticks, noise):
44
    data = np.array(np.concatenate(sticks, axis=0), dtype=np.float32)
45
    _add_noise(data, noise, np.random.RandomState(0))
46
    pc = pcl.PointCloudXYZRGB(data)
47
    return extract_mask(pc, get_red_mask(pc))
48
49
50
@parameterized.expand([(0.01,), (0.02,), (0.05,), (0.1,)])
51
def test_stickscale(noise):
52
    s1 = make_red_stick([0, 0, 0], [0, 1, 0])
53
    s2 = make_red_stick([1, 2, 0], [1, 1, 0])
54
    s3 = make_red_stick([3, 3, 0], [3, 4, 0])
55
    pc = make_pointcloud((s1, s2, s3), noise)
56
    meter, confidence = get_stick_scale(pc)
57
    red_part_length = 0.25 + noise
58
    assert_with_error(meter, 4 * red_part_length / 0.8)
59
    assert_with_error(confidence, 1.0)
60
61
62
@parameterized.expand([
63
    (500, 3, 1.0),
64
    (100, 3, 1.0 / 5.0),
65
    (500, 2, 2.0 / 3.0),
66
    (500, 1, 1.0 / 3.0),
67
    (100, 2, min(1.0 / 5.0, 2.0 / 3.0)),
68
])
69
def test_confidence(votes, numberOfClusters, expected_confidence):
70
    confidence = get_confidence_level(votes, numberOfClusters)
71
    assert_with_error(confidence, expected_confidence)
72
73
74
# The ground truths for these tests was defined by measuring stick segments,
75
# either white or red, by hand, in Meshlab. """
76
@parameterized.expand([
77
    # ("SITE9", 'redstick_SITE_9.ply', 11.45, True),
78
    # ("SITE11", 'redstick_SITE_11.ply', 2.925, True),
79
    # ("SITE12", 'redstick_SITE_12.ply', 10.85, True),
80
    # ("SITE13", 'redstick_SITE_13.ply', 4.35, False),
81
    # # only one segment visible
82
    # ("SITE14", 'redstick_SITE_14.ply', 1.07, False),
83
    # # hardly anything of a segment is visible
84
    # ("SITE15", 'redstick_SITE_15.ply', 2.0, True),
85
    # ("SITE16", 'redstick_SITE_16.ply', 5.13, False),
86
    # # no red segments completely visible
87
    # ("SITE19", 'redstick_SITE_19.ply', 3.15, False),
88
    # # one complete stick segment, and one partly that contains more points
89
    # # (!)
90
    # ("SITE20", 'redstick_SITE_20.ply', 5.55, True),
91
    # ("SITE21", 'redstick_SITE_21.ply', 5.4, True)
92
])
93
def test_actual_data_confidence(name, filename, expected_meter,
94
                                expect_confident):
95
    pc = load('tests/testdata/' + filename)
96
    meter, confidence = get_stick_scale(pc)
97
    if expect_confident:
98
        assert_greater(confidence, .5, "confidence too low")
99
    else:
100
        assert_less(confidence, .5, "confidence too high")
101
102
103
def assert_with_error(estimated, expected):
104
    error_ratio = 0.05
105
    margin = error_ratio * expected
106
    message = ('Value does not match expected value with %f%% (%f) margin.'
107
               '\nEstimated: %f\nExpected: %f' % (100 * error_ratio,
108
                                                  margin, estimated, expected))
109
    assert_less(abs(estimated - expected), margin, message)
110
111
112
class TestStickScale(unittest.TestCase):
113
114
    def test_stickscale_emptycloud(noise):
115
        '''Cloud with zero point should return zero confidence.'''
116
        pc = pcl.PointCloudXYZRGB()
117
        meter, confidence = get_stick_scale(pc)
118
        np.testing.assert_almost_equal(confidence, 0.0)
119
120
    def test_stickscale_nocluster(noise):
121
        '''Cloud without clusters should return zero confidence.'''
122
        pc = pcl.PointCloudXYZRGB([[0, 0, 0], [10000, 10000, 10000]])
123
        meter, confidence = get_stick_scale(pc)
124
        np.testing.assert_almost_equal(confidence, 0.0)
125