Pythonを使用して画像に円を描画しようとしています。 PILを使用してこれを試しましたが、linewidth
を指定したいと思います。現在、PILは円を描きますが、境界線が細すぎます。
これが私がしたことです。
テスト画像の場合:MSペイントで1632 X 1200の画像を作成し、緑色で塗りつぶしました。私はそれをtest_1.jpgと呼びました。入力ファイルは次のとおりです。
from PIL import Image, ImageDraw
im = Image.open('test_1.jpg')
width, height = im.size
eX, eY = 816,816 #Size of Bounding Box for ellipse
bbox = (width/2 - eX/2, height/2 - eY/2, width/2 + eX/2, height/2 + eY/2)
draw = ImageDraw.Draw(im)
bbox_L = []
for j in range(0,5):
bbox_L.append([element+j for element in bbox])
draw.ellipse(Tuple(bbox_L[j]), outline ='white')
im.show()
基本的には、同じ場所を中心に半径が異なる複数の円を描いてみました。太い線の効果が出ると思いました。
ただし、これにより、以下の添付ファイルに示す出力が生成されます。
問題:ご覧のとおり、左下と右上が薄すぎます。また、さまざまな円の間にギャップがあります(左上と右下を参照)。
円の太さはさまざまです。均一な太さの円を探しています。
質問: PIL、NumPyなどを使用してtest_1.jpgのような画像に、Pythonで円を描く方法はありますか線の太さを指定するには?
私も同じ問題を抱えていたので、あなたと同じようなヘルパー関数を書くことにしました。この関数は、マスクレイヤー上に白黒で2つの同心楕円を描画し、目的のアウトラインカラーがマスクを介して元の画像にスタンプされます。よりスムーズな結果(アンチエイリアス)を取得するために、楕円とマスクはより高い解像度で描画されます。
白い楕円の幅は20ピクセル、黒い楕円の幅は0.5ピクセルです。
from PIL import Image, ImageDraw
def draw_ellipse(image, bounds, width=1, outline='white', antialias=4):
"""Improved ellipse drawing function, based on PIL.ImageDraw."""
# Use a single channel image (mode='L') as mask.
# The size of the mask can be increased relative to the imput image
# to get smoother looking results.
mask = Image.new(
size=[int(dim * antialias) for dim in image.size],
mode='L', color='black')
draw = ImageDraw.Draw(mask)
# draw outer shape in white (color) and inner shape in black (transparent)
for offset, fill in (width/-2.0, 'white'), (width/2.0, 'black'):
left, top = [(value + offset) * antialias for value in bounds[:2]]
right, bottom = [(value - offset) * antialias for value in bounds[2:]]
draw.ellipse([left, top, right, bottom], fill=fill)
# downsample the mask using PIL.Image.LANCZOS
# (a high-quality downsampling filter).
mask = mask.resize(image.size, Image.LANCZOS)
# paste outline color to input image through the mask
image.paste(outline, mask=mask)
# green background image
image = Image.new(mode='RGB', size=(700, 300), color='green')
ellipse_box = [50, 50, 300, 250]
# draw a thick white ellipse and a thin black ellipse
draw_ellipse(image, ellipse_box, width=20)
# draw a thin black line, using higher antialias to preserve finer detail
draw_ellipse(image, ellipse_box, outline='black', width=.5, antialias=8)
# Lets try without antialiasing
ellipse_box[0] += 350
ellipse_box[2] += 350
draw_ellipse(image, ellipse_box, width=20, antialias=1)
draw_ellipse(image, ellipse_box, outline='black', width=1, antialias=1)
image.show()
私はこのコードをpython 3.4でテストしただけですが、大きな変更を加えなくても2.7で動作するはずです。
単純な(しかしニースではない)解決策は、2つの円(背景色の小さい方の円)を描くことです。
outline = 10 # line thickness
draw.ellipse((x1-outline, y1-outline, x2+outline, y2+outline), fill=outline_color)
draw.ellipse((x1, y1, x2, y2), fill=background_color)
楕円の厚さを指定する方法はないと思いますが、引数width = ..を使用して、楕円が通過する各ピクセルに線を引くことができます。
注意:私は外国人なので、英語が間違っていたらごめんなさい。
このようなImage.core.drawメソッドを使用できます
`zero_array = np.zeros((224,224))
im = Image.fromarray(np.uint8(zero_array))
draw = ImageDraw.Draw(im)
dr_im = Image.core.draw(im.getdata(), 0)
dr_im.draw_rectangle((22,33, 150,100),220,2)
dr_im.draw_rectangle((22,33, 150,100),125,0)
#draw.rectangle((22,33, 150,100), fill=220,outline = 125)
print(np.array(im)[33][23])
im.show()`