Schreiben Sie ein Programm, das ein Standard- Echtfarbenbild und eine einzelne 24-Bit- RGB- Farbe (drei Zahlen von 0 bis 255) aufnimmt . Ändern Sie das Eingabebild (oder geben Sie ein neues Bild mit denselben Abmessungen aus), sodass die durchschnittliche Farbe genau der einzelnen eingegebenen Farbe entspricht. Sie können die Pixel im Eingabebild beliebig ändern, um dies zu erreichen. Ziel ist es jedoch, die Farbänderungen so wenig wie möglich sichtbar zu machen .
Die durchschnittliche Farbe eines RGB-Bildes setzt sich aus drei arithmetischen Mitteln zusammen , eines für jeden Farbkanal. Der durchschnittliche Rotwert ist die Summe der Rotwerte aller Pixel im Bild geteilt durch die Gesamtzahl der Pixel (Bildbereich), abgerundet auf die nächste Ganzzahl. Der grüne und der blaue Durchschnitt werden auf die gleiche Weise berechnet.
Dieses Python 2- Skript (mit PIL ) kann die durchschnittliche Farbe der meisten Bilddateiformate berechnen:
from PIL import Image
print 'Enter image file'
im = Image.open(raw_input()).convert('RGB')
pixels = im.load()
avg = [0, 0, 0]
for x in range(im.size[0]):
for y in range(im.size[1]):
for i in range(3):
avg[i] += pixels[x, y][i]
print 'The average color is', tuple(c // (im.size[0] * im.size[1]) for c in avg)
(Es gibt ähnliche durchschnittliche Farbprogramme hier , aber sie müssen nicht genau die gleiche Berechnung tun.)
Die Hauptanforderung für Ihr Programm besteht darin, dass für jedes Eingabebild die durchschnittliche Farbe der entsprechenden Ausgabe genau mit der eingegebenen Farbe übereinstimmen muss. Dies wird anhand des Python-Snippets oder eines entsprechenden Codes beurteilt. Das Ausgabebild muss genau die gleichen Abmessungen wie das Eingabebild haben.
Sie könnten also technisch ein Programm einreichen, das einfach die gesamte Eingabe mit der angegebenen Durchschnittsfarbe einfärbt (weil der Durchschnitt immer diese Farbe sein würde), aber dies ist ein Beliebtheitswettbewerb - die Einreichung mit der höchsten Stimmenzahl gewinnt und eine solche Kleinigkeit Einreichung wird Ihnen nicht viele positive Stimmen einbringen. Neuartige Ideen wie das Ausnutzen von Macken in der menschlichen Sicht oder das Verkleinern des Bildes und das Zeichnen eines farbigen Rahmens werden (hoffentlich) zu Abstimmungen führen.
Beachten Sie, dass bestimmte Kombinationen von Durchschnittsfarben und Bildern äußerst auffällige Farbänderungen erfordern. Wenn zum Beispiel die zu vergleichende Durchschnittsfarbe schwarz (0, 0, 0) wäre, müsste jedes Eingabebild vollständig schwarz gemacht werden, denn wenn Pixel Werte ungleich Null hätten, würden sie auch den Durchschnittswert ungleich Null machen ( Rundungsfehler vorbehalten). Beachten Sie diese Einschränkungen bei der Abstimmung.
Bilder testen
Einige Bilder und ihre durchschnittlichen Standardfarben zum Herumspielen. Klicken Sie für volle Größen.
A. Durchschnitt (127, 127, 127)
Von fejesjoco ‚s Bilder mit allen Farben beantworten . Gefunden Original auf seinem Blog .
B. durchschnittlich (62, 71, 73)
Yokohama . Bereitgestellt von Geobits .
C. Durchschnitt (115, 112, 111)
Tokio . Bereitgestellt von Geobits .
D. Durchschnitt (154, 151, 154)
Eschers Wasserfall . Original .
E. Durchschnitt (105, 103, 102)
Mount Shasta . Von mir bereitgestellt.
F. Durchschnitt (75, 91, 110)
Anmerkungen
- Die genauen Eingabe- und Ausgabeformate und Bilddateitypen, die Ihr Programm verwendet, spielen keine große Rolle. Stellen Sie einfach sicher, dass klar ist, wie Sie Ihr Programm verwenden.
- Es ist wahrscheinlich eine gute Idee (aber technisch keine Voraussetzung), dass ein Bild, wenn es bereits die durchschnittliche Zielfarbe hat, so ausgegeben wird, wie es ist.
- Stellen Sie Testbilder mit einem durchschnittlichen Farbeintrag als (150, 100, 100) oder (75, 91, 110) bereit, damit die Wähler dieselben Eingaben für verschiedene Lösungen sehen können. (Das Posten von mehr Beispielen ist in Ordnung, sogar erwünscht.)
quelle
Antworten:
Python 2 + PIL, einfache Farbskalierung
Hier ist ein naiver Ansatz, der als gute Basis dienen sollte. Bei jeder Iteration vergleichen wir unseren aktuellen Durchschnitt mit dem gewünschten Durchschnitt und skalieren den RGB-Wert jedes Pixels anhand des entsprechenden Verhältnisses. Wir müssen jedoch aus zwei Gründen vorsichtig sein:
Das Skalieren von 0 führt immer noch zu 0, also fügen wir vor dem Skalieren etwas Kleines hinzu (hier
0.01
)RGB-Werte liegen zwischen 0 und 255, daher müssen wir das Verhältnis entsprechend anpassen, um die Tatsache auszugleichen, dass das Skalieren von Pixeln mit Begrenzung nichts bewirkt.
Die Bilder werden als PNG gespeichert, da das Speichern als JPG die Farbdurchschnitte durcheinander zu bringen scheint.
Beispielausgabe
(40, 40, 40)
(150, 100, 100)
(75, 91, 110), Starry Night-Palette
quelle
C ++, Gammakorrektur
Dies führt eine Helligkeitsanpassung des Bildes mit einer einfachen Gammakorrektur durch, wobei der Gammawert für jede Komponente separat bestimmt wird, um dem Zielmittelwert zu entsprechen.
Die übergeordneten Schritte sind:
Alle Bildeingaben / -ausgaben verwenden PPM-Dateien in ASCII. Bilder wurden mit GIMP von / nach PNG konvertiert. Der Code wurde auf einem Mac ausgeführt, Bildkonvertierungen wurden unter Windows durchgeführt.
Code:
Der Code selbst ist ziemlich einfach. Ein subtiles, aber wichtiges Detail ist, dass ich die Farbwerte, obwohl sie im Bereich [0, 255] liegen, der Gammakurve so zuordne, als ob der Bereich [-1, 256] wäre. Dadurch kann der Durchschnitt auf 0 oder 255 gesetzt werden. Andernfalls würde 0 immer 0 bleiben und 255 würde immer 255 bleiben, was möglicherweise niemals einen Durchschnitt von 0/255 zulässt.
Benutzen:
.cpp
, zforce.cpp
.c++ -o force -O2 force.cpp
../force input.ppm targetR targetG target >output.ppm
.Beispielausgabe für 40, 40, 40
Beachten Sie, dass die Bilder für alle größeren Samples als JPEGs enthalten sind, da sie als PNGs die SE-Größenbeschränkung überschreiten. Da JPEG ein verlustbehaftetes Komprimierungsformat ist, entsprechen sie möglicherweise nicht genau dem Zieldurchschnitt. Ich habe die PNG-Version aller Dateien, die genau übereinstimmt.
Beispielausgabe für 150, 100, 100:
Beispielausgabe für 75, 91, 110:
quelle
Python 2 + PIL
Dies durchläuft jedes Pixel in einer zufälligen Reihenfolge und verringert den Abstand zwischen jeder Komponente der Farbe des Pixels und /
255
oder0
(abhängig davon, ob der aktuelle Durchschnitt kleiner oder größer als der gewünschte Durchschnitt ist). Der Abstand wird um einen festen Multiplikationsfaktor verringert. Dies wird wiederholt, bis der gewünschte Durchschnitt erreicht ist. Die Reduzierung erfolgt immer mindestens1
, es sei denn, die Farbe ist255
(oder0
), um sicherzustellen, dass die Verarbeitung nicht unterbrochen wird, sobald sich das Pixel in der Nähe von Weiß oder Schwarz befindet.Beispielausgabe
(40, 40, 40)
(150, 100, 100)
(75, 91, 110)
quelle
Java
Ein RNG-basierter Ansatz. Ein bisschen langsam für große Eingabebilder.
Tests:
(40,40,40)
(150, 100, 100)
(75,91,110)
quelle