mirror of
https://github.com/wassname/scikit-image.git
synced 2026-07-12 12:18:59 +08:00
Implement line_aa
This commit is contained in:
@@ -1,9 +1,11 @@
|
||||
from .draw import circle, ellipse, set_color
|
||||
from ._draw import (line, polygon, ellipse_perimeter, circle_perimeter,
|
||||
circle_perimeter_aa, bezier_segment)
|
||||
from .draw3d import ellipsoid, ellipsoid_stats
|
||||
from ._draw import (line, line_aa, polygon, ellipse_perimeter,
|
||||
circle_perimeter, circle_perimeter_aa,
|
||||
bezier_segment)
|
||||
|
||||
__all__ = ['line',
|
||||
'line_aa',
|
||||
'polygon',
|
||||
'ellipse',
|
||||
'ellipse_perimeter',
|
||||
|
||||
@@ -27,6 +27,10 @@ def line(Py_ssize_t y, Py_ssize_t x, Py_ssize_t y2, Py_ssize_t x2):
|
||||
May be used to directly index into an array, e.g.
|
||||
``img[rr, cc] = 1``.
|
||||
|
||||
Notes
|
||||
-----
|
||||
Anti-aliased line generator is available with `line_aa`.
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> from skimage.draw import line
|
||||
@@ -89,6 +93,83 @@ def line(Py_ssize_t y, Py_ssize_t x, Py_ssize_t y2, Py_ssize_t x2):
|
||||
return np.asarray(rr), np.asarray(cc)
|
||||
|
||||
|
||||
def line_aa(Py_ssize_t y1, Py_ssize_t x1, Py_ssize_t y2, Py_ssize_t x2):
|
||||
"""Generate line pixel coordinates.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
y1, x1 : int
|
||||
Starting position (row, column).
|
||||
y2, x2 : int
|
||||
End position (row, column).
|
||||
|
||||
Returns
|
||||
-------
|
||||
rr, cc, val : (N,) ndarray of int
|
||||
Indices of pixels that belong to the line.
|
||||
May be used to directly index into an array, e.g.
|
||||
``img[rr, cc] = val``.
|
||||
|
||||
References
|
||||
----------
|
||||
.. [1] A Rasterizing Algorithm for Drawing Curves, A. Zingl, 2012
|
||||
http://members.chello.at/easyfilter/Bresenham.pdf
|
||||
|
||||
"""
|
||||
cdef list rr = list()
|
||||
cdef list cc = list()
|
||||
cdef list val = list()
|
||||
|
||||
cdef int dx = abs(x1 - x2)
|
||||
cdef int dy = abs(y1 - y2)
|
||||
cdef int err = dx - dy
|
||||
cdef int x, y, e, ed, sign_x, sign_y
|
||||
|
||||
if x1 < x2:
|
||||
sign_x = 1
|
||||
else:
|
||||
sign_x = -1
|
||||
|
||||
if y1 < y2:
|
||||
sign_y = 1
|
||||
else:
|
||||
sign_y = -1
|
||||
|
||||
if dx + dy == 0:
|
||||
ed = 1
|
||||
else:
|
||||
ed = <int>(sqrt(dx*dx + dy*dy))
|
||||
|
||||
x, y = x1, y1
|
||||
while True:
|
||||
cc.append(x)
|
||||
rr.append(y)
|
||||
val.append(255 * abs(err - dx + dy) / ed)
|
||||
e = err
|
||||
if 2 * e >= -dx:
|
||||
if x == x2:
|
||||
break
|
||||
if e + dy < ed:
|
||||
cc.append(x)
|
||||
rr.append(y + sign_y)
|
||||
val.append(255 * abs(e + dy) / ed)
|
||||
err -= dy
|
||||
x += sign_x
|
||||
if 2 * e <= dy:
|
||||
if y == y2:
|
||||
break
|
||||
if dx - e < ed:
|
||||
cc.append(x)
|
||||
rr.append(y)
|
||||
val.append(255 * abs(dx - e) / ed)
|
||||
err += dx
|
||||
y += sign_y
|
||||
|
||||
return (np.array(rr, dtype=np.intp),
|
||||
np.array(cc, dtype=np.intp),
|
||||
255 - np.array(val, dtype=np.intp))
|
||||
|
||||
|
||||
def polygon(y, x, shape=None):
|
||||
"""Generate coordinates of pixels within polygon.
|
||||
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
from numpy.testing import assert_array_equal
|
||||
from numpy.testing import assert_array_equal, assert_equal
|
||||
import numpy as np
|
||||
|
||||
from skimage.draw import (line, polygon, circle, circle_perimeter,
|
||||
circle_perimeter_aa, ellipse,
|
||||
from skimage.draw import (line, line_aa,
|
||||
polygon, circle,
|
||||
circle_perimeter, circle_perimeter_aa,
|
||||
ellipse,
|
||||
ellipse_perimeter, bezier_segment,
|
||||
)
|
||||
|
||||
@@ -54,6 +56,43 @@ def test_line_diag():
|
||||
assert_array_equal(img, img_)
|
||||
|
||||
|
||||
def test_line_aa_horizontal():
|
||||
img = np.zeros((10, 10))
|
||||
|
||||
rr, cc, val = line_aa(0, 0, 0, 9)
|
||||
img[rr, cc] = val
|
||||
|
||||
img_ = np.zeros((10, 10))
|
||||
img_[0, :] = 255
|
||||
|
||||
assert_array_equal(img, img_)
|
||||
|
||||
|
||||
def test_line_aa_vertical():
|
||||
img = np.zeros((10, 10))
|
||||
|
||||
rr, cc, val = line_aa(0, 0, 9, 0)
|
||||
img[rr, cc] = val
|
||||
|
||||
img_ = np.zeros((10, 10))
|
||||
img_[:, 0] = 255
|
||||
|
||||
assert_array_equal(img, img_)
|
||||
|
||||
|
||||
def test_line_aa_diagonal():
|
||||
img = np.zeros((10, 10))
|
||||
|
||||
rr, cc, val = line_aa(0, 0, 9, 6)
|
||||
img[rr, cc] = 1
|
||||
|
||||
# Check that each pixel belonging to line,
|
||||
# also belongs to line_aa
|
||||
r, c = line(0, 0, 9, 6)
|
||||
for x, y in zip(r, c):
|
||||
assert_equal(img[r, c], 1)
|
||||
|
||||
|
||||
def test_polygon_rectangle():
|
||||
img = np.zeros((10, 10), 'uint8')
|
||||
poly = np.array(((1, 1), (4, 1), (4, 4), (1, 4), (1, 1)))
|
||||
|
||||
Reference in New Issue
Block a user