Seite 1 von 1
PIL RGB-Farbwert auslesen
Verfasst: Freitag 27. Februar 2009, 16:47
von Birne94
HI^^
Wie kann ich mit PIL den Farbwert eines Pixels auslesen?
Mit getpixel kommt ich nicht weiter

Verfasst: Freitag 27. Februar 2009, 17:24
von BlackJack
@Birne94: Das geht mit `getpixel()` auf dem `Image`-Exemplar. Was heisst also Du kommst damit nicht weiter genau!?
Re: PIL RGB-Farbwert auslesen
Verfasst: Freitag 27. Februar 2009, 17:46
von OverNord
Birne94 hat geschrieben:
Wie kann ich mit PIL den Farbwert eines Pixels auslesen?
Mit getpixel kommt ich nicht weiter

Code: Alles auswählen
import Image
img = Image.open('bild.png')
img.getpixel((17, 42))
So schwer ist das doch nicht.
Verfasst: Freitag 27. Februar 2009, 18:08
von Birne94
ja. und dann erhalte ich eine Zahl, zB 19.
Wie kann ich das dann in den RGB wert umwandeln...?
Verfasst: Freitag 27. Februar 2009, 18:22
von Trundle
Es könnte sein, dass das Bild eine Farbpalette benutzt (`img.mode` müsste dann "P" sein), dann gibt `getpixel()` eben den Index zurück. An die RGB-Farbe kommst du dann mit `getpalette()` oder du konvertierst das Bild einfach vorher schon in ein RGB-Bild.
Beispiel:
Code: Alles auswählen
assert img.mode == 'P'
index = img.getpixel((1,1))
r, g, b = img.getpalette()[index * 3:index * 3 + 3]
# oder eben
r, g, b = img.convert('RGB').getpixel((1,1))
Mehrere Pixel gleichzeitig auslesen bzw. Mittelwerte bilden
Verfasst: Mittwoch 30. September 2009, 10:25
von raimund
Hallo zusammen,
dies ist mein erster Beitrag in eurem Forum. Kurz was zu mir. Ich bin was Python angeht totaler Laie und beschäftige mich seit heute morgen mit der Materie. Für meine Doktorarbeit muss ich allerdings einige Berechnungen anstellen, so dass ich mich entschieden habe, mich in Python einzuarbeiten. Dabei hat mir folgende Seite die ersten Schritte deutlich erleichtert:
http://www.wspiegel.de/pykurs/kurs_index.htm
Für euch ist das wahrscheinlich schon lange kein Thema mehr, aber man muss ja mal anfangen...
Nun zu meinem konkreten Anliegen:
Ich möchte gerne aus jpg-Bildern RGB-Information herausziehen. Der erste Schritt ist mir soeben gelungen. Ich habe mit der PIL und getpixel RGB-Daten von einem bestimmten Pixel bekommen. Super, das war mein erstes Erfolgserlebnis!
Code: Alles auswählen
from PIL import Image
import Image
im = Image.open('c:/test.jpg')
im.getpixel((x,y))
Weiter im Text: Der nächste Schritt wäre für mich, dass ich von einer bestimmten Region im Bild einen Mittelwert von den Rot- Grün- und Blau-Informationen bekomme. Konkret: ein Foto ist 500x500 pixel groß. Ich brauche von der Fläche x1=200, x2=300, y1=200 und y2=300 einen mittleren Rot, Grün und Blau-Wert. Die Standardabweichung davon könnte ich vielleicht dann selber errechen. Das wird ja dann sehr ähnlich wie die Mittelwertberechnung sein.
Habe mir schon Gedanken dazu gemacht, aber leider stecke ich noch nicht so sehr in der Programmier-Sprache drin. Die Zeit mich nun Wochen einzuarbeiten habe ich leider auch nicht. Vielleicht kennt sich ja einer von euch besser damit aus.
Würde mich über Hilfe sehr freuen!
Viele Grüße,
raimund.
Verfasst: Mittwoch 30. September 2009, 12:06
von raimund
so... nach der Mittagspause der nächste Erfolg. Ich habe es schon mal geschafft, die RGB-Daten zu trennen. In einem anderen Forum habe ich ein Skript dafür gefunden.
Danke an TheSplit aus dem gulli:board!
(Vorausgesetzt wird Python und die Installation von PIL. Das kleine Programm liest den Ordner "Images" aus und speichert jeden Bildkanal in Farbabstufungen und in Helligkeitsstufen in den Ordner "img_channels")
Code: Alles auswählen
import Image, ImageOps
from os import listdir
from string import rfind
imgfolder = 'Images'
channelfolder = 'img_channels'
channels = ['R', 'G', 'B']
for image in listdir(imgfolder):
Imgfile = Image.open(imgfolder+'\\'+image)
img_channels = Imgfile.split()
c = 0
img_name = image[:rfind(image, '.')]
img_type = image[rfind(image, '.') +1:]
for channel in img_channels:
ch_name = channels[c]
if ch_name == 'R':
color = (255,0,0)
elif ch_name == 'G':
color = (0,255,0)
elif ch_name == 'B':
color = (0,0,255)
ImageOps.colorize(channel, (0,0,0),color).save(channelfolder+'\\'+img_name+ch_name+'_color.'+img_type, 'JPEG')
channel.save(channelfolder+'\\'+img_name+ch_name+'_grey.'+img_type, 'JPEG')
c += 1
so komme ich vielleicht besser voran...
Zum Schluss sollte eh ein Skript rauskommen, dass einen ganzen Haufen Bilder automatisch verarbeitet. Daher ist das Skript von TheSplit schon mal eine große Hilfe.
Jetzt muss ich nur noch diese Mittelwerte berechnen... mmmmh....
Verfasst: Mittwoch 30. September 2009, 13:16
von mkesper
Der Code von Trundle liefert dir wesentlich direkter die einzelnen Farbwerte (er hat sie r, g, b genannt, warum wohl?) zurück.
Verfasst: Mittwoch 30. September 2009, 13:21
von raimund
ja, das ist klar. Aber ich muss die RGB-Werte ja von vielen verschiedenen Pixeln berechnen. Ich dachte, da wäre es vielleicht praktischer, erstmal die Kanäle zu trennen...
so oder so... weiß halt nicht wie ich statt "im.getpixel((x,y))" eine range von mehreren Pixeln angeben kann. Vielleicht bin ich auch total auf dem Holzweg! Mal schauen...
Verfasst: Mittwoch 30. September 2009, 14:07
von mkesper
Auch in den einzelnen Farbkanälen müsstest du die einzelnen Werte pro Wert betrachten, oder? Eventuell könnte natürlich hier
numpyeffektiver eingesetzt werden. In numpy sollte sowas wie Matrizenberechnung, Standardabweichung etc. eigentlich kein Problem sein.
Verfasst: Mittwoch 30. September 2009, 14:18
von raimund
danke, mkallas, aber ich glaube ich bin soeben fündig geworden:
mühsam ernährt sich das Eichhörnchen...
Habe was gefunden: The ImageStat Module
http://effbot.org/imagingbook/imagestat.htm
Code: Alles auswählen
import Image
import ImageStat
im = Image.open('test.jpg')
stat = ImageStat.Stat(im)
print stat.mean
Gibt mir zumindest schon mal einen Mittelwert des gesamten Bildes aus. Nun muss ich noch eine Maske definieren...
Verfasst: Mittwoch 30. September 2009, 15:20
von raimund
so... ich lasse euch ja nicht dumm sterben:
hier was zur Maske.
Code: Alles auswählen
import Image
import ImageStat
im = Image.open('c:/test.jpg')
mask = Image.open('c:/test_mask.bmp')
# Maske muss gleiche Größe wie das Originalbild haben und im Modus 1 oder L abgespeichert sein
# alle Pixel, die in der Maske ungleich null sind, werden dabei im Original ausgewertet
stat = ImageStat.Stat(im,mask)
# ohne Verwendung der Maske: "stat = ImageStat.Stat(im)"
print stat.mean
nun muss ich die Skripte noch irgendwie aneinanderhängen...
Verfasst: Mittwoch 30. September 2009, 18:30
von BlackJack
@raimund: Ich dachte der Bereich ist rechteckig!? Dann ist eine Maske vielleicht overkill. Du könntest doch einfach mit der `crop()`-Methode den überflüssigen Teil der Daten vorher entsorgen.
Verfasst: Mittwoch 30. September 2009, 18:59
von raimund
wahrscheinlich wird er rechteckig, vielleicht aber auch nicht. kannst Du mir ein kurzes Beispiel posten, wie das mit dem crop geht. Danke!
Verfasst: Mittwoch 30. September 2009, 19:34
von BlackJack
So kompliziert ist die Methode ja nicht. Was für Fragen lässt die Dokumentation denn offen?
http://effbot.org/imagingbook/image.htm ... Image.crop
Verfasst: Mittwoch 30. September 2009, 20:07
von raimund
ok, habs geschnallt. Danke nochmal für den Tipp!
btw: schöne Grüße an den User "Doik" von TheSplit!
Verfasst: Mittwoch 30. September 2009, 20:40
von BlackJack
@raimund: Wobei das Skript aus dem Gulli-Board nicht besonders gut ist.
Aus dem `string`-Modul sollte man keine Funktionen mehr verwenden, die es auch als Methoden auf Zeichenketten gibt.
`channels` zusammen mit der ``if``/``elif``-Kaskade ist unnötig indirekt und kompliziert.
Zum ermitteln von `img_name` und `img_typ` gibt es `os.path.splitext()`. Zum plattformunabhängigen zusammensetzen von Pfaden ist `os.path.join()` da.
`c` ist überfüssig, wenn man mittels `zip()` oder `itertools.izip()` über `channels` und `img_channels` gleichzeitig iteriert.
Verfasst: Mittwoch 30. September 2009, 21:10
von raimund
danke für den Hinweis, aber da ich mich erst seit wenigen Stunden mit Python geschäftige, müsstest Du ungefähr wissen, dass ich erstmal zufrieden bin, dass es funzt. Deine Änderungen würden mich vielleicht Tage oder Wochen kosten, damit es irgendwie anders funktioniert. Im Ergebnis wirds wohl keinen Unterschied machen.
Ich hoffe Du verstehst was ich meine...
Verfasst: Mittwoch 30. September 2009, 21:15
von BlackJack
@raimund: Ich verstehe schon. Leute die nur irgendwie ein Problem gelöst bekommen wollen, und denen egal ist, wie die Lösung aussieht. Amateure. Ganz furchtbar.

Verfasst: Mittwoch 30. September 2009, 21:18
von raimund
leider kann ich mich nicht in jedes Themengebiet 100%ig einarbeiten. Das ist schade. Aber zumindest habe ich heute nichts anderes gemacht, als im Internet zu suchen und zu probieren und bin eigentlich schon recht weit gekommen. Ohne Hilfe würde es halt Wochen dauern. Bin ja keiner, der hier nur ein Posting absetzt und auf n fertiges Skript wartet. Ich hoffe, den Eindruck habe ich nicht erzeugt.
Morgen früh in der Uni gehts sofort weiter... Danke!