scikit-image

Форк
0
1261 строка · 40.2 Кб
1
import numpy as np
2
from numpy.testing import assert_array_equal, assert_equal, assert_almost_equal
3
import pytest
4

5
from skimage._shared.testing import run_in_parallel
6
from skimage._shared._dependency_checks import has_mpl
7

8
from skimage.draw import (
9
    set_color,
10
    line,
11
    line_aa,
12
    polygon,
13
    polygon_perimeter,
14
    disk,
15
    circle_perimeter,
16
    circle_perimeter_aa,
17
    ellipse,
18
    ellipse_perimeter,
19
    _bezier_segment,
20
    bezier_curve,
21
    rectangle,
22
    rectangle_perimeter,
23
)
24
from skimage.measure import regionprops
25

26

27
def test_set_color():
28
    img = np.zeros((10, 10))
29

30
    rr, cc = line(0, 0, 0, 30)
31
    set_color(img, (rr, cc), 1)
32

33
    img_ = np.zeros((10, 10))
34
    img_[0, :] = 1
35

36
    assert_array_equal(img, img_)
37

38

39
def test_set_color_with_alpha():
40
    img = np.zeros((10, 10))
41

42
    rr, cc, alpha = line_aa(0, 0, 0, 30)
43
    set_color(img, (rr, cc), 1, alpha=alpha)
44

45
    # Wrong dimensionality color
46
    with pytest.raises(ValueError):
47
        set_color(img, (rr, cc), (255, 0, 0), alpha=alpha)
48

49
    img = np.zeros((10, 10, 3))
50

51
    rr, cc, alpha = line_aa(0, 0, 0, 30)
52
    set_color(img, (rr, cc), (1, 0, 0), alpha=alpha)
53

54

55
@run_in_parallel()
56
def test_line_horizontal():
57
    img = np.zeros((10, 10))
58

59
    rr, cc = line(0, 0, 0, 9)
60
    img[rr, cc] = 1
61

62
    img_ = np.zeros((10, 10))
63
    img_[0, :] = 1
64

65
    assert_array_equal(img, img_)
66

67

68
def test_line_vertical():
69
    img = np.zeros((10, 10))
70

71
    rr, cc = line(0, 0, 9, 0)
72
    img[rr, cc] = 1
73

74
    img_ = np.zeros((10, 10))
75
    img_[:, 0] = 1
76

77
    assert_array_equal(img, img_)
78

79

80
def test_line_reverse():
81
    img = np.zeros((10, 10))
82

83
    rr, cc = line(0, 9, 0, 0)
84
    img[rr, cc] = 1
85

86
    img_ = np.zeros((10, 10))
87
    img_[0, :] = 1
88

89
    assert_array_equal(img, img_)
90

91

92
def test_line_diag():
93
    img = np.zeros((5, 5))
94

95
    rr, cc = line(0, 0, 4, 4)
96
    img[rr, cc] = 1
97

98
    img_ = np.eye(5)
99

100
    assert_array_equal(img, img_)
101

102

103
def test_line_aa_horizontal():
104
    img = np.zeros((10, 10))
105

106
    rr, cc, val = line_aa(0, 0, 0, 9)
107
    set_color(img, (rr, cc), 1, alpha=val)
108

109
    img_ = np.zeros((10, 10))
110
    img_[0, :] = 1
111

112
    assert_array_equal(img, img_)
113

114

115
def test_line_aa_vertical():
116
    img = np.zeros((10, 10))
117

118
    rr, cc, val = line_aa(0, 0, 9, 0)
119
    img[rr, cc] = val
120

121
    img_ = np.zeros((10, 10))
122
    img_[:, 0] = 1
123

124
    assert_array_equal(img, img_)
125

126

127
def test_line_aa_diagonal():
128
    img = np.zeros((10, 10))
129

130
    rr, cc, val = line_aa(0, 0, 9, 6)
131
    img[rr, cc] = 1
132

133
    # Check that each pixel belonging to line,
134
    # also belongs to line_aa
135
    r, c = line(0, 0, 9, 6)
136
    for r_i, c_i in zip(r, c):
137
        assert_equal(img[r_i, c_i], 1)
138

139

140
def test_line_equal_aliasing_horizontally_vertically():
141
    img0 = np.zeros((25, 25))
142
    img1 = np.zeros((25, 25))
143

144
    # Near-horizontal line
145
    rr, cc, val = line_aa(10, 2, 12, 20)
146
    img0[rr, cc] = val
147

148
    # Near-vertical (transpose of prior)
149
    rr, cc, val = line_aa(2, 10, 20, 12)
150
    img1[rr, cc] = val
151

152
    # Difference - should be zero
153
    assert_array_equal(img0, img1.T)
154

155

156
def test_polygon_rectangle():
157
    img = np.zeros((10, 10), 'uint8')
158
    poly = np.array(((1, 1), (4, 1), (4, 4), (1, 4), (1, 1)))
159

160
    rr, cc = polygon(poly[:, 0], poly[:, 1])
161
    img[rr, cc] = 1
162

163
    img_ = np.zeros((10, 10), 'uint8')
164
    img_[1:5, 1:5] = 1
165

166
    assert_array_equal(img, img_)
167

168

169
def test_polygon_rectangle_angular():
170
    img = np.zeros((10, 10), 'uint8')
171
    poly = np.array(((0, 3), (4, 7), (7, 4), (3, 0), (0, 3)))
172

173
    rr, cc = polygon(poly[:, 0], poly[:, 1])
174
    img[rr, cc] = 1
175

