LoginSignup
0
0

More than 3 years have passed since last update.

numpyで綺麗な円を描く

Last updated at Posted at 2020-04-05

OpenCVのcircleは適当なので、もっと綺麗な円を書きましょう。半径rの円の画像は、中心からr-1以下の距離では1、r以上の距離では0、その間ではr-距離とすることとします。

import math, cv2, numpy as np
# r must be greater than 0.
def circle(r):
    c = math.ceil(r - 1)
    s = c * 2 + 1
    return np.clip(r - np.sqrt(np.sum((np.stack((
        np.tile(np.arange(s), (s, 1)),
        np.repeat(np.arange(s), s).reshape((-1, s))
    )) - c) ** 2, axis=0)), 0, 1)
# r must be greater than 0. width must be greater than 0 and less than r.
def outline_circle(r, width):
    circ = circle(r)
    icirc = circle(r - width)
    ch, cw = circ.shape
    ich, icw = icirc.shape
    sx = (cw - icw) // 2
    sy = (ch - ich) // 2
    ex = sx + icw
    ey = sy + ich
    circ[sy:ey, sx:ex] = np.amax(np.stack((circ[sy:ey, sx:ex] - icirc, np.zeros((ich, icw)))), axis=0)
    return circ
def save_cv2_circle(file_name, r, thickness = -1):
    s = r * 2 + 1
    cv2.imwrite(file_name, cv2.circle(np.zeros((s, s), dtype=np.uint8), (r, r), r, 255, thickness))
def save_circle(file_name, c):
    im = (np.around(c) * 255).astype(np.uint8)
    cv2.imwrite(file_name, im)
save_circle('/tmp/circle10.jpg', circle(11))
save_cv2_circle('/tmp/cv2_circle10.jpg', 10)
save_circle('/tmp/circle10_outline.jpg', outline_circle(11, 1))
save_cv2_circle('/tmp/cv2_circle10_outline.jpg', 10, 1)

/tmp/circle10.jpg
circle10.jpg

/tmp/cv2_circle10.jpg
cv2_circle10.jpg

/tmp/circle10_outline.jpg
circle10_outline.jpg

/tmp/cv2_circle10_outline.jpg
cv2_circle10_outline.jpg

違いは一目瞭然ですね。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0