aboutsummaryrefslogtreecommitdiffstats
path: root/fg21sim/utils
diff options
context:
space:
mode:
authorAaron LI <aaronly.me@outlook.com>2016-10-25 23:32:37 +0800
committerAaron LI <aaronly.me@outlook.com>2016-10-25 23:32:37 +0800
commit7fbd15078b3689c2c4ffde9e986a8de5ca6bd29b (patch)
treeb9eb4d0597983f7751c7e1abd1ab780605ca042a /fg21sim/utils
parent1a1a3ab66f5191e350e0fcbec7e852c074fb420f (diff)
downloadfg21sim-7fbd15078b3689c2c4ffde9e986a8de5ca6bd29b.tar.bz2
draw.py: Optimize "ellipse()" using numba JIT
NOTE: However, there are two significant problems: * Cannot figure out why ``nb.optional(nb.types.UniTuple(nb.int64, 2))`` does NOT work. Therefore, make ``shape`` as mandatory parameter instead of optional. * Cannot figure out multi-dispatch that allows both int and float types for ``r``, ``c``, ``r_radius`` and ``c_radius``. Thus only support the int type for the moment.
Diffstat (limited to 'fg21sim/utils')
-rw-r--r--fg21sim/utils/draw.py44
1 files changed, 27 insertions, 17 deletions
diff --git a/fg21sim/utils/draw.py b/fg21sim/utils/draw.py
index 3d9acc1..a80e301 100644
--- a/fg21sim/utils/draw.py
+++ b/fg21sim/utils/draw.py
@@ -83,16 +83,29 @@ def _ellipse_in_shape(shape, center, radii):
return (xi, yi)
-def ellipse(r, c, r_radius, c_radius, shape=None):
+@nb.jit(nb.types.UniTuple(nb.int64[:], 2)(nb.int64, nb.int64,
+ nb.int64, nb.int64,
+ nb.types.UniTuple(nb.int64, 2)),
+ nopython=True)
+def ellipse(r, c, r_radius, c_radius, shape):
"""Generate coordinates of pixels within the ellipse.
+ XXX/NOTE
+ --------
+ * Cannot figure out why ``nb.optional(nb.types.UniTuple(nb.int64, 2))``
+ does NOT work. Therefore, make ``shape`` as mandatory parameter
+ instead of optional.
+ * Cannot figure out multi-dispatch that allows both int and float types
+ for ``r``, ``c``, ``r_radius`` and ``c_radius``. Thus only support
+ the int type for the moment.
+
Parameters
----------
- r, c : float
+ r, c : int
Center coordinate of the ellipse.
- r_radius, c_radius : float
+ r_radius, c_radius : int
Minor and major semi-axes. ``(r/r_radius)**2 + (c/c_radius)**2 = 1``.
- shape : tuple, optional
+ shape : tuple
Image shape which is used to determine the maximum extent of output
pixel coordinates. This is useful for ellipses that exceed the image
size. If None, the full extent of the ellipse is used.
@@ -127,35 +140,32 @@ def ellipse(r, c, r_radius, c_radius, shape=None):
# The upper_left and lower_right corners of the
# smallest rectangle containing the ellipse.
- upper_left = np.ceil(center - radii).astype(int)
- lower_right = np.floor(center + radii).astype(int)
+ upper_left = np.ceil(center - radii).astype(np.int64)
+ lower_right = np.floor(center + radii).astype(np.int64)
- if shape is not None:
- # Constrain upper_left and lower_right by shape boundary.
- upper_left = np.maximum(upper_left, np.array([0, 0]))
- lower_right = np.minimum(lower_right, np.array(shape[:2]) - 1)
+ # Constrain upper_left and lower_right by shape boundary.
+ upper_left = np.maximum(upper_left, np.array([0, 0]))
+ lower_right = np.minimum(lower_right, np.array(shape)-1)
shifted_center = center - upper_left
bounding_shape = lower_right - upper_left + 1
rr, cc = _ellipse_in_shape(bounding_shape, shifted_center, radii)
- rr.flags.writeable = True
- cc.flags.writeable = True
rr += upper_left[0]
cc += upper_left[1]
- return rr, cc
+ return (rr, cc)
-def circle(r, c, radius, shape=None):
+def circle(r, c, radius, shape):
"""Generate coordinates of pixels within the circle.
Parameters
----------
- r, c : float
+ r, c : int
Center coordinate of the circle.
- radius : float
+ radius : int
Radius of the circle.
- shape : tuple, optional
+ shape : tuple
Image shape which is used to determine the maximum extent of output
pixel coordinates. This is useful for circles that exceed the image
size. If None, the full extent of the circle is used.