Zum Forum springen
Matrix interpoliere...
 
Benachrichtigungen
Alles löschen

Matrix interpolieren mit Origin oder Freeware

21 Beiträge
6 Benutzer
10 Reactions
1,869 Ansichten
Snookz
Beigetreten: 13.06.2008

Ich brauche die geballte Hilfe des Forums und hoffe, dass sich hier jemand damit auskennt!
Konkret geht es um folgendes:
Ich habe eine Matrix, die Höhenwerte enthält (Messwerte eines Konfokalmikroskops). Die Werte liegen als .csv im Format x,y,z vor. Z ist obv. die Höhe. An manchen stellen gibt es Messfehler wegen des Messprinzips, der z-Wert ist da 0. Bei gültigen Messpunkten ist der z-Wert immer >0, d. h. ich kann die fehlenden Messwerte eindeutig identifizieren.
Prinzipbedingt liefert das Konfokalmikroskop keinen Wert, wenn die Steigung der gemessenen Oberfläche an einem bestimmten Punkt x,y zu groß ist - es wird nicht genügend Licht reflektiert, um eine gültige Messung zu erhalten.
Liegt beispielsweise eine Kugel auf einer sonst ebenen Oberfläche, bekomme ich an den Flanken der Kugel keine Messwerte. Ich würde jetzt gerne zwischen den gültigen Messwerte interpolieren, als würde ich ein sehr dünnes Tuch über die Kugel legen.

Kennt da jemand ein Programm, dass mir die Daten in der Art manipulieren kann? Grundsätzlich könnte ich die Nullen auch durch NaN oder so ersetzen, falls das Programm das erfordern würde. Die manipulierten Daten brauche ich, um einen 3D-Plot zu erzeugen und Oberflächenkennwerte zu berechnen.


Antwort
Zitat
20 Antworten
Penishaubize
Beigetreten: 04.06.2006

Kannst du dir das nicht Recht schnell mit einer Programmiersprache deiner Wahl zusammenbasteln?


Antwort
Zitat
Snookz
Beigetreten: 13.06.2008

Theoretisch ja, aber ich würde mindestens eine Spline-Interpolation machen wollen und weiß außerdem nicht, ob man zeilen- oder spaltenweise interpoliert bzw. ob man dazwischen nochmal glätten würde. Ich hoffe ja, dass es da schon Algorithmen gibt.


Antwort
Zitat
honeybadgerrg
Beigetreten: 26.04.2012

Original von Snookz
Bei gültigen Messpunkten ist der z-Wert immer >0, d. h. ich kann die fehlenden Messwerte eindeutig identifizieren.
Prinzipbedingt liefert das Konfokalmikroskop keinen Wert, wenn die Steigung der gemessenen Oberfläche an einem bestimmten Punkt x,y zu groß ist - es wird nicht genügend Licht reflektiert, um eine gültige Messung zu erhalten.

In Matlab, Python, ... die CSV importieren. Vermutlich alle Zeilen mit z=0 löschen.

Original von SnookzLiegt beispielsweise eine Kugel auf einer sonst ebenen Oberfläche, bekomme ich an den Flanken der Kugel keine Messwerte. Ich würde jetzt gerne zwischen den gültigen Messwerte interpolieren, als würde ich ein sehr dünnes Tuch über die Kugel legen.

In Matlab bspw. interp3 oder interpn. In Python analog scipy.interpolate.interpn.

Original von SnookzDie manipulierten Daten brauche ich, um einen 3D-Plot zu erzeugen und Oberflächenkennwerte zu berechnen.

Brauchst du für einen simplen 3d-Plot wirklich die interpolierten Werte? Für den Plot sollten die Messwerte genügen. Für letzteres eventuell lieber eine Funktion fitten?


Antwort
Zitat
Rho0
Beigetreten: 20.10.2008

dafür gibt s ne extra funktion in scipy


Antwort
Zitat
Snookz
Beigetreten: 13.06.2008

Vielen Dank, das sieht exakt nach dem aus, das ich brauche!
Ich kann ganz ok programmieren, bin aber totaler Noob in Python.
Wie gehe ich das jetzt am besten? Zuerst bräuchte ich ja irgendeine IDE, dann ein kleines Snippet, um meine Daten einzulesen und müsste die dann in Python in ein Array kopieren und den Rest würde dann die interpolate-Funktion übernehmen, oder?
Kann jemand eine IDE empfehlen?

Edit:
Hier nur mal als Beispielbild, damit man sieht, wie die Rohdaten aussehen:


Antwort
Zitat
Rho0
Beigetreten: 20.10.2008

ich benutze Anaconda als Umgebung und Spyder als IDE. Wenn Du Anaconda installierst, dann gibt s ne Anaconda Prompt (sowas ähnliches wie cmd.exe), da kannste einfach "Spyder" (ohne Anführungszeichen) eingeben, und es startet Spyder.

Ich nehme jetzt an, Deine Datei hat das Format "x;y;z;"

Dann wäre mein Code:

import scipy
import numpy as np
import matplotlib.pyplot as plt

myfile = open( "Pfad zur Datei", "r" )

