Farbsortierung

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.
Benutzeravatar
drewsilson
User
Beiträge: 21
Registriert: Dienstag 9. Januar 2007, 12:13

Samstag 4. Oktober 2008, 22:14

Hallo,

ich würde gerne aus einem image sämtliche farben im RGB format entnehmen und dann anschliessend nach helligkeit im sinne des menschlichen auges sortieren. soll heissen ich möchte mit einer farbskala hell nach dunkel am end dastehen.
mein ansatz sieht folgendermassen aus:

Code: Alles auswählen

@ numerix: brauch_mir_hier_nicht_anhören_wie_mies_ich_code
Meine ausgabe liste enthält listen von R,G,B werten:
RGBs = [[R,G,B,],...]

Soweit sogut. wenn ich nun aber mit RGBs.sort()
weitermache habe ich nicht das erwünschte resultat.
habe auch schon erfolgreich versucht den RGB in IHS zu transformieren, um dann nach I H oder S zu sortieren, was das ergebnis allerdings nicht besser macht.

Kann man da vielleicht was mit dem ImagePalette modul machen (so nach dem motto: eine palette aus den farben eines bildes erstellen)??

Ansonsten ist das wohl eher ne frage für ein optik-forum...sorry :shock:

Aber trotzdem schon mal danke,

micha
Zuletzt geändert von drewsilson am Samstag 4. Oktober 2008, 22:44, insgesamt 2-mal geändert.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7472
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Samstag 4. Oktober 2008, 22:21

Dazu wäre es schön zu wissen, wie unsorted_scale aussieht! Wird wohl eine Liste sein, aber was für Elemente stehen da drin? Ohne diese Angabe kann man wohl kaum sagen, wie sortiert wird.

Desweiteren habe ich keine Ahnung, wie Du / man "Helligkeit" mittels RGB definiert? Ohne den entsprechenden Ansatz würde ich wirklich erst mal danach recherchieren.
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Samstag 4. Oktober 2008, 22:28

Abgesehen davon, dass der Code insgesamt verbesserungsbedürftig ist, sind zwei Dinge anzumerken:

sort() ist eine Methode, die eine Liste in-place sortiert und nicht die sortierte Liste als Rückgabewert hat.

Du machst dir deine Liste schon dadurch kaputt, dass du ganz unnötigerweise eine neue Liste daraus machst und die Dateigröße mit hineinpackst. Damit sortierst du die äußere Liste und die hat gerade mal zwei Elemente.
Benutzeravatar
drewsilson
User
Beiträge: 21
Registriert: Dienstag 9. Januar 2007, 12:13

Samstag 4. Oktober 2008, 22:31

Oh ok.

RGBs ist eine liste mit RGB listen z.B.:

RGBs = [[R1,G1,B1],[R2,G2,B2],...,[Rn,Gn,Bn]] wobei R,G und B aus einem image entommen sind und nicht sortiert sind.
--> entspricht in etwa list(image.getdata()) aus dem Image module.

danke,
micha
Benutzeravatar
drewsilson
User
Beiträge: 21
Registriert: Dienstag 9. Januar 2007, 12:13

Samstag 4. Oktober 2008, 22:34

@ numerix:
danke für die hilfreiche aussage. ich sortiere natürlich "in-place". von daher also kein problem.

micha
Benutzeravatar
Hyperion
Moderator
Beiträge: 7472
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Samstag 4. Oktober 2008, 23:19

Naja, sort() sortiert hier eben numerisch aufsteigend. Also werden zunächst alle Farben dem Rot-Wert nach sortiert. Insofern wird ein schwarz vor anderen helleren Tönen vorkommen. Da musst Du Dir eine andere Strategie überlegen.
BlackJack

Sonntag 5. Oktober 2008, 00:11

@drewsilson: Man muss sich einfach nur eine Schlüsselfunktion basteln, die die Helligkeit eines RGB-Wertes berechnet und mit der dann absteigend sortieren:

Code: Alles auswählen

def main():
    rgbs = [(6, 65, 12), (0, 1, 0), (255, 0, 0)]
    rgbs.sort(key=lambda (r, g, b): (2 * r + 5 * g + b) / 8, reverse=True)
    print rgbs
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

Sonntag 5. Oktober 2008, 07:35

BlackJack hat geschrieben:

Code: Alles auswählen

def main():
    rgbs = [(6, 65, 12), (0, 1, 0), (255, 0, 0)]
    rgbs.sort(key=lambda (r, g, b): (2 * r + 5 * g + b) / 8, reverse=True)
    print rgbs
Ich würde ja das Y von YUV vorschlagen, war früher das Signal vom Schwarz/Weiss Fernsehen.

Code: Alles auswählen

def main():
    rgbs = [(6, 65, 12), (0, 1, 0), (255, 0, 0)]
    rgbs.sort(key=lambda (r, g, b): (0.299 * r + 0.587 * g + 0.114 * b), reverse=True)
    print rgbs
Gruss
BlackJack

Sonntag 5. Oktober 2008, 08:26

@rayo: Im Grunde machst Du das gleiche nur mit etwas anderer Gewichtung von RGB und mit Fliesskommazahlen.

Meins sieht mit Fliesskommazahlen so aus: 0.25 * r + 0.625 * g + 0.125 * b
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

Sonntag 5. Oktober 2008, 08:29

@BlackJack

Ja das war schon klar, nur halt ein wenig anderes Gewicht ;)
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Sonntag 5. Oktober 2008, 12:18

rayo hat geschrieben:Ja das war schon klar, nur halt ein wenig anderes Gewicht ;)
Könnt ihr einen Unwissenden mal aufklären, wie ihr auf diese spezielle Gewichtung kommt?

Gibt es (k)eine "Normgewichtung" für die Helligkeit von RGBs?
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

Sonntag 5. Oktober 2008, 12:57

Benutzeravatar
drewsilson
User
Beiträge: 21
Registriert: Dienstag 9. Januar 2007, 12:13

Sonntag 5. Oktober 2008, 13:20

danke leute!

hab den sw-wert auch schon probiert, aber das ist nicht sehr befriedigend (habe immer noch ausreisser in meinem output-scale-image)

die besten ergebnisse erziele ich, wenn ich R, G und B einzeln sortiere und dann wieder zu [R,G,B] zusammensetze. Allerdings habe ich dann nicht mehr exakt die farben, die ich zuvor in meinem image hatte, aber für meine zwecke reichts.

micha
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

Sonntag 5. Oktober 2008, 13:37

numerix hat geschrieben:Könnt ihr einen Unwissenden mal aufklären, wie ihr auf diese spezielle Gewichtung kommt?

Gibt es (k)eine "Normgewichtung" für die Helligkeit von RGBs?
Weil die Helligkeit nunmal Ansichtssache ist :) Dieses Gewicht entspricht einfach ungefähr dem menschlichen Auge. Aber man kann genau so gut einfach (R+G+B)/3 rechnen, nur entspricht dann das Graustufenbild nicht dem, was das Auge bei wenig Licht wahrnehmen würde (Bei wenig Licht sehen wir fast nur noch in Graustufen, also nur Umrisse).

Gruss
Benutzeravatar
Hyperion
Moderator
Beiträge: 7472
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Sonntag 5. Oktober 2008, 14:08

drewsilson hat geschrieben: die besten ergebnisse erziele ich, wenn ich R, G und B einzeln sortiere und dann wieder zu [R,G,B] zusammensetze. Allerdings habe ich dann nicht mehr exakt die farben, die ich zuvor in meinem image hatte, aber für meine zwecke reichts.
Ähem ... wie das?
Antworten