aasche
Anmeldungsdatum: 30. Januar 2006
Beiträge: 14259
|
Prof. Frink schrieb: Wenn da Interesse ist, würde ich wenn ich mit meiner Prüfung durch bin (habe gerade nicht so viel Zeit), das noch mal überarbeiten, Sortierung nach einer Fläche implementieren, schneller machen (Vielleicht auch mit C-Code ?), für die Verwendung mit mehr Programmen optimieren usw. und dann könnte ich einen Artikel darüber schreiben.
Interesse ist auf jeden Fall vorhanden, denn eine Alternative zu ImageSorter 🇬🇧 konnte ich bisher unter Linux nicht finden.
|
Prof._Frink
Anmeldungsdatum: 29. Mai 2010
Beiträge: 1096
|
aasche schrieb: Interesse ist auf jeden Fall vorhanden, denn eine Alternative zu ImageSorter 🇬🇧 konnte ich bisher unter Linux nicht finden.
Ja, okay, ich hätte auch Spaß daran soetwas zu schreiben, ich denke die optimale performance würde man erreichen, wenn man den Code von identify so umschreibt, dass er nur noch die RGB-Daten liest und dann auch gleich schon die Projektionen berechnet, sodass man den Inhalt der while-Schleife durch eine C-Routine ersetzen könnte (eine abgewandelte Version des jetzigen Skripts, ohne C, könnte man ja alternativ anbieten). Ansonsten müsste man sich noch mal überlegen, ob die jetztige Lösung mit symbolischen Links, nicht irgendwie besser ginge, obwohl es natürlich den Vorteil hat, dass man irgendein Programm benutzen kann, das Bilder nach Namen sortieren kann. Aber ohne es jetzt überprüft zu haben, kann ich mir vorstellen, dass es dann wieder Probleme bei der Verwaltung der Bilder mit dem Programm gibt, weil es ja halt nur auf Links zugreift. Wer dazu noch Ideen hat, kann die hier ja mal mitteilen. Grüße Frink
|
Amrius
(Themenstarter)
Anmeldungsdatum: 9. Februar 2006
Beiträge: 94
|
Wow, vielen Dank schon einmal!
Eigentlich hatte ich ja gehofft dass es so etwas schon fertig gibt, aber da das ja nicht der Fall zu sein scheint sieht dein Skript schon einmal vielversprechend aus! Ich werde einmal versuchen, damit weiterzuarbeiten. Was für Verbesserungen mir spontan einfallen:
- Umrechnung der RGB-Werte in den HSV-Farbraum und anschließendes Ordnen nach dem H-Anteil (=Farbton) - damit wäre es dann möglich, einen kompletten Farbverlauf mit allen Farben (ohne Berücksichtigung von Helligkeit und Sättigung) darzustellen
- Aufsplitten in 2 Skripte und speichern der relevanten Daten (Pfad/Dateiname, RGB-Werte) in eine Textdatei - dann müsste man die Bilddateien nur noch einmal erfassen und könnte danach sehr viel schneller nach verschiedenen Kriterien ordnen. Im Moment braucht das Skript bei mir ca. 4 Sekunden pro Bild
|
Prof._Frink
Anmeldungsdatum: 29. Mai 2010
Beiträge: 1096
|
Hey, schön, dass du schon mal was damit anfangen kannst und das sind wirklich gute Hinweise: Amrius schrieb: - Umrechnung der RGB-Werte in den HSV-Farbraum und anschließendes Ordnen nach dem H-Anteil (=Farbton) - damit wäre es dann möglich, einen kompletten Farbverlauf mit allen Farben (ohne Berücksichtigung von Helligkeit und Sättigung) darzustellen
Den Farbraum kannte ich noch gar nicht, aber der H-Wert ist wirklich interessant, das würde die Berechnung auch sehr viel schneller machen.
- Aufsplitten in 2 Skripte und speichern der relevanten Daten (Pfad/Dateiname, RGB-Werte) in eine Textdatei - dann müsste man die Bilddateien nur noch einmal erfassen und könnte danach sehr viel schneller nach verschiedenen Kriterien ordnen.
Jop, hatte ich auch schon so angedacht.
Im Moment braucht das Skript bei mir ca. 4 Sekunden pro Bild
Wie gesagt, wenn man es schafft identify, so zu beschneiden, dass es nur noch die rgb-Mittelwerte liest und die Berechung in eine C-Routine verlagert, bzw. gleich noch auf HSV umsteigt, dann sollte das sehr viel schneller gehen. Ich werde nächste Woche mal einen ersten Anlauf machen. Grüße Frink
|
Antiqua
Anmeldungsdatum: 30. Dezember 2008
Beiträge: 4532
|
Nur so eine Idee, imagemagick kann schön Histogramme ausgeben. Bringt euch so eine Ausgabe weiter? $ convert einBild.jpg -alpha off +dither -colors 32 -depth 8 +repage -colorspace HSL -format %c histogram:info:-
38252: ( 0,126, 48) #007E30 hsl(0%,49.4743%,18.6282%)
89822: ( 0,204, 30) #00CC1E hsl(0%,80%,11.7647%)
77134: ( 1,210, 46) #01D22E hsl(0.222782%,82.417%,17.8439%)
170363: ( 1,229, 39) #01E527 hsl(0.238041%,89.7429%,15.2941%)
257976: ( 1,219, 22) #01DB16 hsl(0.450141%,86.0472%,8.43214%)
55494: ( 1,158, 55) #019E37 hsl(0.489815%,61.8189%,21.5686%)
48330: ( 1,101, 76) #01654C hsl(0.555428%,39.4736%,29.8039%)
98901: ( 2,235, 13) #02EB0D hsl(0.694285%,92.3079%,5.09804%)
47297: ( 2,181, 48) #02B530 hsl(0.724804%,71.1345%,19.0188%)
51105: ( 2,121, 38) #027926 hsl(0.926223%,47.3686%,14.902%)
28412: ( 3, 90, 62) #035A3E hsl(1.1368%,35.4833%,24.3137%)
32505: ( 3,124, 58) #037C3A hsl(1.16884%,48.7175%,22.9404%)
15996: ( 6, 62, 95) #063E5F hsl(2.17441%,24.21%,37.2549%)
61370: ( 6,138, 31) #068A1F hsl(2.52537%,54.0978%,11.9615%)
16956: ( 8, 78,107) #084E6B hsl(3.33257%,30.5165%,41.7655%)
12951: ( 11, 88, 84) #0B5854 hsl(4.31067%,34.5235%,32.9412%)
7122: ( 11, 24,100) #0B1864 hsl(4.38544%,9.54757%,39.0204%)
15264: ( 12, 61,124) #0C3D7C hsl(4.51972%,23.8865%,48.4321%)
22038: ( 12, 90,127) #0C5A7F hsl(4.86915%,35.1781%,49.6086%)
10168: ( 13, 65,196) #0D41C4 hsl(5.00038%,25.4231%,76.8627%)
6920: ( 13, 69, 42) #0D452A hsl(5.0721%,27.0588%,16.6659%)
7768: ( 13,110, 99) #0D6E63 hsl(5.09804%,43.1479%,38.6282%)
12098: ( 14, 37,159) #0E259F hsl(5.35744%,14.583%,62.3529%)
10189: ( 14, 65,145) #0E4191 hsl(5.35744%,25.4551%,56.8627%)
73771: ( 14,153, 2) #0E9902 hsl(5.55581%,60%,0.979629%)
5009: ( 17, 59, 72) #113B48 hsl(6.56596%,23.0762%,28.04%)
9086: ( 23, 76, 19) #174C13 hsl(9.09133%,29.7292%,7.25566%)
724: ( 25,140,149) #198C95 hsl(9.91379%,54.7173%,58.4314%)
291: (223,116,152) #DF7498 hsl(87.4113%,45.6306%,59.6078%)
306: (244, 64, 77) #F4404D hsl(95.7259%,25.1606%,30.3914%)
857: (253,140, 88) #FD8C58 hsl(99.3133%,54.8028%,34.7051%)
26245: (254,178, 60) #FEB23C hsl(99.8016%,69.9992%,23.5294%)
Die Ausgabe ist also nicht vom Originalbild, sondern die Ausgabe ist, als wäre der Alphakanal entfernt, dithering aus, auf 32 Farben und 8bit Tiefe reduziert. Das reicht doch zum Vergleichen locker, oder?
|
Prof._Frink
Anmeldungsdatum: 29. Mai 2010
Beiträge: 1096
|
Antiqua schrieb: Nur so eine Idee, imagemagick kann schön Histogramme ausgeben. Bringt euch so eine Ausgabe weiter? $ convert einBild.jpg -alpha off +dither -colors 32 -depth 8 +repage -colorspace HSL -format %c histogram:info:-
38252: ( 0,126, 48) #007E30 hsl(0%,49.4743%,18.6282%)
89822: ( 0,204, 30) #00CC1E hsl(0%,80%,11.7647%)
77134: ( 1,210, 46) #01D22E hsl(0.222782%,82.417%,17.8439%)
170363: ( 1,229, 39) #01E527 hsl(0.238041%,89.7429%,15.2941%)
257976: ( 1,219, 22) #01DB16 hsl(0.450141%,86.0472%,8.43214%)
55494: ( 1,158, 55) #019E37 hsl(0.489815%,61.8189%,21.5686%)
48330: ( 1,101, 76) #01654C hsl(0.555428%,39.4736%,29.8039%)
98901: ( 2,235, 13) #02EB0D hsl(0.694285%,92.3079%,5.09804%)
47297: ( 2,181, 48) #02B530 hsl(0.724804%,71.1345%,19.0188%)
51105: ( 2,121, 38) #027926 hsl(0.926223%,47.3686%,14.902%)
28412: ( 3, 90, 62) #035A3E hsl(1.1368%,35.4833%,24.3137%)
32505: ( 3,124, 58) #037C3A hsl(1.16884%,48.7175%,22.9404%)
15996: ( 6, 62, 95) #063E5F hsl(2.17441%,24.21%,37.2549%)
61370: ( 6,138, 31) #068A1F hsl(2.52537%,54.0978%,11.9615%)
16956: ( 8, 78,107) #084E6B hsl(3.33257%,30.5165%,41.7655%)
12951: ( 11, 88, 84) #0B5854 hsl(4.31067%,34.5235%,32.9412%)
7122: ( 11, 24,100) #0B1864 hsl(4.38544%,9.54757%,39.0204%)
15264: ( 12, 61,124) #0C3D7C hsl(4.51972%,23.8865%,48.4321%)
22038: ( 12, 90,127) #0C5A7F hsl(4.86915%,35.1781%,49.6086%)
10168: ( 13, 65,196) #0D41C4 hsl(5.00038%,25.4231%,76.8627%)
6920: ( 13, 69, 42) #0D452A hsl(5.0721%,27.0588%,16.6659%)
7768: ( 13,110, 99) #0D6E63 hsl(5.09804%,43.1479%,38.6282%)
12098: ( 14, 37,159) #0E259F hsl(5.35744%,14.583%,62.3529%)
10189: ( 14, 65,145) #0E4191 hsl(5.35744%,25.4551%,56.8627%)
73771: ( 14,153, 2) #0E9902 hsl(5.55581%,60%,0.979629%)
5009: ( 17, 59, 72) #113B48 hsl(6.56596%,23.0762%,28.04%)
9086: ( 23, 76, 19) #174C13 hsl(9.09133%,29.7292%,7.25566%)
724: ( 25,140,149) #198C95 hsl(9.91379%,54.7173%,58.4314%)
291: (223,116,152) #DF7498 hsl(87.4113%,45.6306%,59.6078%)
306: (244, 64, 77) #F4404D hsl(95.7259%,25.1606%,30.3914%)
857: (253,140, 88) #FD8C58 hsl(99.3133%,54.8028%,34.7051%)
26245: (254,178, 60) #FEB23C hsl(99.8016%,69.9992%,23.5294%)
Die Ausgabe ist also nicht vom Originalbild, sondern die Ausgabe ist, als wäre der Alphakanal entfernt, dithering aus, auf 32 Farben und 8bit Tiefe reduziert. Das reicht doch zum Vergleichen locker, oder?
Hey, danke für den Hinweis, allerdings sind die Histogramme nicht so gut zum Sortieren geeignet; im Endeffekt will man jedem Bild möglichst einen Wert zuordnen können, nach dem man sortiert.
Aber dein Vorschlag hat mich drauf gebracht, noch mal ein bisschen die Imagemagick-Homepage zu durchstöbern und so bin ich jetzt zu folgenden beiden Befehlen gekommen: convert bild.jpg -colorspace HSL -scale 1x1\! -format '%[pixel:s]' info:- bzw. convert bild.jpg -colorspace RGB -scale 1x1\! -format '%[pixel:s]' info:- damit bekommt man die Mittelwerte für den jeweiligen Raum direkt, indem man das Bild auf ein Pixel zusammenzieht, d.h. man braucht nicht den Code umzuschreiben, die Funktion gibt es schon. Und wenn man jetzt noch den H-Wert zum Sortieren benutzt, ist es wirklich ein sehr einfaches Skript, das aber schon recht schnell sein sollte. Man muss sich vielleicht nur noch mal genauer Gedanken machen, was man eigentlich als Ausgabe will, ob die Lösung mit den symbolischen Links wirklich schon so gut ist, bzw. mit welchem Programm man optimaler Weise wie weiterarbeitet, um die Bilder zu sortieren. Eine Anwendung, die man leicht implementieren könnte, die unabhängig von weiteren grafischen Oberflächen ist, wäre das Aufspüren von Duplikaten, bzw. nur leicht veränderten Bilder anhand dieser Mittelwerte. Grüße Frink
|
Prof._Frink
Anmeldungsdatum: 29. Mai 2010
Beiträge: 1096
|
Hier noch mal eine Version, die nach dem H-Wert sortiert, für 346 sehr kleine Bilder, hat das bei mir gerade nur 4 Sekunden (also insgesamt) gedauert. 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 | #!/bin/bash
#Aufruf: bash skriptname "Pfad zum Ordner"
find "$1" -iname "*.jpg" > files.txt
#Ordner erzeugen
base=$(basename $1)
folder=$(echo "H-Wert-$base")
if [[ ! -d $folder ]];then
mkdir $folder
fi
while read file; do
#H-Wert lesen
h=$(echo "$(convert "$file" -colorspace HSL -scale 1x1\! -format '%[pixel:s]' info:- | tr -d "hsl()%" | cut -d "," -f 1)*10000" | bc | cut -d "." -f 1)
#Verlinkung erzeugen
base=$(basename "$file")
name=$(printf "%06d" $h)
#Ein bisschen was zum Gucken, was so passiert:
echo -e "$name \t $file"
ln -s "$file" "./$folder/${name}_${base}"
done < files.txt
#Hilfdateien löschen
rm files.txt
|
Das Ergebnis in Darktable ist im Anhang zu sehen (die gleichen Bilder, wie im rgb-Beispiel oben), allerdings finde ich die Sortierung nicht so stichhaltig, wie zuvor (zum Beispiel grün und blau scheinen dem Eindruck nach doch noch recht durchmischt zu sein), zumindest sieht man sehr schön, dass die Graustufenbilder (H=0) zusammen liegen. Grüße Frink
- Bilder
|
Amrius
(Themenstarter)
Anmeldungsdatum: 9. Februar 2006
Beiträge: 94
|
Hm, das neue Skript geht auf jeden Fall viel schneller (ca. 1-2 Bilder pro Sekunde), aber die Sortierung passt bei mir leider noch nicht ganz. Ich habe einmal ein Testbild in verschiedenen Farbtönen erstellt- da kommen komischerweise immer gleiche Werte raus. Woran könnte das liegen?
Die Reihenfolge sollte eigentlich den ursprünglichen Dateinamen entsprechen (1,2,3...), da ich für die Erstellung der Bilder immer nur im HSV-Farbraum den H-Wert erhöht habe... Das kann man an deinem Beispiel auch gut erkennen: Rot wird gut vom Rest getrennt, aber grün und blau scheinen vermischt zu sein.
- Bilder
|
diesch
Anmeldungsdatum: 18. Februar 2009
Beiträge: 5072
Wohnort: Brandenburg an der Havel
|
Statt das Bild auf 1x1 Pixel zu verkleinern, wäre es warscheinlich sinnvoller, den Median oder den Durchschnitt der H-Werte aller Pixel zu nehmen. Das geht mit identify vermutlich aber nicht.
|
Prof._Frink
Anmeldungsdatum: 29. Mai 2010
Beiträge: 1096
|
Hey, ich habe auch noch ein bisschen rumprobiert mit einfarbigen Bildern und tatsächlich gibt die derzeitige Einstellung irgendwie nur Unsinn aus, die Lösung lautet HSB statt HSL, auch wenn ich nicht weiß warum, aber wenn ich den HSB-Raum wähle, dann bekomme ich immer nahezu den richtigen H-Wert, im Skript ist also die entsprechende Zeile durch: | h=$(echo "$(convert "$file" -colorspace HSB -scale 1x1\! -format '%[pixel:s]' info:- | tr -d "hsb()%" | cut -d "," -f 1)*10000" | bc | cut -d "." -f 1)
|
zu ersetzen. Im Anhang das Ergebnis mit meinem Standard-Set von Bildern; blau und grün sind offenbar gut getrennt, aber warum jetzt zum Beispiel die Merkel mit ihrem roten Anorak da an der Stelle (H:136°, was irgendeine Abstufung von Grün ist) ist, will mir nicht so recht in den Kopf, aber wie gesagt habe ich für alle einfarbigen Bilder, die ich getestet habe, den richtigen H-Wert bekommen, es könnte dann höchstens noch sein, dass bei der Interpolation auf einen Pixel irgendetwas schief läuft. Grüße Frink
- Bilder
|
Prof._Frink
Anmeldungsdatum: 29. Mai 2010
Beiträge: 1096
|
diesch schrieb: Statt das Bild auf 1x1 Pixel zu verkleinern, wäre es warscheinlich sinnvoller, den Median oder den Durchschnitt der H-Werte aller Pixel zu nehmen. Das geht mit identify vermutlich aber nicht.
Also, ich denke, dass das passiert, wenn man auf 1x1 verkleinert, zumindest ist diese Methode auf der Homepage speziell zur Berechnung der Durchschnittswerte angegeben. Vielleicht könnte man noch versuchen Einfluss auf den Algorithmus, bei der Verkleinerung zu nehmen. Grüße Frink
|
Amrius
(Themenstarter)
Anmeldungsdatum: 9. Februar 2006
Beiträge: 94
|
Hm, diese falsche Platzierung von rot ist seltsam. Ich habe das gerade mit meinen einfarbigen Testbildern ausprobiert, da wird das rote Bild auch zwischen den grünen platziert. Jetzt habe ich noch den HWB-Farbraum ausprobiert (kannte ich noch nicht)- da liegt rot zwischen den Blautönen... edit: Ich konnte das Problem lösen, indem ich die Skalierung weg gelassen habe und den HSB-Farbraum verwende. Damit werden jetzt alle Testbilder richtig einsortiert:
| h=$(echo "$(convert "$file" -colorspace HSB -format '%[pixel:s]' info:- | tr -d "hsb()%" | cut -d "," -f 1)*10000" | bc | cut -d "." -f 1)
|
Seltsam ist, dass nur bei einem bestimmten Bild (rot) völlig verschiedene H-Werte rauskommen, je nachem wie stark ich skaliere und ob ich HSV oder HSB verwende. Ist das ein Bug?
|
Prof._Frink
Anmeldungsdatum: 29. Mai 2010
Beiträge: 1096
|
Amrius schrieb: edit: Ich konnte das Problem lösen, indem ich die Skalierung weg gelassen habe und den HSB-Farbraum verwende. Damit werden jetzt alle Testbilder richtig einsortiert:
| h=$(echo "$(convert "$file" -colorspace HSB -format '%[pixel:s]' info:- | tr -d "hsb()%" | cut -d "," -f 1)*10000" | bc | cut -d "." -f 1)
|
Seltsam ist, dass nur bei einem bestimmten Bild (rot) völlig verschiedene H-Werte rauskommen, je nachem wie stark ich skaliere und ob ich HSV oder HSB verwende. Ist das ein Bug?
Ne, das ist kein Bug, wenn du die Skalierung weg lässt, bekommst du keinen Durchschnittswert, ich glaube, dann ist das der Wert des ersten Pixels oder so, also total willkürlich. Ich habe mal ein Bild von unten nach oben mit einer anderen Farbe schrittweise übermalt und mit dem Befehl | convert bild.jpg -colorspace HSB -format '%[pixel:s]' info:-
|
bekomme ich immer denselben Wert, erst als ich das letzte obere Stück übermalt habe, hat sich der Wert verändert. Das ist also nicht das, was wir wollen. Grüße
Frink
|
Prof._Frink
Anmeldungsdatum: 29. Mai 2010
Beiträge: 1096
|
Hey, also ich kann zu den HSB/HSL Werten von convert kein wirkliches Vertrauen fassen, denn es kommen zum Beispiel total verschiedene Werte heraus, je nachdem ob man erst nach HSB konvertiert und dann verkleinert oder umgekehrt: | convert rose: -scale 1x1\! -colorspace HSB -format '%[pixel:s]' info:-
|
vs.
| convert rose: -colorspace HSB -scale 1x1\! -format '%[pixel:s]' info:-
|
Deshalb habe ich jetzt noch mal nach den Formeln aus Wikipedia umgerechnet 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66 | #!/bin/bash
#Aufruf: bash skriptname "Pfad zum Ordner"
find "$1" -iname "*.jpg" > files.txt
#Ordner erzeugen
base=$(basename $1)
folder=$(echo "H-Wert-$base")
if [[ ! -d $folder ]];then
mkdir $folder
fi
while read file; do
#H-Wert lesen
rgb=$(convert "$file" -scale 1x1\! -format '%[fx:255*r],%[fx:255*g],%[fx:255*b]' info:-)
r=$(echo $rgb | cut -d "," -f 1)
g=$(echo $rgb | cut -d "," -f 2)
b=$(echo $rgb | cut -d "," -f 3)
h=$( bc <<EOF
scale=10
define max(r,g,b){
if(r>g && r>b){return r}
if(g>r && g>b){return g}
if(b>r && b>r){return b}
if(r=g && r=b){return 0}
}
define min(r,g,b){
if(r<g && r<b){return r}
if(g<r && g<b){return g}
if(b<r && b<r){return b}
if(r=g && r=b){return 0}
}
define h(r,g,b){
max=max(r,g,b)
min=min(r,g,b)
diff=max-min
if(diff==0){aux=0}
if( max==r){aux=60*(0+(g-b)/diff)}
if( max==g){aux=60*(2+(b-r)/diff)}
if( max==b){aux=60*(4+(r-g)/diff)}
if(aux<0){aux+=360}
aux*=10000
scale=0
return aux/1
}
h($r,$g,$b)
EOF
)
#Verlinkung erzeugen
base=$(basename "$file")
name=$(printf "%07d" $h)
#Ein bisschen was zum Gucken, was so passiert:
echo -e "$name \t $file"
ln -s "$file" "./$folder/${name}_${base}"
done < files.txt
#Hilfdateien löschen
rm files.txt
|
und das sieht eigentlich ziemlich gut aus (s. Anhang: Ich habe auch noch ein paar einfarbige Bilder hinzugefügt), auch wenn die Berechnung dadurch zunächst mal wieder etwas länger dauert. Grüße Frink
- Bilder
|