282 votes

matplotlib : comment dessiner un rectangle sur une image

Comment dessiner un rectangle sur une image, comme ceci : enter image description here

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)

Je ne sais pas comment procéder.

483voto

tom Points 25939

Vous pouvez ajouter un Rectangle patch pour les Axes de matplotlib.

Par exemple (en utilisant l'image du tutoriel ici ) :

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

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

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

# 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()

enter image description here

1 votes

Merci pour votre réponse ! Cela fonctionne, mais il semble que le rectangle soit dessiné sur l'axe, et non l'image elle-même. Si j'essaie d'enregistrer l'image dans un fichier, le rectangle ne sera pas sauvegardé. Existe-t-il un moyen pour que le rectangle remplace les valeurs des pixels de l'image ? Merci encore !

0 votes

C'est pas grave. J'ai trouvé ceci lien et cela semble fonctionner : )

0 votes

Si vous obtenez toujours un rectangle rempli, passez la commande suivante fill=False pour Rectangle

61voto

user2665315 Points 61

Il n'est pas nécessaire d'utiliser des sous-points, et pyplot peut afficher des images LIP, ce qui permet de simplifier encore les choses :

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)

Ou, la version courte :

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'))

29voto

Serenity Points 16825

Vous devez utiliser des correctifs.

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')

4 votes

J'ai aimé la façon dont vous avez encapsulé les axes dans un objet figure : les axes font le tracé, la figure s'occupe de l'interface de haut niveau.

7voto

user3731622 Points 1299

D'après ce que j'ai compris matplotlib est une bibliothèque de traçage.

Si vous souhaitez modifier les données de l'image (par exemple, dessiner un rectangle sur une image), vous pouvez utiliser la commande suivante ImageDraw de PIL , OpenCV ou quelque chose de similaire.

Voici La méthode ImageDraw de PIL pour dessiner un rectangle .

Voici l'une des Les méthodes d'OpenCV pour dessiner un rectangle .

Votre question portait sur Matplotlib, mais vous auriez probablement dû vous contenter de demander comment dessiner un rectangle sur une image.

Voici une autre question qui répond à ce que vous vouliez savoir, je pense : Dessiner un rectangle et un texte à l'intérieur à l'aide du LIP

4voto

Aelius Points 407

Si vous disposez d'un ensemble de coordonnées de points ordonnés, vous pouvez également utiliser la fonction plot et les tracer directement sans utiliser le patch Rect. Je recrée ici l'exemple proposé par @tmdavison en utilisant cette fonction :

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

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

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

# Display the image
ax.imshow(im)

# Coordinates of rectangle vertices
# in clockwise order
xs = [50, 90, 90, 50, 50]
ys = [100, 100, 130, 130, 100]
ax.plot(xs, ys, color="red")

plt.show()

stinkbug photo with red rectangle identifying a small zone

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X