Speichern Bild mit passender Bouning Box

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
DR88
User
Beiträge: 8
Registriert: Sonntag 8. März 2020, 16:01

Hallo zusammen,
ich möchte gern ein Bild mit

Code: Alles auswählen

fig.savefig("fname", facecolor="black", bbox_inches="tight", pad_inches=0)
abspeichen.
Was ich erwarte ist eine Datei im JPEG-Format das nur meine Objekt umschließt, was ich erhalte ist das hier:

Bild

Der y-Wert wird korrekt verarbeitet, der X-Wert allerdings nicht.

Kann mir jemand dies erklären?

Gruß
Benutzeravatar
__blackjack__
User
Beiträge: 14052
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@DR88: Ein Fehler den Du gemacht hast, oder ein Fehler in `matplotlib` (sofern ich hier richtig rate was Du da verwendest). Mehr kann man da so nicht sagen.

Wie entsteht denn das Bild? Ist `matplotlib` hier überhaupt das richtige Werkzeug‽
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
DR88
User
Beiträge: 8
Registriert: Sonntag 8. März 2020, 16:01

@long long
das Bild entsteht aus einer Punktwolke und wird über

Code: Alles auswählen

import open3d as o3d  
pcd = o3d.io.read_point_cloud(file)
colors = np.asarray(pcd.colors)
points = np.asarray(pcd.points)
eingelesen.

Die Bilder dienen später meine neuronalen Netz als Trainingsdaten.
DR88
User
Beiträge: 8
Registriert: Sonntag 8. März 2020, 16:01

mit open3d ist keine automatisierung möglich
vgl. https://github.com/intel-isl/Open3D/issues/2006

die Frage ist von mir gestellt.

Deshalb versuche ich den Weg über mpl.

Leider rennt mir ein wenig die Zeit für die Masterarbeit davon und das ganze mit einer neuen Bib umszusetzten schaffe ich leider nicht.

eine andere möglichkeit die ich probiert habe ist:

Code: Alles auswählen

bbox = BboxBase([[X.max(),Y.max()],[X.min(),Y.min()]])
fig.savefig("fname", facecolor="w", bbox_inches=bbox ,pad_inches=0)
und erhalte leider immer einen

NotImplementedError

vermutlich weil ich mpl ==2.0 verwenden.

eine höhere Version kann nicht verwendet werden da sonst die Seitenverhältnisse der Axen nicht angepasst werden können

Code: Alles auswählen

ax = fig.gca(projection='3d',elev=elev[0],azim=azim[0])
ax.set_aspect('equal')
set_aspect() wurde von den Entwicklern ab Version 3 entfernt
Benutzeravatar
__blackjack__
User
Beiträge: 14052
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@DR88: Okay, dann war die Frage nicht präzise genug: Man kann da nichts sagen wenn man nicht weiss wie *genau* das Bild entsteht. Wie gesagt, entweder machst Du irgend etwas falsch oder `matplotlib` hat einen Fehler. Solange Du das Problem nicht so beschreibst das man das so nachvollziehen kann, das man den selben Fehler bekommt, kann man da nicht mehr zu sagen als Du ohnehin schon weisst: irgendwo ist halt was falsch.

Und da ist das mit der Punktwolke eventuell sogar völlig irrelevant, wenn beispielsweise das gleiche Problem bei irgendwelchen Zufallsdaten besteht. Die Frage zielte also eher darauf ab was mit dem `Figure`-Objekt so alles angestellt wird bevor dessen `save_fig()`-Methode aufgerufen wird.

Wirf einfach mal nach und nach alles aus dem Programm raus was keinen Einfluss auf den Fehler hat, und versuche ein minimal lauffähiges Beispiel zu erzeugen das immer noch den Fehler hat, was hier jeder leicht bei sich nachvollziehen kann. Entweder findest Du auf dem Weg zu diesem Beispielprogramm selbst das Problem, oder wir können das auch mal ausprobieren und versuchen das Problem zu finden.

Edit: Nach dem neuen Beitrag vielleicht noch als Zusatz: Wenn Du exotische Versionen von irgend etwas verwendest, ist die Information natürlich auch relevant. Und verringert eventuell die Chancen auf Hilfe falls man sich dafür tatsächlich eine andere/alte Version installieren muss.

Und die Entwickler haben die Funktionalität nicht aus Spass raus genommen, sondern weil die nicht funktioniert hat, und zwar so gar nicht: https://github.com/matplotlib/matplotlib/issues/1077
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
DR88
User
Beiträge: 8
Registriert: Sonntag 8. März 2020, 16:01

python == 3.7.7
matplotlib == 2.0.0

Code: Alles auswählen

import os
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.transforms import BboxBase
from mpl_toolkits.mplot3d import Axes3D


aatn = 57
point_size=[5,7,10]
elev = [45,30,90]
azim = [0,aatn,aatn]

X= np.random.random_integers(400,450+1,1000)
Y= np.random.random_integers(400,450+1,1000)
Z= np.random.random_integers(0,600+1,1000)
colors = np.random.random(1000)

fig = plt.figure()


