Disons que j'ai une image de 3841 x 7195 pixels. Je voudrais enregistrer le contenu de la figure sur le disque, ce qui donne une image de la taille exacte que je spécifie en pixels.
Pas d'axe, pas de titres. Juste l'image. Personnellement, je ne me soucie pas des DPI, car je souhaite uniquement spécifier la taille de l'image sur l'écran du disque en pixels .
J'ai lu d' autres fils , et ils semblent tous faire des conversions en pouces, puis spécifier les dimensions de la figure en pouces et ajuster les dpi d'une manière ou d'une autre. Je voudrais éviter de faire face à la perte de précision potentielle qui pourrait résulter des conversions pixel-pouces.
J'ai essayé avec:
w = 7195
h = 3841
fig = plt.figure(frameon=False)
fig.set_size_inches(w,h)
ax = plt.Axes(fig, [0., 0., 1., 1.])
ax.set_axis_off()
fig.add_axes(ax)
ax.imshow(im_np, aspect='normal')
fig.savefig(some_path, dpi=1)
sans chance (Python se plaint que la largeur et la hauteur doivent chacune être inférieures à 32768 (?))
De tout ce que j'ai vu, matplotlib
nécessite que la taille de la figure soit spécifiée dans inches
et dpi
, mais je ne suis intéressé que par les pixels que la figure prend dans le disque. Comment puis-je faire ceci?
Pour clarifier: je cherche un moyen de le faire avec matplotlib
, et non avec d'autres bibliothèques d'enregistrement d'images.
la source
Réponses:
Matplotlib ne fonctionne pas directement avec les pixels, mais plutôt avec les tailles physiques et DPI. Si vous souhaitez afficher une figure avec une certaine taille de pixel, vous devez connaître le DPI de votre moniteur. Par exemple, ce lien détectera cela pour vous.
Si vous avez une image de 3841x7195 pixels, il est peu probable que votre moniteur soit aussi grand, vous ne pourrez donc pas afficher un chiffre de cette taille (matplotlib nécessite que le chiffre tienne dans l'écran, si vous demandez une taille trop grand, il sera réduit à la taille de l'écran). Imaginons que vous vouliez une image de 800x800 pixels juste à titre d'exemple. Voici comment afficher une image de 800 x 800 pixels sur mon moniteur (
my_dpi=96
):Donc, vous divisez simplement les dimensions en pouces par votre DPI.
Si vous souhaitez enregistrer une figure d'une taille spécifique, c'est une autre affaire. Les DPI de l'écran ne sont plus si importants (sauf si vous demandez un chiffre qui ne rentre pas dans l'écran). En utilisant le même exemple de la figure 800x800 pixels, nous pouvons l'enregistrer dans différentes résolutions en utilisant le
dpi
mot - clé desavefig
. Pour l'enregistrer dans la même résolution que l'écran, utilisez simplement le même dpi:Pour l'enregistrer sous forme d'image 8000x8000 pixels, utilisez un dpi 10 fois plus grand:
Notez que le paramètre DPI n'est pas pris en charge par tous les backends. Ici, le backend PNG est utilisé, mais les backends pdf et ps implémenteront la taille différemment. En outre, la modification du DPI et des tailles affectera également des éléments tels que la taille de la police. Un DPI plus grand conservera les mêmes tailles relatives de polices et d'éléments, mais si vous voulez des polices plus petites pour un chiffre plus grand, vous devez augmenter la taille physique au lieu du DPI.
Pour revenir à votre exemple, si vous souhaitez enregistrer une image avec 3841 x 7195 pixels, vous pouvez procéder comme suit:
Notez que j'ai utilisé le chiffre dpi de 100 pour s'adapter à la plupart des écrans, mais enregistré avec
dpi=1000
pour obtenir la résolution requise. Dans mon système, cela produit un png avec 3840x7190 pixels - il semble que le DPI enregistré soit toujours 0,02 pixels / pouce plus petit que la valeur sélectionnée, ce qui aura un (petit) effet sur les grandes tailles d'image. Un peu plus de discussion à ce sujet ici .la source
figsize
àplt.figure
. La solution était de faire comme les autres réponses le suggèrent et après l'avoir appelé sansfigsize
, puis d'appelerfig.set_size_inches(w,h)
figure
etsavefig
.Cela a fonctionné pour moi, en fonction de votre code, générant une image png de 93 Mo avec un bruit de couleur et les dimensions souhaitées:
J'utilise les dernières versions PIP des bibliothèques Python 2.7 dans Linux Mint 13.
J'espère que cela pourra aider!
la source
Sur la base de la réponse acceptée par tiago, voici une petite fonction générique qui exporte un tableau numpy vers une image ayant la même résolution que le tableau:
Comme indiqué dans la réponse précédente de tiago, l'écran DPI doit être trouvé en premier, ce qui peut être fait ici par exemple: http://dpi.lv
J'ai ajouté un argument supplémentaire
resize_fact
dans la fonction qui vous permet d'exporter l'image à 50% (0,5) de la résolution d'origine, par exemple.la source
L'OP souhaite conserver les données de pixels 1: 1. En tant qu'astronome travaillant avec des images scientifiques, je ne peux autoriser aucune interpolation des données d'image car cela introduirait un bruit ou des erreurs inconnus et imprévisibles. Par exemple, voici un extrait d'une image 480x480 enregistrée via pyplot.savefig (): Détail des pixels que matplotlib a rééchantillonné pour être à peu près 2x2, mais remarquez la colonne de 1x2 pixels
Vous pouvez voir que la plupart des pixels ont simplement été doublés (donc un pixel 1x1 devient 2x2) mais certaines colonnes et lignes sont devenues 1x2 ou 2x1 par pixel, ce qui signifie que les données scientifiques d'origine ont été modifiées.
Comme l'indique Alka, plt.imsave () qui réalisera ce que l'OP demande. Supposons que vous ayez des données d'image stockées dans le tableau d'images im, alors on peut faire quelque chose comme
où le nom de fichier a l'extension "png" dans cet exemple (mais vous devez quand même spécifier le format avec format = 'png' pour autant que je sache), le tableau d'image est arr, et nous avons choisi l'échelle de gris inversée "gray_r" comme la palette de couleurs. J'ajoute généralement vmin et vmax pour spécifier la plage dynamique, mais ceux-ci sont facultatifs.
Le résultat final est un fichier png avec exactement les mêmes dimensions en pixels que le tableau im.
Remarque: l'OP n'a spécifié aucun axe, etc., ce que fait exactement cette solution. Si l'on veut ajouter des axes, des graduations, etc., mon approche préférée est de le faire sur un tracé séparé, en enregistrant avec transparent = True (PNG ou PDF) puis en superposant ce dernier sur l'image. Cela garantit que vous avez conservé les pixels d'origine intacts.
la source
plt.imsave a travaillé pour moi. Vous pouvez trouver la documentation ici: https://matplotlib.org/3.2.1/api/_as_gen/matplotlib.pyplot.imsave.html
la source