Seite 1 von 1

Speichern Bild mit passender Bouning Box

Verfasst: Donnerstag 16. Juli 2020, 13:23
von DR88
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ß

Re: Speichern Bild mit passender Bouning Box

Verfasst: Donnerstag 16. Juli 2020, 14:35
von __blackjack__
@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‽

Re: Speichern Bild mit passender Bouning Box

Verfasst: Donnerstag 16. Juli 2020, 14:51
von DR88
@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.

Re: Speichern Bild mit passender Bouning Box

Verfasst: Donnerstag 16. Juli 2020, 15:07
von DR88
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

Re: Speichern Bild mit passender Bouning Box

Verfasst: Donnerstag 16. Juli 2020, 15:25
von __blackjack__
@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

Re: Speichern Bild mit passender Bouning Box

Verfasst: Freitag 17. Juli 2020, 07:01
von DR88
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)

Re: Speichern Bild mit passender Bouning Box

Verfasst: Freitag 17. Juli 2020, 07:19
von sparrow
@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.

Re: Speichern Bild mit passender Bouning Box

Verfasst: Freitag 17. Juli 2020, 08:08
von DR88
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

Re: Speichern Bild mit passender Bouning Box

Verfasst: Freitag 17. Juli 2020, 10:21
von __blackjack__
@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.

Re: Speichern Bild mit passender Bouning Box

Verfasst: Freitag 17. Juli 2020, 11:43
von DR88
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.

Re: Speichern Bild mit passender Bouning Box

Verfasst: Freitag 17. Juli 2020, 12:57
von __blackjack__
@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