www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik 24Bit RGB zu 16Bit wandeln


Autor: Thorsten (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Leute,

ich möchte eine 24Bit RGB Wert in 16bit für ein TFT wandeln. Natürlich 
funktioniert das schon mit der einfachen Variante die unteren Bits 
einfach zu streichen, dies entspricht meiner Meinung nach nicht der 
ganzen Warheit.

Als Beispiel

R G B Wert =   11111111 00000011 00000111

dies wäre ja umgewandelt einfach nur rot. Wenn ich nun eine 24Bit Bitmap 
(Foto) so ausgebe, sieht man das natürlich schon an gewissen stellen im 
Bild.

Hat jemand von euch eine bessere Idee die Umwandlung besser 
durchzuführen?

Gruß

Th.

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
aufrunden

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mal angenommen die Darstellung ist 5:6:5 für RGB und du willst den 
Grünwert; den könntest runden, zB:
G6 = G8 + 2            // aufrunden: + 2**1
if (G6 > 255) G6 = 255 // evtl. Überlauf abschneiden
G6 = G6 >> 2           // grün hat 6 bits (8-2)

irgendwo gibt's aber immer Informationsverlust, der vor allem bei 
blassen Farben und an der Grauachse auffallen wird.

Autor: Flo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Werte skalieren, sprich die Werte schieben und eventuell bei 
Übertrag auf Maximalwert setzen?

Autor: Thomas R. (tinman) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Thorsten schrieb:
> Natürlich
> funktioniert das schon mit der einfachen Variante die unteren Bits
> einfach zu streichen, dies entspricht meiner Meinung nach nicht der
> ganzen Warheit.

> Als Beispiel
> R G B Wert =   11111111 00000011 00000111
> dies wäre ja umgewandelt einfach nur rot

nah, nicht den ganzen 24bit RGB nehmen und "beschneiden" sondern die 
jeweiligen farbwerte von 8 auf 5 bzw 6 bit aufrunden.

Autor: Jobst M. (jobstens-de)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Thorsten schrieb:

> dies wäre ja umgewandelt einfach nur rot. Wenn ich nun eine 24Bit Bitmap
> (Foto) so ausgebe, sieht man das natürlich schon an gewissen stellen im
> Bild.

Stimmt. Da wirst Du auch mit keiner Technik der Welt gegen ankommen. Die 
Anzahl der Farben ist nun mal begrenzt. Und wenn Du einen Gradienten im 
Bild hast, dann sind Stufen dort drin.
Du könntest es dithern ...


Falk Brunner schrieb:
> aufrunden

Geht nicht.

Aus 11111111 würde dann z.B. 00000 werden (führende 1 abgeschnitten).
Eine Skalierung fällt auch aus, da dann die Farben verfälscht werden.
Ohne Rundung ist das Bild dann im Schnitt eben einfach ein halbes LSB 
dunkler. Auch volle Helligkeit ist fast ein ganzes LSB 'dunkler'
Den Unterschied zwischen

11111000 11111100 11111000
und
11111111 11111111 11111111

wirst Du einfach nicht darstellen können ...
(hier müsstest Du ja dann auch abrunden ...)

Ich denke, einfach die Bits abzuschneiden ist schon die richtige Lösung.
Gewisse Farben kann das Display einfach nicht darstellen, damit wirst Du 
leben müssen.


Gruß

Jobst

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jobst M. schrieb:

>> aufrunden
>
> Geht nicht.
>
> Aus 11111111 würde dann z.B. 00000 werden

Klar geht das, aber natürlich muss saturierend gerechnet werden.

Autor: Thorsten (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

das es nicht ohne Verluste geht ist klar. Wie aber machen es denn die 
"Profis"? Wenn ich beispielsweise dieses Foto nehm:

http://www.architekten24.de/mediadb/news/2012/dockland_2.jpg

und wandel es mit Gimp in eine 16Bit RGB Bitmap um, sieht es am PC noch 
super aus.

Wie würde das denn mit dem Runden aussehen? Momentan sieht meine 
Funktion so aus:

uint16 convert_to_16bit(uint8 red, uint8 green, uint8 blue)
{
return ((red>>3)<<11)+((green>>2)<<5)+(blue>>3);
}

Gruß

Th.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Thorsten schrieb:

> das es nicht ohne Verluste geht ist klar. Wie aber machen es denn die
> "Profis"?

Vermutlich mit dithering.

Autor: Andreas K. (derandi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Thorsten schrieb:
> R G B Wert =   11111111 00000011 00000111
>
> dies wäre ja umgewandelt einfach nur rot. Wenn ich nun eine 24Bit Bitmap
> (Foto) so ausgebe, sieht man das natürlich schon an gewissen stellen im
> Bild.

(Auf)Runden.
Rot und Blau bekommen 5, Grün 6 Bit.
Mein Vorschlag: Das 3. Bit des alten 8-Bit-wertes wird das LSB des neuen 
Wertes.
Alt         Neu
0000 0100 = 00001
0000 0011 = 00000
0000 0111 = 00001
Denn: Die letzten 3 Bits des 8-Bit-Farbwertes können 7 Werte darstellen, 
will man das auf 5 Bit eindampfen kann man nur noch auf einen Wert 
diskriminieren.
Das 3-letzte Bit ist mehr wert als die verbleiben zwei zusammen, die 
muss man also garnicht erst ansehen um zu wissen ob auf oder abgerundet 
wird.
Analog das ganze beim Grünwert, nur ein Bit verschoben.
Einfach das spezielle Bit als neues LSB des eingedampfen Farbwertes 
übernehmen, so kriegt man das ohne viel Rechenzeit umgerechnet.

Autor: Jobst M. (jobstens-de)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Na, ihr Runder ;-)

Dann macht das doch mal mit diesen Werten:

z.B. Rot
11110100
11110111
11111000
11111111


Gruß

Jobst

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jobst M. schrieb:

> Dann macht das doch mal mit diesen Werten:

Dass man beim Bitwegkürzen Information verliert kommt dir sicherlich 
völlig unerwartet.

Autor: Falk Brunner (falk)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Siehe Anhang, einmal mit runden und enínmal mit Dither. Damit man die 
feinen Unterschiede bei 16 Bit sieht muss man reinzoomen.

Mf
Falk

Autor: Thorsten (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

@Falk

mit dem 16bit rounding ist ja klasse. Wie hast du das gemacht?

Gruß und vielen Dank für eure Antworten!

Th.

Autor: Jobst M. (jobstens-de)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
A. K. schrieb:
> Jobst M. schrieb:
>
>> Dann macht das doch mal mit diesen Werten:
>
> Dass man beim Bitwegkürzen Information verliert kommt dir sicherlich
> völlig unerwartet.

Nein, das genaue Gegenteil versuche ich die ganze Zeit klar zu machen.

Mal eine anderer Ansatz: Stellt Euch vor, das Ganze müsste auf 1 Bit pro 
Farbe gekürzt werden. Wie würdet Ihr runden? Oder doch einfach nur alle 
Werte ab 128 auf 1 setzen und darunter auf 0?


Falk: Wo kommen die Punkte in 'dockland_16_bit_rounding.png' her?


Gruß

Jobst

Autor: Jobst M. (jobstens-de)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nochwas: Für Text ist Dithering evtl. nicht so geeignet ...


Gruß

Jobst

Autor: Jobst M. (jobstens-de)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jobst M. schrieb:
> Falk: Wo kommen die Punkte in 'dockland_16_bit_rounding.png' her?

Vermutlich jpg artefakte ... :-/

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jobst M. schrieb:

> Nein, das genaue Gegenteil versuche ich die ganze Zeit klar zu machen.

Der Treppeneffekt ist völlig unabhängig davon ob man rundet oder 
abschneidet. Die Nähe zum Original ist es jedoch nicht. Bei Rundung 
beträgt der Fehler maximal 0,5 LSB, beim Abschneiden 1 LSB.

Ist die Nähe zum Original nicht massgeblich, beispielsweise weil das 
Ausgabemedium sowieso nicht farbkalibriert ist, dann hat Rundung nur 
noch den Vorteil, Artefakte an den Grenzwerten automatisch zu vermeiden. 
Das geht aber auch einfacher.

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  Thorsten (Gast)

>mit dem 16bit rounding ist ja klasse. Wie hast du das gemacht?

Bild mit PaintShop 7 geladen, Farben reduzieren, 16Bit, runden.

MFG
Falk

Autor: Jobst M. (jobstens-de)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
A. K. schrieb:
> Jobst M. schrieb:
>
>> Nein, das genaue Gegenteil versuche ich die ganze Zeit klar zu machen.
>
> Der Treppeneffekt ist völlig unabhängig davon ob man rundet oder
> abschneidet. Die Nähe zum Original ist es jedoch nicht. Bei Rundung
> beträgt der Fehler maximal 0,5 LSB, beim Abschneiden 1 LSB.

Korrekt - ist also ein Helligkeitsunterschied von 0,5 LSB
Problem der Rundung ist aber, daß die hellste Stufe 1,5LSB überstreicht.

Farbbluten wird man sowieso nicht vermeiden können.


Gruß

Jobst

Autor: Thorsten (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

so ich hab nunmal alles ausprobiert. Leider ist das irgendwie nicht 
zufriedenstellend. Dann werd ich wohl damit leben müssen :-(

Trotzdem Danke an alle!

Gruß

Th.

Autor: Thorsten (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Falk

leider macht das Paint Shop "nicht richtig". Es werden zwar die Farben 
auf 64k reduziert, trotzdem ist es ja noch eine 24Bit Bitmap.

Gruß

Th.

Autor: Steffen H. (avrsteffen)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hier mal ein Converter der 24bit bmp in 16bit für AVR macht.

Grüße Steffen

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.