2017-10-24 4 views

Antwort

2

In ImageMagick, -skala 1x1! ignoriert die transparenten Pixel und gibt den Durchschnitt der undurchsichtigen Pixel an. Wenn Sie also den Durchschnitt der maskierten Region möchten, können Sie die Maske in den Alphakanal einfügen und dann -scale 1x1 verwenden! um es auf ein Pixel zu mitteln. Die Maske sollte weiß sein, wo Sie den Durchschnitt und Schwarz erhalten möchten, wo es transparent sein sollte, und diese Pixel im Durchschnitt ignorieren. Das sollte es also tun.

convert image.png mask.png -alpha off -compose copy_opacity -composite -scale 1x1! -alpha off -format "%[pixel:u.p{0,0}]" info: 


Zum Beispiel, wenn ich machen das Logo: Bild transparent, wo es weiß ist, und dann den Durchschnitt, ich

convert logo: -transparent white -scale 1x1! -alpha off -format "%[pixel:u.p{0,0}]" info: 
srgb(100,81,99) 


Sie zeigen können, bekommen, dass dies funktioniert, indem man es tut der lange Weg. Multiplizieren Sie die Maske mit dem Bild und ermitteln Sie den Durchschnittswert für jeden Kanal des Produkts. Dann erhalte den Durchschnitt der Maske. Dann die Verhältnisse auf den Bereich von 0 bis 255.

convert logo: -transparent white logot.png 
convert logot.png -alpha extract mask.png 

declare `convert \(logot.png -alpha off \) mask.png -compose multiply -composite -format "IR=%[fx:mean.r]\nIG=%[fx:mean.g]\nIB=%[fx:mean.b]\n" info:` 
echo "IR=$IR; IG=$IG; IB=$IB" 
IR=0.0651798; IG=0.0529989; IB=0.0641607 

MM=`convert mask.png -format "%[fx:mean]\n" info:` 
echo "MM=$MM" 
MM=0.165872 

convert xc: -format "srgb(%[fx:round(255*$IR/$MM)],%[fx:round(255*$IG/$MM)],%[fx:round(255*$IB/$MM)])\n" info: 
srgb(100,81,99) 


Ergebnis skaliert berechnen ist das gleiche wie oben.Beachten Sie, dass

convert \(logot.png -alpha off \) mask.png -compose multiply -composite ... 

in diesem Fall ist das gleiche wie nur

convert logot.png -alpha remove ... 

Aber ich zeige ihm den langen Weg, wenn der Benutzer eine separate Maske hat und Bild ohne Transparenz:

ASIDE .

+0

danke, das hat funktioniert! –

0

Vielleicht ...

convert demo.png -mask demo_mask.png -trim -fx mean -extent 1x1 txt:- |\ 
     tail -1 | cut -d ' ' -f 4 

Dies würde funktionieren, weil -trim wird das maskierte Bild nach unten in den MBR des ROI reduzieren . Der FX-Operator -fx mean konvertiert alle Pixel in den Gesamtdurchschnitt. Und schließlich wird die -extent 1x1 das erste Pixel im Bild isolieren. Der Rest ist grundlegende Unix-Utilities.


Eine weitere Option mit einer besseren Leistung ...

MEAN=$(convert demo.png -mask demo_mask.png -trim -format '%[fx:mean]' info:-) 
convert null: -depth 8 -format "%[pixel:$MEAN]" info:- 

Oder vom Quantization documentation ...

convert demo.png -mask demo_mask.png -trim -scale 1x1\! '%[pixel:s]' info:- 
+0

danke für die Antwort, aber der Vorschlag dauert zu lange, um zu rechnen (wartete etwa 15 Sekunden vor ctr + c). Und für die anderen, die sich fragen, was MBR und ROI bedeuten. MBR = minimales begrenzendes Rechteck, ROI = Region von Interesse –

+0

jetzt funktioniert die zweite Lösung, aber ich muss die Ergebnisse testen –

+0

gibt mir immer "srgba (151,151,151,1)" was nicht korrekt ist –

1

Sie sollten sehr nahe bekommen können, was Sie wollen mit einem Befehl so etwas ...

convert image.png mask.png -compose copyopacity -composite -resize 1x1! txt:- 

nur die Farbinformation Sie so etwas wie dies zu Ausgabe versuchen ...

convert image.png mask.png \ 
    -compose copyopacity -composite -resize 1x1! -format "%[pixel:p]" info: 

Ich habe nicht versucht, aber Sie können „-negate“ Ihr Maskenbild muss je nachdem, welche Version von IM, das Sie verwenden, da sich die Handhabung des Alphakanals geändert hat.

Sie erhalten ein etwas anderes Ergebnis, wenn Sie vor der "-größe" "-trim".

Wenn Sie die Alpha-Kanalinformationen nicht ausgeben möchten, können Sie "-alpha off" nach "-resize" hinzufügen.

+0

Ich muss den Scheck an fmw42 geben weil "-scale 1x1! die transparenten Pixel ignoriert". sry, auch wenn deine Antwort auch absolut korrekt war –

Verwandte Themen