scikit-image
1261 строка · 40.2 Кб
1import numpy as np
2from numpy.testing import assert_array_equal, assert_equal, assert_almost_equal
3import pytest
4
5from skimage._shared.testing import run_in_parallel
6from skimage._shared._dependency_checks import has_mpl
7
8from skimage.draw import (
9set_color,
10line,
11line_aa,
12polygon,
13polygon_perimeter,
14disk,
15circle_perimeter,
16circle_perimeter_aa,
17ellipse,
18ellipse_perimeter,
19_bezier_segment,
20bezier_curve,
21rectangle,
22rectangle_perimeter,
23)
24from skimage.measure import regionprops
25
26
27def test_set_color():
28img = np.zeros((10, 10))
29
30rr, cc = line(0, 0, 0, 30)
31set_color(img, (rr, cc), 1)
32
33img_ = np.zeros((10, 10))
34img_[0, :] = 1
35
36assert_array_equal(img, img_)
37
38
39def test_set_color_with_alpha():
40img = np.zeros((10, 10))
41
42rr, cc, alpha = line_aa(0, 0, 0, 30)
43set_color(img, (rr, cc), 1, alpha=alpha)
44
45# Wrong dimensionality color
46with pytest.raises(ValueError):
47set_color(img, (rr, cc), (255, 0, 0), alpha=alpha)
48
49img = np.zeros((10, 10, 3))
50
51rr, cc, alpha = line_aa(0, 0, 0, 30)
52set_color(img, (rr, cc), (1, 0, 0), alpha=alpha)
53
54
55@run_in_parallel()
56def test_line_horizontal():
57img = np.zeros((10, 10))
58
59rr, cc = line(0, 0, 0, 9)
60img[rr, cc] = 1
61
62img_ = np.zeros((10, 10))
63img_[0, :] = 1
64
65assert_array_equal(img, img_)
66
67
68def test_line_vertical():
69img = np.zeros((10, 10))
70
71rr, cc = line(0, 0, 9, 0)
72img[rr, cc] = 1
73
74img_ = np.zeros((10, 10))
75img_[:, 0] = 1
76
77assert_array_equal(img, img_)
78
79
80def test_line_reverse():
81img = np.zeros((10, 10))
82
83rr, cc = line(0, 9, 0, 0)
84img[rr, cc] = 1
85
86img_ = np.zeros((10, 10))
87img_[0, :] = 1
88
89assert_array_equal(img, img_)
90
91
92def test_line_diag():
93img = np.zeros((5, 5))
94
95rr, cc = line(0, 0, 4, 4)
96img[rr, cc] = 1
97
98img_ = np.eye(5)
99
100assert_array_equal(img, img_)
101
102
103def test_line_aa_horizontal():
104img = np.zeros((10, 10))
105
106rr, cc, val = line_aa(0, 0, 0, 9)
107set_color(img, (rr, cc), 1, alpha=val)
108
109img_ = np.zeros((10, 10))
110img_[0, :] = 1
111
112assert_array_equal(img, img_)
113
114
115def test_line_aa_vertical():
116img = np.zeros((10, 10))
117
118rr, cc, val = line_aa(0, 0, 9, 0)
119img[rr, cc] = val
120
121img_ = np.zeros((10, 10))
122img_[:, 0] = 1
123
124assert_array_equal(img, img_)
125
126
127def test_line_aa_diagonal():
128img = np.zeros((10, 10))
129
130rr, cc, val = line_aa(0, 0, 9, 6)
131img[rr, cc] = 1
132
133# Check that each pixel belonging to line,
134# also belongs to line_aa
135r, c = line(0, 0, 9, 6)
136for r_i, c_i in zip(r, c):
137assert_equal(img[r_i, c_i], 1)
138
139
140def test_line_equal_aliasing_horizontally_vertically():
141img0 = np.zeros((25, 25))
142img1 = np.zeros((25, 25))
143
144# Near-horizontal line
145rr, cc, val = line_aa(10, 2, 12, 20)
146img0[rr, cc] = val
147
148# Near-vertical (transpose of prior)
149rr, cc, val = line_aa(2, 10, 20, 12)
150img1[rr, cc] = val
151
152# Difference - should be zero
153assert_array_equal(img0, img1.T)
154
155
156def test_polygon_rectangle():
157img = np.zeros((10, 10), 'uint8')
158poly = np.array(((1, 1), (4, 1), (4, 4), (1, 4), (1, 1)))
159
160rr, cc = polygon(poly[:, 0], poly[:, 1])
161img[rr, cc] = 1
162
163img_ = np.zeros((10, 10), 'uint8')
164img_[1:5, 1:5] = 1
165
166assert_array_equal(img, img_)
167
168
169def test_polygon_rectangle_angular():
170img = np.zeros((10, 10), 'uint8')
171poly = np.array(((0, 3), (4, 7), (7, 4), (3, 0), (0, 3)))
172
173rr, cc = polygon(poly[:, 0], poly[:, 1])
174img[rr, cc] = 1
175
176img_ = 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
192assert_array_equal(img, img_)
193
194
195def test_polygon_parallelogram():
196img = np.zeros((10, 10), 'uint8')
197poly = np.array(((1, 1), (5, 1), (7, 6), (3, 6), (1, 1)))
198
199rr, cc = polygon(poly[:, 0], poly[:, 1])
200img[rr, cc] = 1
201
202img_ = 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
218assert_array_equal(img, img_)
219
220
221def test_polygon_exceed():
222img = np.zeros((10, 10), 'uint8')
223poly = np.array(((1, -1), (100, -1), (100, 100), (1, 100), (1, 1)))
224
225rr, cc = polygon(poly[:, 0], poly[:, 1], img.shape)
226img[rr, cc] = 1
227
228img_ = np.zeros((10, 10))
229img_[1:, :] = 1
230
231assert_array_equal(img, img_)
232
233
234def test_polygon_0d_input():
235# Bug reported in #4938: 0d input causes segfault.
236rr, cc = polygon(0, 1)
237
238assert rr.size == cc.size == 1
239
240
241def test_disk():
242img = np.zeros((15, 15), 'uint8')
243
244rr, cc = disk((7, 7), 6)
245img[rr, cc] = 1
246
247img_ = 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
267assert_array_equal(img, img_)
268
269
270def test_circle_perimeter_bresenham():
271img = np.zeros((15, 15), 'uint8')
272rr, cc = circle_perimeter(7, 7, 0, method='bresenham')
273img[rr, cc] = 1
274assert np.sum(img) == 1
275assert img[7][7] == 1
276
277img = np.zeros((17, 15), 'uint8')
278rr, cc = circle_perimeter(7, 7, 7, method='bresenham')
279img[rr, cc] = 1
280img_ = 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)
301assert_array_equal(img, img_)
302
303
304def test_circle_perimeter_bresenham_shape():
305img = np.zeros((15, 20), 'uint8')
306rr, cc = circle_perimeter(7, 10, 9, method='bresenham', shape=(15, 20))
307img[rr, cc] = 1
308shift = 5
309img_ = np.zeros((15 + 2 * shift, 20), 'uint8')
310rr, cc = circle_perimeter(7 + shift, 10, 9, method='bresenham', shape=None)
311img_[rr, cc] = 1
312assert_array_equal(img, img_[shift:-shift, :])
313
314
315def test_circle_perimeter_andres():
316img = np.zeros((15, 15), 'uint8')
317rr, cc = circle_perimeter(7, 7, 0, method='andres')
318img[rr, cc] = 1
319assert np.sum(img) == 1
320assert img[7][7] == 1
321
322img = np.zeros((17, 15), 'uint8')
323rr, cc = circle_perimeter(7, 7, 7, method='andres')
324img[rr, cc] = 1
325img_ = 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)
346assert_array_equal(img, img_)
347
348
349def test_circle_perimeter_aa():
350img = np.zeros((15, 15), 'uint8')
351rr, cc, val = circle_perimeter_aa(7, 7, 0)
352img[rr, cc] = 1
353assert np.sum(img) == 1
354assert img[7][7] == 1
355
356img = np.zeros((17, 17), 'uint8')
357rr, cc, val = circle_perimeter_aa(8, 8, 7)
358img[rr, cc] = val * 255
359# fmt: off
360img_ = 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
380assert_array_equal(img, img_)
381
382
383def test_circle_perimeter_aa_shape():
384img = np.zeros((15, 20), 'uint8')
385rr, cc, val = circle_perimeter_aa(7, 10, 9, shape=(15, 20))
386img[rr, cc] = val * 255
387
388shift = 5
389img_ = np.zeros((15 + 2 * shift, 20), 'uint8')
390rr, cc, val = circle_perimeter_aa(7 + shift, 10, 9, shape=None)
391img_[rr, cc] = val * 255
392assert_array_equal(img, img_[shift:-shift, :])
393
394
395def test_ellipse_trivial():
396img = np.zeros((2, 2), 'uint8')
397rr, cc = ellipse(0.5, 0.5, 0.5, 0.5)
398img[rr, cc] = 1
399img_correct = np.array([[0, 0], [0, 0]])
400assert_array_equal(img, img_correct)
401
402img = np.zeros((2, 2), 'uint8')
403rr, cc = ellipse(0.5, 0.5, 1.1, 1.1)
404img[rr, cc] = 1
405img_correct = np.array(
406[
407[1, 1],
408[1, 1],
409]
410)
411assert_array_equal(img, img_correct)
412
413img = np.zeros((3, 3), 'uint8')
414rr, cc = ellipse(1, 1, 0.9, 0.9)
415img[rr, cc] = 1
416img_correct = np.array(
417[
418[0, 0, 0],
419[0, 1, 0],
420[0, 0, 0],
421]
422)
423assert_array_equal(img, img_correct)
424
425img = np.zeros((3, 3), 'uint8')
426rr, cc = ellipse(1, 1, 1.1, 1.1)
427img[rr, cc] = 1
428img_correct = np.array(
429[
430[0, 1, 0],
431[1, 1, 1],
432[0, 1, 0],
433]
434)
435assert_array_equal(img, img_correct)
436
437img = np.zeros((3, 3), 'uint8')
438rr, cc = ellipse(1, 1, 1.5, 1.5)
439img[rr, cc] = 1
440img_correct = np.array(
441[
442[1, 1, 1],
443[1, 1, 1],
444[1, 1, 1],
445]
446)
447assert_array_equal(img, img_correct)
448
449
450def test_ellipse_generic():
451img = np.zeros((4, 4), 'uint8')
452rr, cc = ellipse(1.5, 1.5, 1.1, 1.7)
453img[rr, cc] = 1
454img_ = 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)
462assert_array_equal(img, img_)
463
464img = np.zeros((5, 5), 'uint8')
465rr, cc = ellipse(2, 2, 1.7, 1.7)
466img[rr, cc] = 1
467img_ = 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)
476assert_array_equal(img, img_)
477
478img = np.zeros((10, 10), 'uint8')
479rr, cc = ellipse(5, 5, 3, 4)
480img[rr, cc] = 1
481img_ = 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)
495assert_array_equal(img, img_)
496
497img = np.zeros((10, 10), 'uint8')
498rr, cc = ellipse(4.5, 5, 3.5, 4)
499img[rr, cc] = 1
500img_ = 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)
514assert_array_equal(img, img_)
515
516img = np.zeros((15, 15), 'uint8')
517rr, cc = ellipse(7, 7, 3, 7)
518img[rr, cc] = 1
519img_ = 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)
538assert_array_equal(img, img_)
539
540
541def test_ellipse_with_shape():
542img = np.zeros((15, 15), 'uint8')
543
544rr, cc = ellipse(7, 7, 3, 10, shape=img.shape)
545img[rr, cc] = 1
546
547img_ = 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
567assert_array_equal(img, img_)
568
569img = np.zeros((10, 9, 3), 'uint8')
570
571rr, cc = ellipse(7, 7, 3, 10, shape=img.shape)
572img[rr, cc, 0] = 1
573
574img_ = np.zeros_like(img)
575img_[..., 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
590assert_array_equal(img, img_)
591
592
593def test_ellipse_negative():
594rr, cc = ellipse(-3, -3, 1.7, 1.7)
595rr_, cc_ = np.nonzero(
596np.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
607assert_array_equal(rr, rr_ - 5)
608assert_array_equal(cc, cc_ - 5)
609
610
611def test_ellipse_rotation_symmetry():
612img1 = np.zeros((150, 150), dtype=np.uint8)
613img2 = np.zeros((150, 150), dtype=np.uint8)
614for angle in range(0, 180, 15):
615img1.fill(0)
616rr, cc = ellipse(80, 70, 60, 40, rotation=np.deg2rad(angle))
617img1[rr, cc] = 1
618img2.fill(0)
619rr, cc = ellipse(80, 70, 60, 40, rotation=np.deg2rad(angle + 180))
620img2[rr, cc] = 1
621assert_array_equal(img1, img2)
622
623
624def test_ellipse_rotated():
625img = np.zeros((1000, 1200), dtype=np.uint8)
626for rot in range(0, 180, 10):
627img.fill(0)
628angle = np.deg2rad(rot)
629rr, cc = ellipse(500, 600, 200, 400, rotation=angle)
630img[rr, cc] = 1
631# estimate orientation of ellipse
632angle_estim_raw = regionprops(img)[0].orientation
633angle_estim = np.round(angle_estim_raw, 3) % (np.pi / 2)
634assert_almost_equal(angle_estim, angle % (np.pi / 2), 2)
635
636
637def test_ellipse_perimeter_dot_zeroangle():
638# dot, angle == 0
639img = np.zeros((30, 15), 'uint8')
640rr, cc = ellipse_perimeter(15, 7, 0, 0, 0)
641img[rr, cc] = 1
642assert np.sum(img) == 1
643assert img[15][7] == 1
644
645
646def test_ellipse_perimeter_dot_nzeroangle():
647# dot, angle != 0
648img = np.zeros((30, 15), 'uint8')
649rr, cc = ellipse_perimeter(15, 7, 0, 0, 1)
650img[rr, cc] = 1
651assert np.sum(img) == 1
652assert img[15][7] == 1
653
654
655def test_ellipse_perimeter_flat_zeroangle():
656# flat ellipse
657img = np.zeros((20, 18), 'uint8')
658img_ = np.zeros((20, 18), 'uint8')
659rr, cc = ellipse_perimeter(6, 7, 0, 5, 0)
660img[rr, cc] = 1
661rr, cc = line(6, 2, 6, 12)
662img_[rr, cc] = 1
663assert_array_equal(img, img_)
664
665
666def test_ellipse_perimeter_zeroangle():
667# angle == 0
668img = np.zeros((30, 15), 'uint8')
669rr, cc = ellipse_perimeter(15, 7, 14, 6, 0)
670img[rr, cc] = 1
671img_ = 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
706assert_array_equal(img, img_)
707
708
709def test_ellipse_perimeter_nzeroangle():
710# angle != 0
711img = np.zeros((30, 25), 'uint8')
712rr, cc = ellipse_perimeter(15, 11, 12, 6, 1.1)
713img[rr, cc] = 1
714img_ = 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)
748assert_array_equal(img, img_)
749
750
751def test_ellipse_perimeter_shape():
752img = np.zeros((15, 20), 'uint8')
753rr, cc = ellipse_perimeter(7, 10, 9, 9, 0, shape=(15, 20))
754img[rr, cc] = 1
755shift = 5
756img_ = np.zeros((15 + 2 * shift, 20), 'uint8')
757rr, cc = ellipse_perimeter(7 + shift, 10, 9, 9, 0, shape=None)
758img_[rr, cc] = 1
759assert_array_equal(img, img_[shift:-shift, :])
760
761
762def test_bezier_segment_straight():
763image = np.zeros((200, 200), dtype=int)
764r0, r1, r2 = 50, 150, 150
765c0, c1, c2 = 50, 50, 150
766rr, cc = _bezier_segment(r0, c0, r1, c1, r2, c2, 0)
767image[rr, cc] = 1
768
769image2 = np.zeros((200, 200), dtype=int)
770rr, cc = line(r0, c0, r2, c2)
771image2[rr, cc] = 1
772assert_array_equal(image, image2)
773
774
775def test_bezier_segment_curved():
776img = np.zeros((25, 25), 'uint8')
777r0, c0 = 20, 20
778r1, c1 = 20, 2
779r2, c2 = 2, 2
780rr, cc = _bezier_segment(r0, c0, r1, c1, r2, c2, 1)
781img[rr, cc] = 1
782img_ = 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)
811assert_equal(img[r0, c0], 1)
812assert_equal(img[r2, c2], 1)
813assert_array_equal(img, img_)
814
815
816def test_bezier_curve_straight():
817image = np.zeros((200, 200), dtype=int)
818r0, c0 = 50, 50
819r1, c1 = 150, 50
820r2, c2 = 150, 150
821rr, cc = bezier_curve(r0, c0, r1, c1, r2, c2, 0)
822image[rr, cc] = 1
823
824image2 = np.zeros((200, 200), dtype=int)
825rr, cc = line(r0, c0, r2, c2)
826image2[rr, cc] = 1
827assert_array_equal(image, image2)
828
829
830def test_bezier_curved_weight_eq_1():
831img = np.zeros((23, 8), 'uint8')
832r0, c0 = 1, 1
833r1, c1 = 11, 11
834r2, c2 = 21, 1
835rr, cc = bezier_curve(r0, c0, r1, c1, r2, c2, 1)
836img[rr, cc] = 1
837assert_equal(img[r0, c0], 1)
838assert_equal(img[r2, c2], 1)
839img_ = 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)
866assert_equal(img, img_)
867
868
869def test_bezier_curved_weight_neq_1():
870img = np.zeros((23, 10), 'uint8')
871r0, c0 = 1, 1
872r1, c1 = 11, 11
873r2, c2 = 21, 1
874rr, cc = bezier_curve(r0, c0, r1, c1, r2, c2, 2)
875img[rr, cc] = 1
876assert_equal(img[r0, c0], 1)
877assert_equal(img[r2, c2], 1)
878img_ = 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)
905assert_equal(img, img_)
906
907
908def test_bezier_curve_shape():
909img = np.zeros((15, 20), 'uint8')
910r0, c0 = 1, 5
911r1, c1 = 6, 11
912r2, c2 = 1, 14
913rr, cc = bezier_curve(r0, c0, r1, c1, r2, c2, 2, shape=(15, 20))
914img[rr, cc] = 1
915shift = 5
916img_ = np.zeros((15 + 2 * shift, 20), 'uint8')
917r0, c0 = 1 + shift, 5
918r1, c1 = 6 + shift, 11
919r2, c2 = 1 + shift, 14
920rr, cc = bezier_curve(r0, c0, r1, c1, r2, c2, 2, shape=None)
921img_[rr, cc] = 1
922assert_array_equal(img, img_[shift:-shift, :])
923
924
925@pytest.mark.skipif(not has_mpl, reason="matplotlib not installed")
926def test_polygon_perimeter():
927expected = np.array([[1, 1, 1, 1], [1, 0, 0, 1], [1, 1, 1, 1]])
928out = np.zeros_like(expected)
929
930rr, cc = polygon_perimeter([0, 2, 2, 0], [0, 0, 3, 3])
931
932out[rr, cc] = 1
933assert_array_equal(out, expected)
934
935out = np.zeros_like(expected)
936rr, cc = polygon_perimeter(
937[-1, -1, 3, 3], [-1, 4, 4, -1], shape=out.shape, clip=True
938)
939out[rr, cc] = 1
940assert_array_equal(out, expected)
941
942with pytest.raises(ValueError):
943polygon_perimeter([0], [1], clip=True)
944
945
946@pytest.mark.skipif(not has_mpl, reason="matplotlib not installed")
947def test_polygon_perimeter_outside_image():
948rr, cc = polygon_perimeter([-1, -1, 3, 3], [-1, 4, 4, -1], shape=(3, 4))
949assert_equal(len(rr), 0)
950assert_equal(len(cc), 0)
951
952
953def test_rectangle_end():
954expected = 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],
962dtype=np.uint8,
963)
964start = (0, 1)
965end = (3, 3)
966img = np.zeros((5, 5), dtype=np.uint8)
967rr, cc = rectangle(start, end=end, shape=img.shape)
968img[rr, cc] = 1
969assert_array_equal(img, expected)
970
971# Swap start and end
972img = np.zeros((5, 5), dtype=np.uint8)
973rr, cc = rectangle(end=start, start=end, shape=img.shape)
974img[rr, cc] = 1
975assert_array_equal(img, expected)
976
977# Bottom left and top right
978img = np.zeros((5, 5), dtype=np.uint8)
979rr, cc = rectangle(start=(3, 1), end=(0, 3), shape=img.shape)
980img[rr, cc] = 1
981assert_array_equal(img, expected)
982
983img = np.zeros((5, 5), dtype=np.uint8)
984rr, cc = rectangle(end=(3, 1), start=(0, 3), shape=img.shape)
985img[rr, cc] = 1
986assert_array_equal(img, expected)
987
988
989def test_rectangle_float_input():
990expected = 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],
998dtype=np.uint8,
999)
1000start = (0.2, 0.8)
1001end = (3.1, 2.9)
1002img = np.zeros((5, 5), dtype=np.uint8)
1003rr, cc = rectangle(start, end=end, shape=img.shape)
1004img[rr, cc] = 1
1005assert_array_equal(img, expected)
1006
1007# Swap start and end
1008img = np.zeros((5, 5), dtype=np.uint8)
1009rr, cc = rectangle(end=start, start=end, shape=img.shape)
1010img[rr, cc] = 1
1011assert_array_equal(img, expected)
1012
1013# Bottom left and top right
1014img = np.zeros((5, 5), dtype=np.uint8)
1015rr, cc = rectangle(start=(3.1, 0.8), end=(0.2, 2.9), shape=img.shape)
1016img[rr, cc] = 1
1017assert_array_equal(img, expected)
1018
1019img = np.zeros((5, 5), dtype=np.uint8)
1020rr, cc = rectangle(end=(3.1, 0.8), start=(0.2, 2.9), shape=img.shape)
1021img[rr, cc] = 1
1022assert_array_equal(img, expected)
1023
1024
1025def test_rectangle_extent():
1026expected = 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],
1034dtype=np.uint8,
1035)
1036start = (1, 1)
1037extent = (3, 3)
1038img = np.zeros((5, 5), dtype=np.uint8)
1039rr, cc = rectangle(start, extent=extent, shape=img.shape)
1040img[rr, cc] = 1
1041assert_array_equal(img, expected)
1042
1043img = np.zeros((5, 5, 3), dtype=np.uint8)
1044rr, cc = rectangle(start, extent=extent, shape=img.shape)
1045img[rr, cc, 0] = 1
1046expected_2 = np.zeros_like(img)
1047expected_2[..., 0] = expected
1048assert_array_equal(img, expected_2)
1049
1050
1051@pytest.mark.skipif(not has_mpl, reason="matplotlib not installed")
1052def test_rectangle_extent_negative():
1053# These two tests should be done together.
1054expected = 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],
1062dtype=np.uint8,
1063)
1064
1065start = (3, 5)
1066extent = (-1, -2)
1067img = np.zeros(expected.shape, dtype=np.uint8)
1068rr, cc = rectangle_perimeter(start, extent=extent, shape=img.shape)
1069img[rr, cc] = 1
1070
1071rr, cc = rectangle(start, extent=extent, shape=img.shape)
1072img[rr, cc] = 2
1073assert_array_equal(img, expected)
1074
1075# Ensure that rr and cc have no overlap
1076img = np.zeros(expected.shape, dtype=np.uint8)
1077rr, cc = rectangle(start, extent=extent, shape=img.shape)
1078img[rr, cc] = 2
1079
1080rr, cc = rectangle_perimeter(start, extent=extent, shape=img.shape)
1081img[rr, cc] = 1
1082assert_array_equal(img, expected)
1083
1084
1085@pytest.mark.skipif(not has_mpl, reason="matplotlib not installed")
1086def test_rectangle_perimiter():
1087expected = 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],
1095dtype=np.uint8,
1096)
1097start = (2, 3)
1098end = (2, 4)
1099img = np.zeros(expected.shape, dtype=np.uint8)
1100# Test that the default parameter is indeed end
1101rr, cc = rectangle_perimeter(start, end, shape=img.shape)
1102img[rr, cc] = 1
1103assert_array_equal(img, expected)
1104
1105# Swap start and end
1106img = np.zeros(expected.shape, dtype=np.uint8)
1107rr, cc = rectangle_perimeter(end=start, start=end, shape=img.shape)
1108img[rr, cc] = 1
1109assert_array_equal(img, expected)
1110
1111img = np.zeros(expected.shape, dtype=np.uint8)
1112start = (2, 3)
1113extent = (1, 2)
1114rr, cc = rectangle_perimeter(start, extent=extent, shape=img.shape)
1115img[rr, cc] = 1
1116assert_array_equal(img, expected)
1117
1118
1119@pytest.mark.skipif(not has_mpl, reason="matplotlib not installed")
1120def test_rectangle_perimiter_clip_bottom_right():
1121# clip=False
1122expected = 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],
1130dtype=np.uint8,
1131)
1132img = np.zeros((5, 5), dtype=np.uint8)
1133start = (2, 2)
1134extent = (10, 10)
1135rr, cc = rectangle_perimeter(start, extent=extent, shape=img.shape, clip=False)
1136img[rr, cc] = 1
1137assert_array_equal(img, expected)
1138
1139# clip=True
1140expected = 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],
1148dtype=np.uint8,
1149)
1150img = np.zeros((5, 5), dtype=np.uint8)
1151rr, cc = rectangle_perimeter(start, extent=extent, shape=img.shape, clip=True)
1152img[rr, cc] = 1
1153assert_array_equal(img, expected)
1154
1155
1156@pytest.mark.skipif(not has_mpl, reason="matplotlib not installed")
1157def test_rectangle_perimiter_clip_top_left():
1158# clip=False
1159expected = 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],
1167dtype=np.uint8,
1168)
1169img = np.zeros((5, 5), dtype=np.uint8)
1170start = (-5, -5)
1171end = (2, 2)
1172rr, cc = rectangle_perimeter(start, end=end, shape=img.shape, clip=False)
1173img[rr, cc] = 1
1174assert_array_equal(img, expected)
1175
1176# clip=True
1177expected = 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],
1185dtype=np.uint8,
1186)
1187img = np.zeros((5, 5), dtype=np.uint8)
1188rr, cc = rectangle_perimeter(start, end=end, shape=img.shape, clip=True)
1189img[rr, cc] = 1
1190assert_array_equal(img, expected)
1191
1192
1193@pytest.mark.skipif(not has_mpl, reason="matplotlib not installed")
1194def test_rectangle_perimiter_clip_top_right():
1195expected = 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],
1203dtype=np.uint8,
1204)
1205img = np.zeros((5, 5), dtype=np.uint8)
1206start = (-10, 2)
1207end = (2, 10)
1208rr, cc = rectangle_perimeter(start, end=end, shape=img.shape, clip=True)
1209img[rr, cc] = 1
1210assert_array_equal(img, expected)
1211
1212expected = 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],
1220dtype=np.uint8,
1221)
1222img = np.zeros((5, 5), dtype=np.uint8)
1223rr, cc = rectangle_perimeter(start, end=end, shape=img.shape, clip=False)
1224img[rr, cc] = 1
1225assert_array_equal(img, expected)
1226
1227
1228@pytest.mark.skipif(not has_mpl, reason="matplotlib not installed")
1229def test_rectangle_perimiter_clip_bottom_left():
1230expected = 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],
1238dtype=np.uint8,
1239)
1240img = np.zeros((5, 5), dtype=np.uint8)
1241start = (2, -3)
1242end = (10, 1)
1243rr, cc = rectangle_perimeter(start, end=end, shape=img.shape, clip=True)
1244img[rr, cc] = 1
1245assert_array_equal(img, expected)
1246
1247expected = 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],
1255dtype=np.uint8,
1256)
1257
1258img = np.zeros((5, 5), dtype=np.uint8)
1259rr, cc = rectangle_perimeter(start, end=end, shape=img.shape, clip=False)
1260img[rr, cc] = 1
1261assert_array_equal(img, expected)
1262