Skip to content

Commit

Permalink
ENH: Added support for float radius and circle in circle_perimeter()
Browse files Browse the repository at this point in the history
  • Loading branch information
bewithaman committed Mar 20, 2015
1 parent e91dcba commit fc08cbb
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 18 deletions.
27 changes: 9 additions & 18 deletions skimage/draw/_draw.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -289,15 +289,14 @@ def polygon(y, x, shape=None):
return np.array(rr, dtype=np.intp), np.array(cc, dtype=np.intp)


def circle_perimeter(Py_ssize_t cy, Py_ssize_t cx, Py_ssize_t radius,
def circle_perimeter(float cy, float cx, float radius,
method='bresenham', shape=None):
"""Generate circle perimeter coordinates.
Parameters
----------
cy, cx : int
cy, cx : float
Centre coordinate of circle.
radius: int
radius: float
Radius of circle.
method : {'bresenham', 'andres'}, optional
bresenham : Bresenham method (default)
Expand All @@ -306,30 +305,26 @@ def circle_perimeter(Py_ssize_t cy, Py_ssize_t cx, Py_ssize_t radius,
Image shape which is used to determine the maximum extent of output pixel
coordinates. This is useful for circles which exceed the image size.
By default the full extent of the circle are used.
Returns
-------
rr, cc : (N,) ndarray of int
Bresenham and Andres' method:
Indices of pixels that belong to the circle perimeter.
May be used to directly index into an array, e.g.
``img[rr, cc] = 1``.
Notes
-----
Andres method presents the advantage that concentric
circles create a disc whereas Bresenham can make holes. There
is also less distortions when Andres circles are rotated.
Bresenham method is also known as midpoint circle algorithm.
Anti-aliased circle generator is available with `circle_perimeter_aa`.
References
----------
.. [1] J.E. Bresenham, "Algorithm for computer control of a digital
plotter", IBM Systems journal, 4 (1965) 25-30.
.. [2] E. Andres, "Discrete circles, rings and spheres", Computers &
Graphics, 18 (1994) 695-706.
Examples
--------
>>> from skimage.draw import circle_perimeter
Expand All @@ -347,18 +342,14 @@ def circle_perimeter(Py_ssize_t cy, Py_ssize_t cx, Py_ssize_t radius,
[0, 0, 0, 1, 1, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], dtype=uint8)
"""

cdef list rr = list()
cdef list cc = list()

cdef Py_ssize_t x = 0
cdef Py_ssize_t y = radius
cdef Py_ssize_t d = 0

cdef double dceil = 0
cdef double dceil_prev = 0
cdef Py_ssize_t y = <int> round(radius)
cdef float d = 0

cdef char cmethod
if method == 'bresenham':
Expand Down Expand Up @@ -393,11 +384,11 @@ def circle_perimeter(Py_ssize_t cy, Py_ssize_t cx, Py_ssize_t radius,
y = y - 1
x = x + 1
if shape is not None:
return _coords_inside_image(np.array(rr, dtype=np.intp) + cy,
np.array(cc, dtype=np.intp) + cx,
return _coords_inside_image(np.array(rr, dtype=np.intp) + <int> round(cy),
np.array(cc, dtype=np.intp) + <int> round(cx),
shape)
return (np.array(rr, dtype=np.intp) + cy,
np.array(cc, dtype=np.intp) + cx)
return (np.array(rr, dtype=np.intp) + <int> round(cy),
np.array(cc, dtype=np.intp) + <int> round(cx))


def circle_perimeter_aa(Py_ssize_t cy, Py_ssize_t cx, Py_ssize_t radius,
Expand Down
17 changes: 17 additions & 0 deletions skimage/draw/tests/test_draw.py
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,23 @@ def test_circle_perimeter_bresenham():
)
assert_array_equal(img, img_)

img_1 = img = np.zeros((10, 10), 'uint8')
rr, cc = circle_perimeter(4.5, 4.5, 3.5, method='bresenham')
img_1[rr, cc] = 1
img_1_ = np.array(
[[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 0, 0, 0, 1, 0, 0],
[0, 0, 1, 0, 0, 0, 0, 0, 1, 0],
[0, 1, 0, 0, 0, 0, 0, 0, 0, 1],
[0, 1, 0, 0, 0, 0, 0, 0, 0, 1],
[0, 1, 0, 0, 0, 0, 0, 0, 0, 1],
[0, 0, 1, 0, 0, 0, 0, 0, 1, 0],
[0, 0, 0, 1, 0, 0, 0, 1, 0, 0],
[0, 0, 0, 0, 1, 1, 1, 0, 0, 0]]
)
assert_array_equal(img_1, img_1_)


def test_circle_perimeter_bresenham_shape():
img = np.zeros((15, 20), 'uint8')
Expand Down

0 comments on commit fc08cbb

Please sign in to comment.