33

サイズが 200x200 の numpy 配列を生成し、100,100 の座標、半径 80、ストローク幅 3 ピクセルを中心とする円を配置したいと思います。ファイル操作を伴わずにPython 2.7でこれを行うには? おそらくジオメトリまたはイメージング ライブラリを使用して、他の形状への一般化を可能にします。

4

5 に答える 5

53

通常の方法は、座標メッシュを定義し、形状の方程式を適用することです。これを行う最も簡単な方法は、次を使用することnumpy.mgridです。

http://docs.scipy.org/doc/numpy/reference/generated/numpy.mgrid.html

# xx and yy are 200x200 tables containing the x and y coordinates as values
# mgrid is a mesh creation helper
xx, yy = numpy.mgrid[:200, :200]
# circles contains the squared distance to the (100, 100) point
# we are just using the circle equation learnt at school
circle = (xx - 100) ** 2 + (yy - 100) ** 2
# donuts contains 1's and 0's organized in a donut shape
# you apply 2 thresholds on circle to define the shape
donut = numpy.logical_and(circle < (6400 + 60), circle > (6400 - 60))
于 2012-04-05T16:19:26.707 に答える
21

Cairoは、最新の柔軟で高速な 2D グラフィックス ライブラリです。Python バインディングがあり、NumPy 配列に基づいて「サーフェス」を作成できます。

import numpy
import cairo
import math
data = numpy.zeros((200, 200, 4), dtype=numpy.uint8)
surface = cairo.ImageSurface.create_for_data(
    data, cairo.FORMAT_ARGB32, 200, 200)
cr = cairo.Context(surface)

# fill with solid white
cr.set_source_rgb(1.0, 1.0, 1.0)
cr.paint()

# draw red circle
cr.arc(100, 100, 80, 0, 2*math.pi)
cr.set_line_width(3)
cr.set_source_rgb(1.0, 0.0, 0.0)
cr.stroke()

# write output
print data[38:48, 38:48, 0]
surface.write_to_png("circle.png")

このコードは印刷します

[[255 255 255 255 255 255 255 255 132   1]
 [255 255 255 255 255 255 252 101   0   0]
 [255 255 255 255 255 251  89   0   0   0]
 [255 255 255 255 249  80   0   0   0  97]
 [255 255 255 246  70   0   0   0 116 254]
 [255 255 249  75   0   0   0 126 255 255]
 [255 252  85   0   0   0 128 255 255 255]
 [255 103   0   0   0 118 255 255 255 255]
 [135   0   0   0 111 255 255 255 255 255]
 [  1   0   0  97 254 255 255 255 255 255]]

円のランダムな断片を示しています。また、次の PNG も作成します。

赤丸

于 2012-04-05T15:53:43.537 に答える
13

別の可能性は、 を使用することscikit-imageです。中空または完全な円には、 circle_perimeterを使用できます。circle

次のように、一筆の円を描くことができます。

import matplotlib.pyplot as plt
from skimage import draw
arr = np.zeros((200, 200))
rr, cc = draw.circle_perimeter(100, 100, radius=80, shape=arr.shape)
arr[rr, cc] = 1
plt.imshow(arr)
plt.show()

を使用してストロークをエミュレートすることもできますloop。この場合、アーティファクトを避けるために、アンチエイリアス バージョンを使用する必要があります。

import matplotlib.pyplot as plt
from skimage import draw
arr = np.zeros((200, 200))
stroke = 3
# Create stroke-many circles centered at radius. 
for delta in range(-(stroke // 2) + (stroke % 2), (stroke + 1) // 2):
    rr, cc, _ = draw.circle_perimeter_aa(100, 100, radius=80+delta, shape=arr.shape)
    arr[rr, cc] = 1
plt.imshow(arr)
plt.show()

おそらくより効率的な方法は、2 つの完全な円を生成し、外側の円から内側の円を「差し引く」ことです。

import matplotlib.pyplot as plt
from skimage import draw
arr = np.zeros((200, 200))
stroke = 3
# Create an outer and inner circle. Then subtract the inner from the outer.
radius = 80
inner_radius = radius - (stroke // 2) + (stroke % 2) - 1 
outer_radius = radius + ((stroke + 1) // 2)
ri, ci = draw.circle(100, 100, radius=inner_radius, shape=arr.shape)
ro, co = draw.circle(100, 100, radius=outer_radius, shape=arr.shape)
arr[ro, co] = 1
arr[ri, ci] = 0
plt.imshow(arr)
plt.show()

この 2 つの方法では、実際にはわずかに異なる結果が得られます。

<code>stroke=3</code> の円

于 2017-01-05T21:30:44.327 に答える
6

opencv の新しい python バインディング import cv2は、デフォルトの画像形式として numpy 配列を作成します

描画機能が含まれています

于 2012-04-05T15:52:30.073 に答える