Bilder in Matrizen umwandeln

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
carrot
User
Beiträge: 19
Registriert: Montag 5. September 2011, 15:13

Hallo zusammen,
ich bin jemand mit generell eher grundlegenden Programmierkenntnissen und absoluter Neuling was Python angeht.
Ich stehe nun vor der Aufgabe jpeg-Bilder in Matrizen umzuwandeln. Ich vermute das geht irgdnwie mit imread, aber wie genau konnte ich bisher noch nicht herrausfinden.
Mein eigentliches Problem ist etwas komplexer, aber es wäre ziemlich hilfreich zumindest diesen Schritt erstmal bewältigen zu können.. ;)
Wär echt super wenn mir da jemand weiterhelfen kann! :)
LG
deets

Matrizen werden in Python ueblicherweise ueber das dritt-Paket "Numpy" verarbeitet. Und wenn man dafuer dann mal schaut findet man so einiges - zB das hier:

Code: Alles auswählen

from PIL import Image
from numpy import *

im1 = Image.open('/Users/rem7/Desktop/_1.jpg')
im1arr = asarray(im1)

CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Oder alternativ geht auch scipy.misc.fromimage.

Was genau möchtest Du denn machen, carrot?
carrot
User
Beiträge: 19
Registriert: Montag 5. September 2011, 15:13

Also es geht darum ein neuronales Netz zu trainieren und dazu muss ich aus meinem Bilder-Satz eine Datenmatrix für das Training erstellen.
Die Zeilen dieser Datenmatrix bestehen jeweils aus einer Bildmatrix als Zeilenvektor und einem weiteren Zeilenvektor für die Targets.
Ich hoffe das ist nachvollziehbar..
deets

Soll das heissen du hast das, was dir vorgeschlagen wurde nicht versucht?
carrot
User
Beiträge: 19
Registriert: Montag 5. September 2011, 15:13

deets hat geschrieben:Matrizen werden in Python ueblicherweise ueber das dritt-Paket "Numpy" verarbeitet. Und wenn man dafuer dann mal schaut findet man so einiges - zB das hier:

Code: Alles auswählen

from PIL import Image
from numpy import *

im1 = Image.open('/Users/rem7/Desktop/_1.jpg')
im1arr = asarray(im1)

Das habe versucht. Die PIL auch mal installiert, Numpy hab ich schon.
Leider erhalte ich einen Syntax Error an der Stelle "im1arr".
deets

Dann zeig uns bitte *deinen* Code, nicht meinen, und die genaue Exception.
carrot
User
Beiträge: 19
Registriert: Montag 5. September 2011, 15:13

Nee schon okay, dein Code funktioniert.
Leider sieht man dann ja nur einen Teil der Matrix (ist ein 220*79 Pixel jpg), und ich weiß nu nicht wie sie komplett ausschaut.
Ich möchte sie nun in ein externes File (z.B im dat-Format) speichern. Dazu hab ich nun einiges ausprobiert, udn zwar mit:

f = open('output.dat', 'w')
fobj.write(im1arr) #auch mal die Version mit ' ' probiert
fobj.close()

Leider bekomme ich den Inhalt des Arrays nicht in die Datei.

Habs dann mal mit

import json
f = open('output.dat', 'w')
json.dump(im1arr, f)

versucht, wo es mit einem kleinen Test-Array geklappt hatte, aber bei meinem Array folgte dann die Meldung:

"Traceback (most recent call last):
File "<pyshell#6>", line 1, in <module>
json.dump(im1arr, f)
File "C:\Python26\lib\json\__init__.py", line 180, in dump
for chunk in iterable:
File "C:\Python26\lib\json\encoder.py", line 317, in _iterencode
for chunk in self._iterencode_default(o, markers):
File "C:\Python26\lib\json\encoder.py", line 323, in _iterencode_default
newobj = self.default(o)
File "C:\Python26\lib\json\encoder.py", line 344, in default
raise TypeError(repr(o) + " is not JSON serializable")
TypeError: array([...
...], dtype=uint8) is not JSON serializable"
deets

1. Code in Code-tags setzen
2. Stacktraces in Code-tags setzen
3. Was ist das "DAT"-Format. Kenne ich nicht
4. JSON ist nicht geeignet, beliebige Binaerdaten zu serializieren.
5. Verstehe ich nicht, was du mit "Leider sieht man dann ja nur einen Teil der Matrix (ist ein 220*79 Pixel jpg)" meinst.
Benutzeravatar
gkuhl
User
Beiträge: 600
Registriert: Dienstag 25. November 2008, 18:03
Wohnort: Hong Kong

@carrot: NumPy Arrays lassen sich am besten mit "numpy.savetxt" speichern. Ansonsten wäre für dich eventuell noch die Plottinglibrary Matplotlib interessant.
carrot
User
Beiträge: 19
Registriert: Montag 5. September 2011, 15:13

@ deets:
Was genau ein dat-Format ist, kann ich dir leider nicht erklären da ich nicht vom Fach bin. Aber ich habe im Rahmen dieser Aufgabe halt mit Matrizen, gespeichert im dat-Format, gearbeitet und es hat mit meiner Toolbox ganz gut funktioniert.
Gut, wenn json nicht geeignet ist, was gäbe es dann für eien Möglichkeit?!
Weiterhin meinte ich, dass eine 220*79 Pixel Matrix ja recht groß ist, und im Idle mit dem print-Befehl nicht vollständig angezeigt wird.