x = []
y = []
z = []

for line in myfile:
E string_split = line.split( ";" )

E var_z = np.float( string_split[2] )

E if var_z > 0.0:

EE x.append( np.float( string_split[0] ) )
EE y.append( np.float(string_split[1]))
EE z.append(var_z )

damit hast du die daten eingelesen und in den listen x, y und z gespeichert.

ok, das forum mag einrückungen nicht.... E steht für Einrückung, EE steht für doppelte Einrückung.


Antwort
Zitat
Penishaubize
Beigetreten: 04.06.2006

Aus interesse, was sind das für Proben?


Antwort
Zitat
Snookz
Beigetreten: 13.06.2008

Mit einem gepulsten Nd:YAG-Laser behandelte Oberflächen aus 1.4301, ns-Laser, also kein Ultrakurzpuls.


Antwort
Zitat
Snookz
Beigetreten: 13.06.2008

Rho0, vielen Dank!
Ich probiere das morgen direkt aus :)


Antwort
Zitat
DiscoD
Beigetreten: 11.02.2006

Ich würde erstmal AyCarambas und Paxis‘ Meinung abwarten.


Antwort
Zitat
Coach
Paxis
Beigetreten: 01.11.2006

Hab zwar mal Programmieren in meiner Ausbildung gelernt aber nie gemocht. Von daher nicht weiter mit beschäftigt und kann gar nichts mehr :|
Kann da nicht weiterhelfen. Wer weiterhelfen könnte wäre wohl KTU aber der ist leider nicht mehr aktiv hier.


Antwort
Zitat
Snookz
Beigetreten: 13.06.2008

Original von honeybadgerrg

Original von Snookz
Die manipulierten Daten brauche ich, um einen 3D-Plot zu erzeugen und Oberflächenkennwerte zu berechnen.

Brauchst du für einen simplen 3d-Plot wirklich die interpolierten Werte? Für den Plot sollten die Messwerte genügen. Für letzteres eventuell lieber eine Funktion fitten?

Das war für mich bis gerade ehrlich gesagt identisch. Wenn ich den 3D-Plot mache, müssen ja Daten für die Punkte vorliegen. Ich würde dieselben Daten dann für die Berechnung nutzen (ich rechne da ja über die Fläche und nicht über eine Linie).
Bekomme ich aus Python die Daten, die für den Plot verwendet wurden, auch irgendwie wieder heraus?


Antwort
Zitat
Snookz
Beigetreten: 13.06.2008

Brauche wohl doch nochmal Hilfe, so sieht mein Code jetzt aus (ohne Plotten, bekomme vorher einen Error):

myfile = open( "L12_py.csv", "r" )


x = []
y = []
z = []

for line in myfile:
    string_split = line.split(",")

    intensity = np.float(string_split[3])

    if intensity > 0:

        x.append(np.float(string_split[0]))
        y.append(np.float(string_split[1]))
        z.append(np.float(string_split[2]))
        print(string_split[2])

grid_x, grid_y = np.mgrid[0:160:10000j, 0:160:10000j]

t = (x,y)

from scipy.interpolate import griddata
grid_z0 = griddata(t, z, (grid_x, grid_y), method='nearest')
grid_z1 = griddata(t, z, (grid_x, grid_y), method='linear')
grid_z2 = griddata(t, z, (grid_x, grid_y), method='cubic')
  File "Continuum\anaconda3\lib\site-packages\scipy\interpolate\ndgriddata.py", line 81, in __call__
    return self.values[i]

TypeError: only integer scalar arrays can be converted to a scalar index

Wenn ich das richtig verstehe, habe ich aber doch mit t = (x,y) alle Wertepaare und mit z auch die Höhendaten, oder?
Das Grid definiere ich von 0 - 160 für x und y, das ist ja mein Messbereich.
Wo mache ich den Fehler?

Edit: Also ich glaube der Fehler ist, dass das tuple nicht funktioniert und irgendwie in ein 2D-Array muss.


Antwort
Zitat
honeybadgerrg
Beigetreten: 26.04.2012

Original von Snookz
Das war für mich bis gerade ehrlich gesagt identisch. Wenn ich den 3D-Plot mache, müssen ja Daten für die Punkte vorliegen. Ich würde dieselben Daten dann für die Berechnung nutzen (ich rechne da ja über die Fläche und nicht über eine Linie).
Bekomme ich aus Python die Daten, die für den Plot verwendet wurden, auch irgendwie wieder heraus?

Joar, du bekommst die Punkte schon aus der Interpolation, aber ich finde es komplizierter danach einzelne Punkte aus der Matrix zu suchen + du musst hoffen, dass der Punkt auch interpoliert wurde. Als Funktion könntest du einfach die Werte eingeben und kriegst den interpolierten Wert zurück.

Wenn ich das richtig verstehe, habe ich aber doch mit t = (x,y) alle Wertepaare und mit z auch die Höhendaten, oder?
Das Grid definiere ich von 0 - 160 für x und y, das ist ja mein Messbereich.

Wo mache ich den Fehler?

