matplotlib: jak narysować prostokąt na obrazie

159

Jak narysować prostokąt na obrazie, na przykład: wprowadź opis obrazu tutaj

import matplotlib.pyplot as plt
from PIL import Image
import numpy as np
im = np.array(Image.open('dog.png'), dtype=np.uint8)
plt.imshow(im)

Nie wiem, jak mam postępować.

KAI ZHAO
źródło

Odpowiedzi:

275

Możesz dodać Rectanglepatch do osi matplotlib.

Na przykład (używając obrazu z samouczka tutaj ):

import matplotlib.pyplot as plt
import matplotlib.patches as patches
from PIL import Image
import numpy as np

im = np.array(Image.open('stinkbug.png'), dtype=np.uint8)

# Create figure and axes
fig,ax = plt.subplots(1)

# Display the image
ax.imshow(im)

# Create a Rectangle patch
rect = patches.Rectangle((50,100),40,30,linewidth=1,edgecolor='r',facecolor='none')

# Add the patch to the Axes
ax.add_patch(rect)

plt.show()

wprowadź opis obrazu tutaj

tmdavison
źródło
Dzięki za odpowiedź! Działa, ale wydaje się, że prostokąt jest rysowany na osi, a nie sam obraz. Jeśli spróbuję zapisać obraz do pliku, prostokąt nie zostanie zapisany. Czy istnieje sposób, aby prostokąt zastąpił wartości pikseli na obrazie? Dzięki jeszcze raz!
Yanfeng Liu
Nieważne. Znalazłem ten link i wygląda na to, że działa
:)
Jeśli nadal otrzymujesz wypełniony prostokąt, przekaż fill=FalseflagęRectangle
Ivanowi Talalaevowi
7
To jest dziwne. Dokumentacja patches.Rectanglemówi, że pierwsze dwie liczby to The bottom and left rectangle coordinates. Widzę tutaj, że pierwsze dwie liczby (50,100) odpowiadają GÓRNEJ i lewej współrzędnej prostokąta. Jestem zmieszany.
Monica Heddneck
3
Nie, prostokąt jest we właściwym miejscu. Jest we współrzędnych danych. Możesz zmienić transformację, jeśli chcesz, we współrzędnych osi
tmdavison
24

Nie ma potrzeby tworzenia podplotów, a pyplot może wyświetlać obrazy PIL, więc można to jeszcze bardziej uprościć:

import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle
from PIL import Image

im = Image.open('stinkbug.png')

# Display the image
plt.imshow(im)

# Get the current reference
ax = plt.gca()

# Create a Rectangle patch
rect = Rectangle((50,100),40,30,linewidth=1,edgecolor='r',facecolor='none')

# Add the patch to the Axes
ax.add_patch(rect)

Lub krótka wersja:

import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle
from PIL import Image

# Display the image
plt.imshow(Image.open('stinkbug.png'))

# Add the patch to the Axes
plt.gca().add_patch(Rectangle((50,100),40,30,linewidth=1,edgecolor='r',facecolor='none'))
James „Fluffy” Burton
źródło
23

Musisz użyć łatek.

import matplotlib.pyplot as plt
import matplotlib.patches as patches

fig2 = plt.figure()
ax2 = fig2.add_subplot(111, aspect='equal')

ax2.add_patch(
     patches.Rectangle(
        (0.1, 0.1),
        0.5,
        0.5,
        fill=False      # remove background
     ) ) 
fig2.savefig('rect2.png', dpi=90, bbox_inches='tight')
Spokój
źródło
1
Podobał mi się sposób, w jaki zamknęliście osie w obiekcie figury: osie wykonują kreślenie, figura wykonuje czynności związane z interfejsem wysokiego poziomu
Alex
7

Z mojego zrozumienia matplotlib to biblioteka kreśląca .

Jeśli chcesz zmienić dane obrazu (np. Narysować prostokąt na obrazie), możesz użyć PIL's ImageDraw , OpenCV lub czegoś podobnego.

Oto metoda PIL's ImageDraw do rysowania prostokąta .

Oto jedna z metod OpenCV do rysowania prostokąta .

Twoje pytanie dotyczyło Matplotlib, ale prawdopodobnie powinno być właśnie pytanie o rysowanie prostokąta na obrazie.

Oto kolejne pytanie, które dotyczy tego, co myślę, że chciałeś wiedzieć: Narysuj prostokąt i tekst w nim za pomocą PIL

user3731622
źródło