Предположим, у меня есть квадратный растр заданного размера, и я хочу "нарисовать" (сделать) круг (или эллипс) заданного радиуса (или больших / малых осей) и центра.
В одну сторону Выполнение этого в Python с NumPy:
import numpy as np
def ellipse(box_size, semisizes, position=0.5, n_dim=2):
shape = (box_size,) * n_dim
if isinstance(semisizes, (int, float)):
semisizes = (semisizes,) * n_dim
position = ((box_size - 1) * position,) * n_dim
grid = [slice(-x0, dim - x0) for x0, dim in zip(position, shape)]
position = np.ogrid[grid]
arr = np.zeros(shape, dtype=float)
for x_i, semisize in zip(position, semisizes):
arr += (np.abs(x_i / semisize) ** 2)
return arr <= 1.0
print(ellipse(5, 2).astype(float))
# [[0. 0. 1. 0. 0.]
# [0. 1. 1. 1. 0.]
# [1. 1. 1. 1. 1.]
# [0. 1. 1. 1. 0.]
# [0. 0. 1. 0. 0.]]
, что приводит к растеризации без сглаживания . В частности, пиксели, которые только частично включены в круг, получают значение 0
(аналогично пикселям, исключенным из круга), тогда как пиксели, полностью включенные в круг, получают значение 1
.
При использовании сглаживания пиксели , частично включенные в круг, получат значение в диапазоне от 0
до 1
в зависимости от того, какая их площадь включена в круг.
Как я могу изменить код сверху, чтобы (возможно, дешево) включить сглаживание? Я изо всех сил пытаюсь понять, как (если?) Я мог бы использовать значения arr
.
Методы, основанные на суперсэмплинге, здесь не обсуждаются.
В конце концов, результат должен выглядеть что-то вроде:
# [[0.0 0.2 1.0 0.2 0.0]
# [0.2 1.0 1.0 1.0 0.2]
# [1.0 1.0 1.0 1.0 1.0]
# [0.2 1.0 1.0 1.0 0.2]
# [0.0 0.2 1.0 0.2 0.0]]
(где 0.2
должно быть значением между 0.0
и 1.0
, представляющим, сколько области этого указанного c пикселя покрыто кружком).
EDIT
Теперь я вижу очевидный способ адаптации кода из Эффективное создание круговой маски с сглаживанием , хотя, очевидно, np.clip()
должно быть частью решения .