@ gkuhl:
Werd mal ein bisschen mit numpy rumprobieren. Matplotlib habe ich auch.
BlackJack

@carrot: Was ist denn das Ziel des Speicherns?

Ob 229×79 schon als gross gilt, ist wohl Ansichtssache. ☺

Die Werte werden bei der Umwandlung in eine Zeichenkette nicht alle angezeigt, weil dass in der Regel nicht viel Sinn macht sich das Terminal mit den ganzen Zahlen voll zu müllen. Der Ausschnitt, denn man da sieht, ist in der Regel zu klein. Und wenn man nur kleine Ausschnitte sehen möchte, kann man sich die ja „raus slicen” denn die Auslassungspunkte kommen erst bei Arrays ab einer bestimmten Grösse. Man kann `numpy` auch dazu bewegen ein Array komplett auszugeben, egal wie gross es ist. Aber wie gesagt, wenn es zu gross ist, macht es eher Sinn nur Ausschnitte zu betrachten, oder die Daten in irgend einer sinnvollen Weise zu aggregieren. Oder mit `matplotlib` graphisch aufzubereiten.
carrot
User
Beiträge: 19
Registriert: Montag 5. September 2011, 15:13

Es wäre ja langweilig wenn alls so funktionieren würde wie man es gerne hätte ;)

Code: Alles auswählen

>>> np.savetxt('test.txt', im1arr)

Traceback (most recent call last):
  File "<pyshell#17>", line 1, in <module>
    np.savetxt('test.txt', im1arr)
  File "C:\Python26\Lib\site-packages\numpy\lib\npyio.py", line 979, in savetxt
    fh.write(asbytes(format % tuple(row) + newline))
TypeError: float argument required, not numpy.ndarray
Also das Ziel ist es aus dem Satz von Bildern eine Datensatzmatrix zu erhalten um ein neuronales Netz zu trainieren.
Im Moment wäre es zunächst mal hilfreich, wenn ich mir ein Beispielbild mal in Matrixform anschauen könnte.
deets

Funktioniert fuer mich voellig problemlos

Code: Alles auswählen

>>> import numpy as np
>>> a = np.zeros((10, 10))
>>> type(a)
<type 'numpy.ndarray'>
>>> np.savetxt("/tmp/test.txt", a)
>>> open("/tmp/test.txt").read()
'0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00\n0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00\n0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00\n0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00\n0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00\n0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00\n0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00\n0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00\n0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00\n0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00\n'
>>> 
Was macht derselbe code bei dir?
BlackJack

@carrot: Die Funktion eignet sich nur für maximal zweidimensionale Arrays. Du hast aber ein dreidimensionales. Irgendwie muss das ja auf die 2D-Struktur von Zeilen und „Spalten” einer Textdatei abgebildet werden.

Code: Alles auswählen

In [96]: img = Image.open('test.jpg')

In [97]: arr = np.asarray(img)

In [98]: arr[0, 0]
Out[98]: array([217, 216, 214], dtype=uint8)
An der Stelle kann `numpy.savetxt()` nun das Array nicht in eine Gleitkommazahl umwandeln. Daher die Fehlermeldung. Eventuell möchtest Du, wenn Du weisst wie Du die drei auf zwei Dimensionen abbildest, auch das Format beim Speichern angeben, denn Zahlen zwischen 0 und 255 als Gleitkommazahl zu formatieren ist vielleicht etwas ungünstig.
carrot
User
Beiträge: 19
Registriert: Montag 5. September 2011, 15:13

@ Black Jack:
Du hast Recht, genau das ist nun mein Problem wie ich das so sehe..
Dann muss ich nun erstmal schauen wie ich das mit den Dimensionen geregelt kriege.

@deets:
Dein Code läuft dann dementsprechend auch leider nicht mit meinem array.
carrot
User
Beiträge: 19
Registriert: Montag 5. September 2011, 15:13

Hallo nochmal!
Ich hätte in dem Zusammenhang die Frage, wie ich mein rgb-Bild in eine Colormap (jet) konvertieren kann (mit Hilfe von Python)?
LG
Benutzeravatar
gkuhl
User
Beiträge: 600
Registriert: Dienstag 25. November 2008, 18:03
Wohnort: Hong Kong

Hallo,

meinst du mit "in eine Colormap (jet) konvertieren" plotten mit Matplotlib? Um einen RGB (drei Zahlen) in eine Colormap (eine Zahl) umzuwandeln, musst du dir eine Abbildung überlegen. Zum Beispiel den Mittelwert der drei Helligkeiten. Dann kannst du z.B. mit `imshow(array, cmap='jet')` den Array darstellen.

Grüße
Gerrit

PS: Matplotlib erkennt auch RGB Farbwerte.
carrot
User
Beiträge: 19
Registriert: Montag 5. September 2011, 15:13

Danke für die schnelle Antwort.
Ich möchte die Datei komplett konvertieren, sodass sie in Matrixform nur noch 2 statt 3 Dimensionen besitzt. Ich brauche die jet-Colormap, sodass jeder Matrixeintrag (ich glaub 0-100) der Farbe eines Pixels entspricht.
BlackJack

@carrot: Wie gkuhl schon geschrieben hat: Du musst die drei Werte halt irgendwie sinnvoll auf einen Wert abbilden. Was sinnvoll bedeutet, hängt ganz von Deinem Kontext ab. Das müsstest *Du* also wissen oder entscheiden.
Antworten