176
    img_ = np.array(
177
        [
178
            [0, 0, 0, 1, 0, 0, 0, 0, 0, 0],
179
            [0, 0, 1, 1, 1, 0, 0, 0, 0, 0],
180
            [0, 1, 1, 1, 1, 1, 0, 0, 0, 0],
181
            [1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
182
            [0, 1, 1, 1, 1, 1, 1, 1, 0, 0],
183
            [0, 0, 1, 1, 1, 1, 1, 0, 0, 0],
184
            [0, 0, 0, 1, 1, 1, 0, 0, 0, 0],
185
            [0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
186
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
187
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
188
        ],
189
        'uint8',
190
    )
191

192
    assert_array_equal(img, img_)
193

194

195
def test_polygon_parallelogram():
196
    img = np.zeros((10, 10), 'uint8')
197
    poly = np.array(((1, 1), (5, 1), (7, 6), (3, 6), (1, 1)))
198

199
    rr, cc = polygon(poly[:, 0], poly[:, 1])
200
    img[rr, cc] = 1
201

202
    img_ = np.array(
203
        [
204
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
205
            [0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
206
            [0, 1, 1, 1, 0, 0, 0, 0, 0, 0],
207
            [0, 1, 1, 1, 1, 1, 1, 0, 0, 0],
208
            [0, 1, 1, 1, 1, 1, 1, 0, 0, 0],
209
            [0, 1, 1, 1, 1, 1, 1, 0, 0, 0],
210
            [0, 0, 0, 0, 1, 1, 1, 0, 0, 0],
211
            [0, 0, 0, 0, 0, 0, 1, 0, 0, 0],
212
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
213
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
214
        ],
215
        'uint8',
216
    )
217

218
    assert_array_equal(img, img_)
219

220

221
def test_polygon_exceed():
222
    img = np.zeros((10, 10), 'uint8')
223
    poly = np.array(((1, -1), (100, -1), (100, 100), (1, 100), (1, 1)))
224

225
    rr, cc = polygon(poly[:, 0], poly[:, 1], img.shape)
226
    img[rr, cc] = 1
227

228
    img_ = np.zeros((10, 10))
229
    img_[1:, :] = 1
230

231
    assert_array_equal(img, img_)
232

233

234
def test_polygon_0d_input():
235
    # Bug reported in #4938: 0d input causes segfault.
236
    rr, cc = polygon(0, 1)
237

238
    assert rr.size == cc.size == 1
239

240

241
def test_disk():
242
    img = np.zeros((15, 15), 'uint8')
243

244
    rr, cc = disk((7, 7), 6)
245
    img[rr, cc] = 1
246

247
    img_ = np.array(
248
        [
249
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
250
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
251
            [0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0],
252
            [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
253
            [0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
254
            [0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
255
            [0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
256
            [0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
257
            [0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
258
            [0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
259
            [0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
260
            [0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
261
            [0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0],
262
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
263
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
264
        ]
265
    )
266

267
    assert_array_equal(img, img_)
268

269

270
def test_circle_perimeter_bresenham():
271
    img = np.zeros((15, 15), 'uint8')
272
    rr, cc = circle_perimeter(7, 7, 0, method='bresenham')
273
    img[rr, cc] = 1
274
    assert np.sum(img) == 1
275
    assert img[7][7] == 1
276

277
    img = np.zeros((17, 15), 'uint8')
278
    rr, cc = circle_perimeter(7, 7, 7, method='bresenham')
279
    img[rr, cc] = 1
280
    img_ = np.array(
281
        [
282
            [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0],
283
            [0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0],
284
            [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0],
285
            [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0],
286
            [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0],
287
            [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
288
            [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
289
            [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
290
            [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
291
            [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
292
            [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0],
293
            [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0],
294
            [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0],
295
            [0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0],
296
            [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0],
297
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
298
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
299
        ]
300
    )
301
    assert_array_equal(img, img_)
302

303

304
def test_circle_perimeter_bresenham_shape():
305
    img = np.zeros((15, 20), 'uint8')
306
    rr, cc = circle_perimeter(7, 10, 9, method='bresenham', shape=(15, 20))
307
    img[rr, cc] = 1
308
    shift = 5
309
    img_ = np.zeros((15 + 2 * shift, 20), 'uint8')
310
    rr, cc = circle_perimeter(7 + shift, 10, 9, method='bresenham', shape=None)
311
    img_[rr, cc] = 1
312
    assert_array_equal(img, img_[shift:-shift, :])
313

314

315
def test_circle_perimeter_andres():
316
    img = np.zeros((15, 15), 'uint8')
317
    rr, cc = circle_perimeter(7, 7, 0, method='andres')
318
    img[rr, cc] = 1
319
    assert np.sum(img) == 1
320
    assert img[7][7] == 1
321

322
    img = np.zeros((17, 15), 'uint8')
323
    rr, cc = circle_perimeter(7, 7, 7, method='andres')
324
    img[rr, cc] = 1
325
    img_ = np.array(
326
        [
327
            [0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0],
328
            [0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0],
329
            [0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0],
330
            [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0],
331
            [1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1],
332
            [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
333
            [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
334
            [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
335
            [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
336
            [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
337
            [1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1],
338
            [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0],
339
            [0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0],
340
            [0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0],
341
            [0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0],
342
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
343
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
344
        ]
345
    )
346
    assert_array_equal(img, img_)
347

348

349
def test_circle_perimeter_aa():
350
    img = np.zeros((15, 15), 'uint8')
351
    rr, cc, val = circle_perimeter_aa(7, 7, 0)
352
    img[rr, cc] = 1
353
    assert np.sum(img) == 1
354
    assert img[7][7] == 1
355

356
    img = np.zeros((17, 17), 'uint8')
357
    rr, cc, val = circle_perimeter_aa(8, 8, 7)
358
    img[rr, cc] = val * 255
359
    # fmt: off
360
    img_ = np.array(
361
        [[  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0],
362
         [  0,   0,   0,   0,   0,  82, 180, 236, 255, 236, 180,  82,   0,   0,   0,   0,   0],
363
         [  0,   0,   0,   0, 189, 172,  74,  18,   0,  18,  74, 172, 189,   0,   0,   0,   0],
364
         [  0,   0,   0, 229,  25,   0,   0,   0,   0,   0,   0,   0,  25, 229,   0,   0,   0],
365
         [  0,   0, 189,  25,   0,   0,   0,   0,   0,   0,   0,   0,   0,  25, 189,   0,   0],
366
         [  0,  82, 172,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 172,  82,   0],
367
         [  0, 180,  74,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  74, 180,   0],
368
         [  0, 236,  18,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  18, 236,   0],
369
         [  0, 255,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 255,   0],
370
         [  0, 236,  18,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  18, 236,   0],
371
         [  0, 180,  74,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  74, 180,   0],
372
         [  0,  82, 172,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 172,  82,   0],
373
         [  0,   0, 189,  25,   0,   0,   0,   0,   0,   0,   0,   0,   0,  25, 189,   0,   0],
374
         [  0,   0,   0, 229,  25,   0,   0,   0,   0,   0,   0,   0,  25, 229,   0,   0,   0],
375
         [  0,   0,   0,   0, 189, 172,  74,  18,   0,  18,  74, 172, 189,   0,   0,   0,   0],
376
         [  0,   0,   0,   0,   0,  82, 180, 236, 255, 236, 180,  82,   0,   0,   0,   0,   0],
377
         [  0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0]]
378
    )
379
    # fmt: on
380
    assert_array_equal(img, img_)
381

382

383
def test_circle_perimeter_aa_shape():
384
    img = np.zeros((15, 20), 'uint8')
385
    rr, cc, val = circle_perimeter_aa(7, 10, 9, shape=(15, 20))
386
    img[rr, cc] = val * 255
387

388
    shift = 5
389
    img_ = np.zeros((15 + 2 * shift, 20), 'uint8')
390
    rr, cc, val = circle_perimeter_aa(7 + shift, 10, 9, shape=None)
391
    img_[rr, cc] = val * 255
392
    assert_array_equal(img, img_[shift:-shift, :])
393

394

395
def test_ellipse_trivial():
396
    img = np.zeros((2, 2), 'uint8')
397
    rr, cc = ellipse(0.5, 0.5, 0.5, 0.5)
398
    img[rr, cc] = 1
399
    img_correct = np.array([[0, 0], [0, 0]])
400
    assert_array_equal(img, img_correct)
401

402
    img = np.zeros((2, 2), 'uint8')
403
    rr, cc = ellipse(0.5, 0.5, 1.1, 1.1)
404
    img[rr, cc] = 1
405
    img_correct = np.array(
406
        [
407
            [1, 1],
408
            [1, 1],
409
        ]
410
    )
411
    assert_array_equal(img, img_correct)
412

413
    img = np.zeros((3, 3), 'uint8')
414
    rr, cc = ellipse(1, 1, 0.9, 0.9)
415
    img[rr, cc] = 1
416
    img_correct = np.array(
417
        [
418
            [0, 0, 0],
419
            [0, 1, 0],
420
            [0, 0, 0],
421
        ]
422
    )
423
    assert_array_equal(img, img_correct)
424

425
    img = np.zeros((3, 3), 'uint8')
426
    rr, cc = ellipse(1, 1, 1.1, 1.1)
427
    img[rr, cc] = 1
428
    img_correct = np.array(
429
        [
430
            [0, 1, 0],
431
            [1, 1, 1],
432
            [0, 1, 0],
433
        ]
434
    )
435
    assert_array_equal(img, img_correct)
436

437
    img = np.zeros((3, 3), 'uint8')
438
    rr, cc = ellipse(1, 1, 1.5, 1.5)
439
    img[rr, cc] = 1
440
    img_correct = np.array(
441
        [
442
            [1, 1, 1],
443
            [1, 1, 1],
444
            [1, 1, 1],
445
        ]
446
    )
447
    assert_array_equal(img, img_correct)
448

449

450
def test_ellipse_generic():
451
    img = np.zeros((4, 4), 'uint8')
452
    rr, cc = ellipse(1.5, 1.5, 1.1, 1.7)
453
    img[rr, cc] = 1
454
    img_ = np.array(
455
        [
456
            [0, 0, 0, 0],
457
            [1, 1, 1, 1],
458
            [1, 1, 1, 1],
459
            [0, 0, 0, 0],
460
        ]
461
    )
462
    assert_array_equal(img, img_)
463

464
    img = np.zeros((5, 5), 'uint8')
465
    rr, cc = ellipse(2, 2, 1.7, 1.7)
466
    img[rr, cc] = 1
467
    img_ = np.array(
468
        [
469
            [0, 0, 0, 0, 0],
470
            [0, 1, 1, 1, 0],
471
            [0, 1, 1, 1, 0],
472
            [0, 1, 1, 1, 0],
473
            [0, 0, 0, 0, 0],
474
        ]
475
    )
476
    assert_array_equal(img, img_)
477

478
    img = np.zeros((10, 10), 'uint8')
479
    rr, cc = ellipse(5, 5, 3, 4)
480
    img[rr, cc] = 1
481
    img_ = np.array(
482
        [
483
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
484
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
485
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
486
            [0, 0, 0, 1, 1, 1, 1, 1, 0, 0],
487
            [0, 0, 1, 1, 1, 1, 1, 1, 1, 0],
488
            [0, 0, 1, 1, 1, 1, 1, 1, 1, 0],
489
            [0, 0, 1, 1, 1, 1, 1, 1, 1, 0],
490
            [0, 0, 0, 1, 1, 1, 1, 1, 0, 0],
491
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
492
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
493
        ]
494
    )
495
    assert_array_equal(img, img_)
496

497
    img = np.zeros((10, 10), 'uint8')
498
    rr, cc = ellipse(4.5, 5, 3.5, 4)
499
    img[rr, cc] = 1
500
    img_ = np.array(
501
        [
502
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
503
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
504
            [0, 0, 0, 1, 1, 1, 1, 1, 0, 0],
505
            [0, 0, 1, 1, 1, 1, 1, 1, 1, 0],
506
            [0, 0, 1, 1, 1, 1, 1, 1, 1, 0],
507
            [0, 0, 1, 1, 1, 1, 1, 1, 1, 0],
508
            [0, 0, 1, 1, 1, 1, 1, 1, 1, 0],
509
            [0, 0, 0, 1, 1, 1, 1, 1, 0, 0],
510
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
511
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
512
        ]
513
    )
514
    assert_array_equal(img, img_)
515

516
    img = np.zeros((15, 15), 'uint8')
517
    rr, cc = ellipse(7, 7, 3, 7)
518
    img[rr, cc] = 1
519
    img_ = np.array(
520
        [
521
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
522
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
523
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
524
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
525
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
526
            [0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
527
            [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
528
            [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
529
            [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
530
            [0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
531
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
532
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
533
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
534
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
535
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
536
        ]
537
    )
538
    assert_array_equal(img, img_)
539

540

541
def test_ellipse_with_shape():
542
    img = np.zeros((15, 15), 'uint8')
543

544
    rr, cc = ellipse(7, 7, 3, 10, shape=img.shape)
545
    img[rr, cc] = 1
546

547
    img_ = np.array(
548
        [
549
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
550
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
551
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
552
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
553
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
554
            [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
555
            [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
556
            [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
557
            [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
558
            [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
559
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
560
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
561
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
562
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
563
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
564
        ]
565
    )
566

567
    assert_array_equal(img, img_)
568

569
    img = np.zeros((10, 9, 3), 'uint8')
570

571
    rr, cc = ellipse(7, 7, 3, 10, shape=img.shape)
572
    img[rr, cc, 0] = 1
573

574
    img_ = np.zeros_like(img)
575
    img_[..., 0] = np.array(
576
        [
577
            [0, 0, 0, 0, 0, 0, 0, 0, 0],
578
            [0, 0, 0, 0, 0, 0, 0, 0, 0],
579
            [0, 0, 0, 0, 0, 0, 0, 0, 0],
580
            [0, 0, 0, 0, 0, 0, 0, 0, 0],
581
            [0, 0, 0, 0, 0, 0, 0, 0, 0],
582
            [1, 1, 1, 1, 1, 1, 1, 1, 1],
583
            [1, 1, 1, 1, 1, 1, 1, 1, 1],
584
            [1, 1, 1, 1, 1, 1, 1, 1, 1],
585
            [1, 1, 1, 1, 1, 1, 1, 1, 1],
586
            [1, 1, 1, 1, 1, 1, 1, 1, 1],
587
        ],
588
    )
589

590
    assert_array_equal(img, img_)
591

592

593
def test_ellipse_negative():
594
    rr, cc = ellipse(-3, -3, 1.7, 1.7)
595
    rr_, cc_ = np.nonzero(
596
        np.array(
597
            [
598
                [0, 0, 0, 0, 0],
599
                [0, 1, 1, 1, 0],
600
                [0, 1, 1, 1, 0],
601
                [0, 1, 1, 1, 0],
602
                [0, 0, 0, 0, 0],
603
            ]
604
        )
605
    )
606

607
    assert_array_equal(rr, rr_ - 5)
608
    assert_array_equal(cc, cc_ - 5)
609

610

611
def test_ellipse_rotation_symmetry():
612
    img1 = np.zeros((150, 150), dtype=np.uint8)
613
    img2 = np.zeros((150, 150), dtype=np.uint8)
614
    for angle in range(0, 180, 15):
615
        img1.fill(0)
616
        rr, cc = ellipse(80, 70, 60, 40, rotation=np.deg2rad(angle))
617
        img1[rr, cc] = 1
618
        img2.fill(0)
619
        rr, cc = ellipse(80, 70, 60, 40, rotation=np.deg2rad(angle + 180))
620
        img2[rr, cc] = 1
621
        assert_array_equal(img1, img2)
622

623

624
def test_ellipse_rotated():
625
    img = np.zeros((1000, 1200), dtype=np.uint8)
626
    for rot in range(0, 180, 10):
627
        img.fill(0)
628
        angle = np.deg2rad(rot)
629
        rr, cc = ellipse(500, 600, 200, 400, rotation=angle)
630
        img[rr, cc] = 1
631
        # estimate orientation of ellipse
632
        angle_estim_raw = regionprops(img)[0].orientation
633
        angle_estim = np.round(angle_estim_raw, 3) % (np.pi / 2)
634
        assert_almost_equal(angle_estim, angle % (np.pi / 2), 2)
635

636

637
def test_ellipse_perimeter_dot_zeroangle():
638
    # dot, angle == 0
639
    img = np.zeros((30, 15), 'uint8')
640
    rr, cc = ellipse_perimeter(15, 7, 0, 0, 0)
641
    img[rr, cc] = 1
642
    assert np.sum(img) == 1
643
    assert img[15][7] == 1
644

645

646
def test_ellipse_perimeter_dot_nzeroangle():
647
    # dot, angle != 0
648
    img = np.zeros((30, 15), 'uint8')
649
    rr, cc = ellipse_perimeter(15, 7, 0, 0, 1)
650
    img[rr, cc] = 1
651
    assert np.sum(img) == 1
652
    assert img[15][7] == 1
653

654

655
def test_ellipse_perimeter_flat_zeroangle():
656
    # flat ellipse
657
    img = np.zeros((20, 18), 'uint8')
658
    img_ = np.zeros((20, 18), 'uint8')
659
    rr, cc = ellipse_perimeter(6, 7, 0, 5, 0)
660
    img[rr, cc] = 1
661
    rr, cc = line(6, 2, 6, 12)
662
    img_[rr, cc] = 1
663
    assert_array_equal(img, img_)
664

665

666
def test_ellipse_perimeter_zeroangle():
667
    # angle == 0
668
    img = np.zeros((30, 15), 'uint8')
669
    rr, cc = ellipse_perimeter(15, 7, 14, 6, 0)
670
    img[rr, cc] = 1
671
    img_ = np.array(
672
        [
673
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
674
            [0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0],
675
            [0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0],
676
            [0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0],
677
            [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0],
678
            [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0],
679
            [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0],
680
            [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0],
681
            [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0],
682
            [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0],
683
            [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0],
684
            [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0],
685
            [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0],
686
            [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0],
687
            [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0],
688
            [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0],
689
            [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0],
690
            [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0],
691
            [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0],
692
            [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0],
693
            [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0],
694
            [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0],
695
            [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0],
696
            [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0],
697
            [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0],
698
            [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0],
699
            [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0],
700
            [0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0],
701
            [0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0],
702
            [0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0],
703
        ]
704
    )
705

706
    assert_array_equal(img, img_)
707

708

709
def test_ellipse_perimeter_nzeroangle():
710
    # angle != 0
711
    img = np.zeros((30, 25), 'uint8')
712
    rr, cc = ellipse_perimeter(15, 11, 12, 6, 1.1)
713
    img[rr, cc] = 1
714
    img_ = np.array(
715
        [
716
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
717
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
718
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
719
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
720
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
721
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
722
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0],
723
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0],
724
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0],
725
            [0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0],
726
            [0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0],
727
            [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0],
728
            [0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0],
729
            [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0],
730
            [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0],
731
            [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0],
732
            [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
733
            [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0],
734
            [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0],
735
            [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
736
            [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
737
            [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
738
            [0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
739
            [0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
740
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
741
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
742
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
743
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
744
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
745
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
746
        ]
747
    )
748
    assert_array_equal(img, img_)
749

750

751
def test_ellipse_perimeter_shape():
752
    img = np.zeros((15, 20), 'uint8')
753
    rr, cc = ellipse_perimeter(7, 10, 9, 9, 0, shape=(15, 20))
754
    img[rr, cc] = 1
755
    shift = 5
756
    img_ = np.zeros((15 + 2 * shift, 20), 'uint8')
757
    rr, cc = ellipse_perimeter(7 + shift, 10, 9, 9, 0, shape=None)
758
    img_[rr, cc] = 1
759
    assert_array_equal(img, img_[shift:-shift, :])
760

761

762
def test_bezier_segment_straight():
763
    image = np.zeros((200, 200), dtype=int)
764
    r0, r1, r2 = 50, 150, 150
765
    c0, c1, c2 = 50, 50, 150
766
    rr, cc = _bezier_segment(r0, c0, r1, c1, r2, c2, 0)
767
    image[rr, cc] = 1
768

769
    image2 = np.zeros((200, 200), dtype=int)
770
    rr, cc = line(r0, c0, r2, c2)
771
    image2[rr, cc] = 1
772
    assert_array_equal(image, image2)
773

774

775
def test_bezier_segment_curved():
776
    img = np.zeros((25, 25), 'uint8')
777
    r0, c0 = 20, 20
778
    r1, c1 = 20, 2
779
    r2, c2 = 2, 2
780
    rr, cc = _bezier_segment(r0, c0, r1, c1, r2, c2, 1)
781
    img[rr, cc] = 1
782
    img_ = np.array(
783
        [
784
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
785
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
786
            [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
787
            [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
788
            [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
789
            [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
790
            [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
791
            [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
792
            [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
793
            [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
794
            [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
795
            [0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
796
            [0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
797
            [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
798
            [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
799
            [0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
800
            [0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
801
            [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
802
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
803
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
804
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0],
805
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
806
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
807
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
808
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
809
        ]
810
    )
811
    assert_equal(img[r0, c0], 1)
812
    assert_equal(img[r2, c2], 1)
813
    assert_array_equal(img, img_)
814

815

816
def test_bezier_curve_straight():
817
    image = np.zeros((200, 200), dtype=int)
818
    r0, c0 = 50, 50
819
    r1, c1 = 150, 50
820
    r2, c2 = 150, 150
821
    rr, cc = bezier_curve(r0, c0, r1, c1, r2, c2, 0)
822
    image[rr, cc] = 1
823

824
    image2 = np.zeros((200, 200), dtype=int)
825
    rr, cc = line(r0, c0, r2, c2)
826
    image2[rr, cc] = 1
827
    assert_array_equal(image, image2)
828

829

830
def test_bezier_curved_weight_eq_1():
831
    img = np.zeros((23, 8), 'uint8')
832
    r0, c0 = 1, 1
833
    r1, c1 = 11, 11
834
    r2, c2 = 21, 1
835
    rr, cc = bezier_curve(r0, c0, r1, c1, r2, c2, 1)
836
    img[rr, cc] = 1
837
    assert_equal(img[r0, c0], 1)
838
    assert_equal(img[r2, c2], 1)
839
    img_ = np.array(
840
        [
841
            [0, 0, 0, 0, 0, 0, 0, 0],
842
            [0, 1, 0, 0, 0, 0, 0, 0],
843
            [0, 0, 1, 0, 0, 0, 0, 0],
844
            [0, 0, 0, 1, 0, 0, 0, 0],
845
            [0, 0, 0, 0, 1, 0, 0, 0],
846
            [0, 0, 0, 0, 1, 0, 0, 0],
847
            [0, 0, 0, 0, 0, 1, 0, 0],
848
            [0, 0, 0, 0, 0, 1, 0, 0],
849
            [0, 0, 0, 0, 0, 0, 1, 0],
850
            [0, 0, 0, 0, 0, 0, 1, 0],
851
            [0, 0, 0, 0, 0, 0, 1, 0],
852
            [0, 0, 0, 0, 0, 0, 1, 0],
853
            [0, 0, 0, 0, 0, 0, 1, 0],
854
            [0, 0, 0, 0, 0, 0, 1, 0],
855
            [0, 0, 0, 0, 0, 0, 1, 0],
856
            [0, 0, 0, 0, 0, 1, 0, 0],
857
            [0, 0, 0, 0, 0, 1, 0, 0],
858
            [0, 0, 0, 0, 1, 0, 0, 0],
859
            [0, 0, 0, 0, 1, 0, 0, 0],
860
            [0, 0, 0, 1, 0, 0, 0, 0],
861
            [0, 0, 1, 0, 0, 0, 0, 0],
862
            [0, 1, 0, 0, 0, 0, 0, 0],
863
            [0, 0, 0, 0, 0, 0, 0, 0],
864
        ]
865
    )
866
    assert_equal(img, img_)
867

868

869
def test_bezier_curved_weight_neq_1():
870
    img = np.zeros((23, 10), 'uint8')
871
    r0, c0 = 1, 1
872
    r1, c1 = 11, 11
873
    r2, c2 = 21, 1
874
    rr, cc = bezier_curve(r0, c0, r1, c1, r2, c2, 2)
875
    img[rr, cc] = 1
876
    assert_equal(img[r0, c0], 1)
877
    assert_equal(img[r2, c2], 1)
878
    img_ = np.array(
879
        [
880
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
881
            [0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
882
            [0, 0, 1, 0, 0, 0, 0, 0, 0, 0],
883
            [0, 0, 0, 1, 0, 0, 0, 0, 0, 0],
884
            [0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
885
            [0, 0, 0, 0, 0, 1, 0, 0, 0, 0],
886
            [0, 0, 0, 0, 0, 0, 1, 0, 0, 0],
887
            [0, 0, 0, 0, 0, 0, 1, 0, 0, 0],
888
            [0, 0, 0, 0, 0, 0, 0, 1, 0, 0],
889
            [0, 0, 0, 0, 0, 0, 0, 0, 1, 0],
890
            [0, 0, 0, 0, 0, 0, 0, 0, 1, 0],
891
            [0, 0, 0, 0, 0, 0, 0, 0, 1, 0],
892
            [0, 0, 0, 0, 0, 0, 0, 0, 1, 0],
893
            [0, 0, 0, 0, 0, 0, 0, 0, 1, 0],
894
            [0, 0, 0, 0, 0, 0, 0, 1, 0, 0],
895
            [0, 0, 0, 0, 0, 0, 1, 0, 0, 0],
896
            [0, 0, 0, 0, 0, 0, 1, 0, 0, 0],
897
            [0, 0, 0, 0, 0, 1, 0, 0, 0, 0],
898
            [0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
899
            [0, 0, 0, 1, 0, 0, 0, 0, 0, 0],
900
            [0, 0, 1, 0, 0, 0, 0, 0, 0, 0],
901
            [0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
902
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
903
        ]
904
    )
905
    assert_equal(img, img_)
906

907

908
def test_bezier_curve_shape():
909
    img = np.zeros((15, 20), 'uint8')
910
    r0, c0 = 1, 5
911
    r1, c1 = 6, 11
912
    r2, c2 = 1, 14
913
    rr, cc = bezier_curve(r0, c0, r1, c1, r2, c2, 2, shape=(15, 20))
914
    img[rr, cc] = 1
915
    shift = 5
916
    img_ = np.zeros((15 + 2 * shift, 20), 'uint8')
917
    r0, c0 = 1 + shift, 5
918
    r1, c1 = 6 + shift, 11
919
    r2, c2 = 1 + shift, 14
920
    rr, cc = bezier_curve(r0, c0, r1, c1, r2, c2, 2, shape=None)
921
    img_[rr, cc] = 1
922
    assert_array_equal(img, img_[shift:-shift, :])
923

924

925
@pytest.mark.skipif(not has_mpl, reason="matplotlib not installed")
926
def test_polygon_perimeter():
927
    expected = np.array([[1, 1, 1, 1], [1, 0, 0, 1], [1, 1, 1, 1]])
928
    out = np.zeros_like(expected)
929

930
    rr, cc = polygon_perimeter([0, 2, 2, 0], [0, 0, 3, 3])
931

932
    out[rr, cc] = 1
933
    assert_array_equal(out, expected)
934

935
    out = np.zeros_like(expected)
936
    rr, cc = polygon_perimeter(
937
        [-1, -1, 3, 3], [-1, 4, 4, -1], shape=out.shape, clip=True
938
    )
939
    out[rr, cc] = 1
940
    assert_array_equal(out, expected)
941

942
    with pytest.raises(ValueError):
943
        polygon_perimeter([0], [1], clip=True)
944

945

946
@pytest.mark.skipif(not has_mpl, reason="matplotlib not installed")
947
def test_polygon_perimeter_outside_image():
948
    rr, cc = polygon_perimeter([-1, -1, 3, 3], [-1, 4, 4, -1], shape=(3, 4))
949
    assert_equal(len(rr), 0)
950
    assert_equal(len(cc), 0)
951

952

953
def test_rectangle_end():
954
    expected = np.array(
955
        [
956
            [0, 1, 1, 1, 0],
957
            [0, 1, 1, 1, 0],
958
            [0, 1, 1, 1, 0],
959
            [0, 1, 1, 1, 0],
960
            [0, 0, 0, 0, 0],
961
        ],
962
        dtype=np.uint8,
963
    )
964
    start = (0, 1)
965
    end = (3, 3)
966
    img = np.zeros((5, 5), dtype=np.uint8)
967
    rr, cc = rectangle(start, end=end, shape=img.shape)
968
    img[rr, cc] = 1
969
    assert_array_equal(img, expected)
970

971
    # Swap start and end
972
    img = np.zeros((5, 5), dtype=np.uint8)
973
    rr, cc = rectangle(end=start, start=end, shape=img.shape)
974
    img[rr, cc] = 1
975
    assert_array_equal(img, expected)
976

977
    # Bottom left and top right
978
    img = np.zeros((5, 5), dtype=np.uint8)
979
    rr, cc = rectangle(start=(3, 1), end=(0, 3), shape=img.shape)
980
    img[rr, cc] = 1
981
    assert_array_equal(img, expected)
982

983
    img = np.zeros((5, 5), dtype=np.uint8)
984
    rr, cc = rectangle(end=(3, 1), start=(0, 3), shape=img.shape)
985
    img[rr, cc] = 1
986
    assert_array_equal(img, expected)
987

988

989
def test_rectangle_float_input():
990
    expected = np.array(
991
        [
992
            [0, 1, 1, 1, 0],
993
            [0, 1, 1, 1, 0],
994
            [0, 1, 1, 1, 0],
995
            [0, 1, 1, 1, 0],
996
            [0, 0, 0, 0, 0],
997
        ],
998
        dtype=np.uint8,
999
    )
1000
    start = (0.2, 0.8)
1001
    end = (3.1, 2.9)
1002
    img = np.zeros((5, 5), dtype=np.uint8)
1003
    rr, cc = rectangle(start, end=end, shape=img.shape)
1004
    img[rr, cc] = 1
1005
    assert_array_equal(img, expected)
1006

1007
    # Swap start and end
1008
    img = np.zeros((5, 5), dtype=np.uint8)
1009
    rr, cc = rectangle(end=start, start=end, shape=img.shape)
1010
    img[rr, cc] = 1
1011
    assert_array_equal(img, expected)
1012

1013
    # Bottom left and top right
1014
    img = np.zeros((5, 5), dtype=np.uint8)
1015
    rr, cc = rectangle(start=(3.1, 0.8), end=(0.2, 2.9), shape=img.shape)
1016
    img[rr, cc] = 1
1017
    assert_array_equal(img, expected)
1018

1019
    img = np.zeros((5, 5), dtype=np.uint8)
1020
    rr, cc = rectangle(end=(3.1, 0.8), start=(0.2, 2.9), shape=img.shape)
1021
    img[rr, cc] = 1
1022
    assert_array_equal(img, expected)
1023

1024

1025
def test_rectangle_extent():
1026
    expected = np.array(
1027
        [
1028
            [0, 0, 0, 0, 0],
1029
            [0, 1, 1, 1, 0],
1030
            [0, 1, 1, 1, 0],
1031
            [0, 1, 1, 1, 0],
1032
            [0, 0, 0, 0, 0],
1033
        ],
1034
        dtype=np.uint8,
1035
    )
1036
    start = (1, 1)
1037
    extent = (3, 3)
1038
    img = np.zeros((5, 5), dtype=np.uint8)
1039
    rr, cc = rectangle(start, extent=extent, shape=img.shape)
1040
    img[rr, cc] = 1
1041
    assert_array_equal(img, expected)
1042

1043
    img = np.zeros((5, 5, 3), dtype=np.uint8)
1044
    rr, cc = rectangle(start, extent=extent, shape=img.shape)
1045
    img[rr, cc, 0] = 1
1046
    expected_2 = np.zeros_like(img)
1047
    expected_2[..., 0] = expected
1048
    assert_array_equal(img, expected_2)
1049

1050

1051
@pytest.mark.skipif(not has_mpl, reason="matplotlib not installed")
1052
def test_rectangle_extent_negative():
1053
    # These two tests should be done together.
1054
    expected = np.array(
1055
        [
1056
            [0, 0, 0, 0, 0, 0],
1057
            [0, 0, 1, 1, 1, 1],
1058
            [0, 0, 1, 2, 2, 1],
1059
            [0, 0, 1, 1, 1, 1],
1060
            [0, 0, 0, 0, 0, 0],
1061
        ],
1062
        dtype=np.uint8,
1063
    )
1064

1065
    start = (3, 5)
1066
    extent = (-1, -2)
1067
    img = np.zeros(expected.shape, dtype=np.uint8)
1068
    rr, cc = rectangle_perimeter(start, extent=extent, shape=img.shape)
1069
    img[rr, cc] = 1
1070

1071
    rr, cc = rectangle(start, extent=extent, shape=img.shape)
1072
    img[rr, cc] = 2
1073
    assert_array_equal(img, expected)
1074

1075
    # Ensure that rr and cc have no overlap
1076
    img = np.zeros(expected.shape, dtype=np.uint8)
1077
    rr, cc = rectangle(start, extent=extent, shape=img.shape)
1078
    img[rr, cc] = 2
1079

1080
    rr, cc = rectangle_perimeter(start, extent=extent, shape=img.shape)
1081
    img[rr, cc] = 1
1082
    assert_array_equal(img, expected)
1083

1084

1085
@pytest.mark.skipif(not has_mpl, reason="matplotlib not installed")
1086
def test_rectangle_perimiter():
1087
    expected = np.array(
1088
        [
1089
            [0, 0, 0, 0, 0, 0],
1090
            [0, 0, 1, 1, 1, 1],
1091
            [0, 0, 1, 0, 0, 1],
1092
            [0, 0, 1, 1, 1, 1],
1093
            [0, 0, 0, 0, 0, 0],
1094
        ],
1095
        dtype=np.uint8,
1096
    )
1097
    start = (2, 3)
1098
    end = (2, 4)
1099
    img = np.zeros(expected.shape, dtype=np.uint8)
1100
    # Test that the default parameter is indeed end
1101
    rr, cc = rectangle_perimeter(start, end, shape=img.shape)
1102
    img[rr, cc] = 1
1103
    assert_array_equal(img, expected)
1104

1105
    # Swap start and end
1106
    img = np.zeros(expected.shape, dtype=np.uint8)
1107
    rr, cc = rectangle_perimeter(end=start, start=end, shape=img.shape)
1108
    img[rr, cc] = 1
1109
    assert_array_equal(img, expected)
1110

1111
    img = np.zeros(expected.shape, dtype=np.uint8)
1112
    start = (2, 3)
1113
    extent = (1, 2)
1114
    rr, cc = rectangle_perimeter(start, extent=extent, shape=img.shape)
1115
    img[rr, cc] = 1
1116
    assert_array_equal(img, expected)
1117

1118

1119
@pytest.mark.skipif(not has_mpl, reason="matplotlib not installed")
1120
def test_rectangle_perimiter_clip_bottom_right():
1121
    # clip=False
1122
    expected = np.array(
1123
        [
1124
            [0, 0, 0, 0, 0],
1125
            [0, 1, 1, 1, 1],
1126
            [0, 1, 0, 0, 0],
1127
            [0, 1, 0, 0, 0],
1128
            [0, 1, 0, 0, 0],
1129
        ],
1130
        dtype=np.uint8,
1131
    )
1132
    img = np.zeros((5, 5), dtype=np.uint8)
1133
    start = (2, 2)
1134
    extent = (10, 10)
1135
    rr, cc = rectangle_perimeter(start, extent=extent, shape=img.shape, clip=False)
1136
    img[rr, cc] = 1
1137
    assert_array_equal(img, expected)
1138

1139
    # clip=True
1140
    expected = np.array(
1141
        [
1142
            [0, 0, 0, 0, 0],
1143
            [0, 1, 1, 1, 1],
1144
            [0, 1, 0, 0, 1],
1145
            [0, 1, 0, 0, 1],
1146
            [0, 1, 1, 1, 1],
1147
        ],
1148
        dtype=np.uint8,
1149
    )
1150
    img = np.zeros((5, 5), dtype=np.uint8)
1151
    rr, cc = rectangle_perimeter(start, extent=extent, shape=img.shape, clip=True)
1152
    img[rr, cc] = 1
1153
    assert_array_equal(img, expected)
1154

1155

1156
@pytest.mark.skipif(not has_mpl, reason="matplotlib not installed")
1157
def test_rectangle_perimiter_clip_top_left():
1158
    # clip=False
1159
    expected = np.array(
1160
        [
1161
            [0, 0, 0, 1, 0],
1162
            [0, 0, 0, 1, 0],
1163
            [0, 0, 0, 1, 0],
1164
            [1, 1, 1, 1, 0],
1165
            [0, 0, 0, 0, 0],
1166
        ],
1167
        dtype=np.uint8,
1168
    )
1169
    img = np.zeros((5, 5), dtype=np.uint8)
1170
    start = (-5, -5)
1171
    end = (2, 2)
1172
    rr, cc = rectangle_perimeter(start, end=end, shape=img.shape, clip=False)
1173
    img[rr, cc] = 1
1174
    assert_array_equal(img, expected)
1175

1176
    # clip=True
1177
    expected = np.array(
1178
        [
1179
            [1, 1, 1, 1, 0],
1180
            [1, 0, 0, 1, 0],
1181
            [1, 0, 0, 1, 0],
1182
            [1, 1, 1, 1, 0],
1183
            [0, 0, 0, 0, 0],
1184
        ],
1185
        dtype=np.uint8,
1186
    )
1187
    img = np.zeros((5, 5), dtype=np.uint8)
1188
    rr, cc = rectangle_perimeter(start, end=end, shape=img.shape, clip=True)
1189
    img[rr, cc] = 1
1190
    assert_array_equal(img, expected)
1191

1192

1193
@pytest.mark.skipif(not has_mpl, reason="matplotlib not installed")
1194
def test_rectangle_perimiter_clip_top_right():
1195
    expected = np.array(
1196
        [
1197
            [0, 1, 1, 1, 1],
1198
            [0, 1, 0, 0, 1],
1199
            [0, 1, 0, 0, 1],
1200
            [0, 1, 1, 1, 1],
1201
            [0, 0, 0, 0, 0],
1202
        ],
1203
        dtype=np.uint8,
1204
    )
1205
    img = np.zeros((5, 5), dtype=np.uint8)
1206
    start = (-10, 2)
1207
    end = (2, 10)
1208
    rr, cc = rectangle_perimeter(start, end=end, shape=img.shape, clip=True)
1209
    img[rr, cc] = 1
1210
    assert_array_equal(img, expected)
1211

1212
    expected = np.array(
1213
        [
1214
            [0, 1, 0, 0, 0],
1215
            [0, 1, 0, 0, 0],
1216
            [0, 1, 0, 0, 0],
1217
            [0, 1, 1, 1, 1],
1218
            [0, 0, 0, 0, 0],
1219
        ],
1220
        dtype=np.uint8,
1221
    )
1222
    img = np.zeros((5, 5), dtype=np.uint8)
1223
    rr, cc = rectangle_perimeter(start, end=end, shape=img.shape, clip=False)
1224
    img[rr, cc] = 1
1225
    assert_array_equal(img, expected)
1226

1227

1228
@pytest.mark.skipif(not has_mpl, reason="matplotlib not installed")
1229
def test_rectangle_perimiter_clip_bottom_left():
1230
    expected = np.array(
1231
        [
1232
            [0, 0, 0, 0, 0],
1233
            [1, 1, 1, 0, 0],
1234
            [1, 0, 1, 0, 0],
1235
            [1, 0, 1, 0, 0],
1236
            [1, 1, 1, 0, 0],
1237
        ],
1238
        dtype=np.uint8,
1239
    )
1240
    img = np.zeros((5, 5), dtype=np.uint8)
1241
    start = (2, -3)
1242
    end = (10, 1)
1243
    rr, cc = rectangle_perimeter(start, end=end, shape=img.shape, clip=True)
1244
    img[rr, cc] = 1
1245
    assert_array_equal(img, expected)
1246

1247
    expected = np.array(
1248
        [
1249
            [0, 0, 0, 0, 0],
1250
            [1, 1, 1, 0, 0],
1251
            [0, 0, 1, 0, 0],
1252
            [0, 0, 1, 0, 0],
1253
            [0, 0, 1, 0, 0],
1254
        ],
1255
        dtype=np.uint8,
1256
    )
1257

1258
    img = np.zeros((5, 5), dtype=np.uint8)
1259
    rr, cc = rectangle_perimeter(start, end=end, shape=img.shape, clip=False)
1260
    img[rr, cc] = 1
1261
    assert_array_equal(img, expected)
1262

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.