ax = fig.gca(projection='3d',elev=elev[0],azim=azim[0])
ax.set_aspect('equal')
scat = ax.scatter(xs=X, ys=Y, zs=Z,s=point_size[0],c=colors)
# Create cubic bounding box to simulate equal aspect ratio
max_range = np.array([X.max()-X.min(), Y.max()-Y.min(), Z.max()-Z.min()]).max()
Xb = 0.5*max_range*np.mgrid[-1:2:2,-1:2:2,-1:2:2][0].flatten() + 0.5*(X.max()+X.min())
Yb = 0.5*max_range*np.mgrid[-1:2:2,-1:2:2,-1:2:2][1].flatten() + 0.5*(Y.max()+Y.min())
Zb = 0.5*max_range*np.mgrid[-1:2:2,-1:2:2,-1:2:2][2].flatten() + 0.5*(Z.max()+Z.min())


plt.axis("off")
plt.grid(b=None) 

#plt.show()     
path_out_image = r"C:\Users\RoosDan\Documents\Python\CropPointCloud\OutputClouds\jpeg_format_test"
os.chdir(path_out_image)
#bbox = BboxBase([[X.max(),Y.max()],[X.min(),Y.min()]])
#fig.savefig("test_pointSize_{}_elev_{}_azim_{}".format(point_size[0],elev[0],azim[0]), facecolor="w", bbox_inches=bbox,pad_inches=0)
fig.savefig("test_pointSize_{}_elev_{}_azim_{}".format(point_size[0],elev[0],azim[0]), facecolor="w", bbox_inches="tight" ,pad_inches=0)
Benutzeravatar
sparrow
User
Beiträge: 4538
Registriert: Freitag 17. April 2009, 10:28

@DR88: Ich weiß nicht, ob man __blackjack__s Beitrag falsch verstehen kann, aber falls doch: Du benutzt eine uralte Version von matplotlib um eine Funktion zu nutzen, die vom Projekt entfernt wurde, weil sie nicht geht.
Also benutze bitte eine aktuelle Version und benutze nicht die, eh kaputte, Funktion.
DR88
User
Beiträge: 8
Registriert: Sonntag 8. März 2020, 16:01

matplotlib == 3.3.0

Code: Alles auswählen

import os
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.transforms import BboxBase
from mpl_toolkits.mplot3d import Axes3D


#Attribute
aatn = 57
point_size=[5,7,10]
elev = [45,30,90]
azim = [0,aatn,aatn]

X= np.random.random_integers(400,450+1,1000)
Y= np.random.random_integers(400,450+1,1000)
Z= np.random.random_integers(0,600+1,1000)
colors = np.random.random(1000)

fig = plt.figure()
ax = fig.gca(projection='3d',elev=elev[0],azim=azim[0])
ax.set_aspect("auto")
scat = ax.scatter(xs=X, ys=Y, zs=Z, s=point_size[0],c=colors)

plt.axis("on")
plt.grid() 

plt.show()     
path_out_image = r"C:\Users\RoosDan\Documents\Python\CropPointCloud\OutputClouds\jpeg_format_test"
os.chdir(path_out_image)
#split extension after "."
#bbox = BboxBase([[X.max(),Y.max()],[X.min(),Y.min()]])
fig.savefig("test_pointSize_{}_elev_{}_azim_{}".format(point_size[0],elev[0],azim[0]), facecolor="w", bbox_inches="tight" ,pad_inches=0)
damit erhalte ich das Ergebnis:
Bild

hier stimmen die Seitenverhältniss nicht. Was ich erwarte ist das hier und das bekomme ich nur hin wenn ich den ober erwähnten Code ausführe.
Bild
Benutzeravatar
__blackjack__
User
Beiträge: 14052
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@DR88: Dann musst Du das mit den Verhältnissen in 3.3.0 selbst lösen, genau wie Du das auch in 2.x.x selbst lösen musst, den das Argument "equal" geht ja dafür auch nicht. Schau Dir die Beispiele in dem Fehlerbericht auf Github an — die Daten passen dann nicht mehr zum Grid. Auch wenn es so ähnlich aussehen mag wie das was Du willst, wenn die Beschriftung von den tatsächlichen Daten abweicht, dann ist die Zeichnung halt nicht mehr zu gebrauchen.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
DR88
User
Beiträge: 8
Registriert: Sonntag 8. März 2020, 16:01

ich stelle die Frage hier weil ich es nicht verstehe. Ich bin kein IT-ler und es fällt mir sehr schwer.

ich werde jetzt eine anderen weg gehen und mit die die gespeicherten Bilder nochmals mit cv bearbeiten und mit eine bbox um die nicht-weißen pixel legen und ausschneiden.

Danke trotzdem für eure Zeit.
Benutzeravatar
__blackjack__
User
Beiträge: 14052
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@DR88: Was genau verstehst Du daran nicht das ``set_aspect('equal')`` bei 3D-Plots nicht funktioniert? Das produziert falsche Ergebnisse. Da sind Bilder im Fehlerbericht auf Github bei denen das *deutlich* zu sehen ist. Da muss man weder von Rechnern, Programmieren, oder Mathematik Ahnung haben — man sieht ganz deutlich das die geplotteten Daten nicht mehr zum Gitter und der Beschriftung passen.

Besonders einfaches und sehr deutliches Beispiel ist wie der Einheitswürfel nach dem Aufruf aussieht: https://github.com/matplotlib/matplotli ... t-14006279
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Antworten