Hier die erste Antwort von google:
https://stackoverflow.com/questions/46902367/numpy-array-typeerror-only-integer-scalar-arrays-can-be-converted-to-a-scalar-i

Ansonsten hatte ich mit 3D Scatterdaten auch schon solche Probleme. Wenn du diese nur visualisieren möchtest habe ich diese glaube als quickfix damals trianguliert um eine "schöne" Surface zu bekommen.

Könntest du ansonsten deine CSV hier posten (oder einen Teil)? Dann schaue ich mal drüber. Kann dir auch empfehlen sowas mit pandas einzulesen, da du dir damit den kompletten ersten Part zum einlesen sparen kannst und schließend auch gut Werte mit Null löschen kannst.


Antwort
Zitat
Snookz
Beigetreten: 13.06.2008

Danke für die ausführliche Antwort!
Also Import funktioniert nun, die x,y-Paare habe ich in ein Array transformiert und bekomme einen neuen Error.

grid_x, grid_y = np.mgrid[0:160:10000j, 0:160:10000j]

t = (x,y)

array = np.asarray(t)
ValueError: different number of values and points

Die Points sind ja jetzt in 'array', das sollte eigentlich genau so groß sein wie die Liste der z-points, weil die Längen von x, y und z wegen dem Importcode identisch sein müssen. Ich probiere mal weiter...

CSV ist 27mb groß, habs hier mal hochgeladen: https://drive.google.com/open?id=1zCq85Cam8oeUtdjGdfQrniX3q4YRAQ1A

Was meinst du genau mit Funktion? Ich kenne mich offenbar damit leider viel zu wenig aus. Kann ich irgendwo einfach die csv reinwerfen und bekomme Höhenkennwerte zurück?


Antwort
Zitat
honeybadgerrg
Beigetreten: 26.04.2012

Probier mal ob der Code das macht was du möchtest. Habe ich selber nur eben zusammenkopiert, sonst muss ich noch einmal genauer schauen (oder alten Code von mir suchen). Läuft aber durch. Habe in Data CSV die ersten 10.000 Zeilen deiner CSV kopiert, da mir das ansonsten zu lange gedauert hat die ganze Datei zu laden:

Spoiler
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
import warnings
warnings.simplefilter(action='ignore', category=FutureWarning)
import pandas as pd
from pandas import ExcelWriter
import numpy as np
from scipy.interpolate import griddata

# ich lasse hier die ersten 6 zeilen weg, da das nur informationen waren. die 7. Zeile war dann der headder mit den spaltennamen 
df = pd.read_csv('Data.csv', sep=',',
                         decimal=".",skiprows=6, error_bad_lines=False)

# lösche intensity == 0
df = df[df.Intensity != 0]

x=df['# X']
y=df['Y']
z=df['Z']

# target grid to interpolate to
xi =  np.arange(0,np.max(x),0.01)
yi = np.arange(0,np.max(y),0.01)
xi,yi = np.meshgrid(xi,yi)

# interpolate
zi = griddata((x,y), z, (xi,yi), method='linear')

# plot
fig = plt.figure()
ax = fig.gca(projection='3d')
surf = ax.plot_surface(xi, yi, zi)
plt.xlabel('xi',fontsize=16)
plt.ylabel('yi',fontsize=16)
plt.savefig('interpolated.png',dpi=100)
plt.show()
plt.close(fig)

Was meinst du genau mit Funktion? Ich kenne mich offenbar damit leider viel zu wenig aus. Kann ich irgendwo einfach die csv reinwerfen und bekomme Höhenkennwerte zurück?

Meine das müsste so gehen, sobald du einmal eine Interpolante bestimmt hast. Aber ich denke es reicht auch einfach ein sehr genauer Plot.


Antwort
Zitat
Snookz
Beigetreten: 13.06.2008

Läuft durch und gibt mir einen Plot zurück!
Gibt allerdings noch eine Warning:

UserWarning: Z contains NaN values. This may result in rendering artifacts.

Zumindest in dem Bild, was er ausgibt, sehe ich aber keine Artefakte (die "ungültigen" z-Werte in den Ausgangsdaten sind 4.2).

Jetzt muss ich nur noch herausfinden, wie ich die neuen Werte wieder in eine csv bekomme


Antwort
Zitat
honeybadgerrg
Beigetreten: 26.04.2012

Entweder über numpy die Arrays speichern, oder die Arrays wieder als pandas dataframe und df.to_csv verwenden:

https://stackoverflow.com/questions/6081008/dump-a-numpy-array-into-a-csv-file


Antwort
Zitat
Snookz
Beigetreten: 13.06.2008

Vielen Dank für die Hilfe!
Wenn ich das nun exportiere, muss ich aber xi, yi und zi exportieren, oder?
Das sind ja dann die interpolierten Koordinaten (xi, yi) und die interpolierte Höhe (zi).
Das delta_x und _y der Ausgangsdaten ist ja 0.16, beim Grid ist es 0.01. Habe ich dann beim Export der Daten mehr Zeilen (also ~160/0.01 dann)?

Und wirklich Danke nochmal, werde Python wohl demnächst öfter nutzen, wenn ich sowas zu tun habe.


Antwort
Zitat