Python PIL ImageDraw.polygon не рисует многоугольник, если это линия или точка - PullRequest
0 голосов
/ 14 июля 2020

Как видно из примеров ниже, если многоугольник является линией или точкой, он не рисуется. Я не думаю, что это желаемое поведение. Теоретически линия также является многоугольником, верно?

Из документов PIL :

ImageDraw.polygon (xy, fill = None, Outline = None)

Dr aws многоугольник.

Контур многоугольника состоит из прямых линий между заданными координатами плюс прямая линия между последней и первой координатами.

...

Для меня это говорит о том, что метод .polygon работает путем рисования линий между точками, однако, как видно из примера № 2, это определенно не так.

Кто-нибудь может сказать мне, почему это так? Может ли кто-нибудь также сказать мне, как я могу сделать так, чтобы, даже если многоугольник является линией или точкой, он все еще рисовался?

# 1 Точка как многоугольник:

Python 3.7.6 (v3.7.6:43364a7ae0, Dec 18 2019, 14:18:50) 
[Clang 6.0 (clang-600.0.57)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from PIL import Image, ImageDraw
>>> import numpy as np
>>> img = Image.new('L', (5, 5), 0)
>>> ImageDraw.Draw(img).polygon([2, 2, 2, 2, 2, 2, 2, 2], outline=1, fill=1)
>>> np.array(img)
array([[0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0]], dtype=uint8)

# 2 Линия как многоугольник:

>>> img = Image.new('L', (5, 5), 0)
>>> ImageDraw.Draw(img).polygon([1, 1, 2, 1, 2, 1, 1, 1], outline=1, fill=1)
>>> np.array(img)
array([[0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0]], dtype=uint8)

# 3 Сквайр как многоугольник:

>>> img = Image.new('L', (5, 5), 0)
>>> ImageDraw.Draw(img).polygon([1, 1, 2, 1, 2, 2, 1, 2], outline=1, fill=1)
>>> np.array(img)
array([[0, 0, 0, 0, 0],
       [0, 1, 1, 0, 0],
       [0, 1, 1, 0, 0],
       [0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0]], dtype=uint8)

Изменить: я немного погуглил для определения многоугольника;

В геометрии многоугольник может быть определен как плоская или плоская двумерная замкнутая форма с прямыми сторонами.

исходный

A плоская фигура, по крайней мере, с тремя прямыми сторонами и углами, а обычно с пятью или более.

источник

Итак, возникает новый вопрос; углы 0 градусов также считаются углами в геометрии? Согласно этому источнику это:

Нулевые углы

Угол с мерой ноль градусов называется нулевым углом. Если это трудно представить, рассмотрите два луча, образующих угол больше нуля градусов, как лучи в. Затем представьте себе, как один из лучей вращается по направлению к другому лучу, пока они оба не будут находиться на одной линии. Угол, который они создают, был уменьшен с исходного размера до нуля градусов. Теперь образуемый угол имеет размер ноль градусов.

1 Ответ

0 голосов
/ 14 июля 2020

Хотя это не объясняет поведение метода .polygon, я нашел обходной путь.

Объединив .polygon с .point .line, вы получите желаемый результат. (См. Редактирование ниже, почему использовать .line вместо .point)

# 1 точка

Python 3.7.6 (v3.7.6:43364a7ae0, Dec 18 2019, 14:18:50) 
[Clang 6.0 (clang-600.0.57)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from PIL import Image, ImageDraw
>>> import numpy as np
>>> img = Image.new('L', (5, 5), 0)
>>> ImageDraw.Draw(img).polygon([2, 2, 2, 2, 2, 2, 2, 2], outline=1, fill=1)
>>> ImageDraw.Draw(img).line([2, 2, 2, 2, 2, 2, 2, 2], fill=1)
>>> np.array(img)
array([[0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0],
       [0, 0, 1, 0, 0],
       [0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0]], dtype=uint8)

# 2 линия

>>> img = Image.new('L', (5, 5), 0)
>>> ImageDraw.Draw(img).polygon([1, 1, 2, 1, 2, 1, 1, 1], outline=1, fill=1)
>>> ImageDraw.Draw(img).line([1, 1, 2, 1, 2, 1, 1, 1], fill=1)
>>> np.array(img)
array([[0, 0, 0, 0, 0],
       [0, 1, 1, 0, 0],
       [0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0]], dtype=uint8)

# 3 прямоугольник

>>> img = Image.new('L', (5, 5), 0)
>>> ImageDraw.Draw(img).polygon([1, 1, 2, 1, 2, 2, 1, 2], outline=1, fill=1)
>>> ImageDraw.Draw(img).line([1, 1, 2, 1, 2, 2, 1, 2], fill=1)
>>> np.array(img)
array([[0, 0, 0, 0, 0],
       [0, 1, 1, 0, 0],
       [0, 1, 1, 0, 0],
       [0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0]], dtype=uint8)

РЕДАКТИРОВАТЬ : чтобы это работало и для более длинных строк (см. Ниже), вместо .point необходимо использовать .line.

С .point

>>> img = Image.new('L', (5, 5), 0)
>>> ImageDraw.Draw(img).polygon([1, 1, 3, 1, 3, 1, 1, 1], outline=1, fill=1)
>>> ImageDraw.Draw(img).point([1, 1, 3, 1, 3, 1, 1, 1], fill=1)
>>> np.array(img)
array([[0, 0, 0, 0, 0],
       [0, 1, 0, 1, 0],
       [0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0]], dtype=uint8)

С .line

>>> img = Image.new('L', (5, 5), 0)
>>> ImageDraw.Draw(img).polygon([1, 1, 3, 1, 3, 1, 1, 1], outline=1, fill=1)
>>> ImageDraw.Draw(img).line([1, 1, 3, 1, 3, 1, 1, 1], fill=1)
>>> np.array(img)
array([[0, 0, 0, 0, 0],
       [0, 1, 1, 1, 0],
       [0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0]], dtype=uint8)
...