32 bit binärdaten spezifisch als rgb+x auswerten
-
Ich habe eine Kamera die 10 und 8 Bit Werte in einem linearen Speicher zurück liefert. Diese Matrix hat pro Pixel 32 Bit. Diese sind nun organisiert als
8 Bit: r(8) g(8) b(8) + x(8)
10 Bit: r(10) g(10) b(10) + x(2)wobei x Müll oder Null enthält.
Wie kann ich diese Pixel die ich z.B. als Integer lesen könnte so interpretieren,
dass ich die Werte von r,g,b einzeln wieder abspeichern kann?
-
Bin mir nicht sicher was Du meinst aber ich denke mal du möchtest die bestimmten bits auslesen.
Du kommst z.B. an die r-werte in dem du eine Bitmask benutzt um sie auszulesen.
Also:int rWert = 0xff000000 & RGBintegerWert; int rWert = rWert >> 24;Wenn Du die jetzt noch um 24 stellen nach rechts shiftest (2.code zeile) dann hast Du die werte...
Bei den 10 bit werten sähe die Maske dann so aus 0xff600000 und der shift nur um 22 stellen.gruß muli
-
Ok, sowas in der Art habe ich gesucht. Nur zum Verständnis: Bei Grün shifte ich dann um 16 und bei Blau um 8?
-
ja und deine bitmask sieht anders aus:
Willst du die Bits 24 - 16 auslesen dann: 0x00ff0000
für die Bits 22-12 : 0x00ff6000Die shifts musst du dann anpassen aber nach dem was Du schreibst ist dieser Teil schon so gut wie verstanden

-
muli schrieb:
ja und deine bitmask sieht anders aus:
Willst du die Bits 24 - 16 auslesen dann: 0x00ff0000
für die Bits 22-12 : 0x00ff6000Ich bin verwirrt. 10 bit sind 1024 Werte, in Hex wäre das 400, ff6 dagegen wäre 4096 = 12 bit.
Müsste dann die Maske nicht eher so aussehen:
32-22: 0x40000000
22-12: 0x00400000
12-10: 0x00001000Nicht das ich mit Hexzahlen gut umgehen könnte...
-
Also die Zahl die dadurch beschrieben wird ist nun erstmal irrelevant.
Du hast bsw.: eine 32-bit wert mit deinen rgb werten der so aussieht:
11110000111100001111000011110000 diese Zahl als hex ist die folgende 0xf0f0f0f0.
So du willst jetzt die ersten 10 bits haben also machst du ein bitweises UND :
11110000111100001111000011110000 // deine rgbx Werte
&
11111111110000000000000000000000 // und deine Maske 0xff600000
------------------------------------------
das Ergebnis ist eine Zahl die dort eine 1 hat wo beide eine 1 haben und 0 sonnst.also bekommst du :
11110000110000000000000000000000 das sind deine ersten 10 Bits.Dann der shift und du hast 1111000011 als dein Ergebnis.
Die bei der Maske ist es wichtig die Einsen an der richtigen Stelle zu haben.
und ff6 sind 10 einsen in Folge...
-
malen wirs doch mal auf:
so sieht das in 10 bit aus (hab mal big und litte endian ignoriert)
rrrr rrrr rrgg gggg gggg bbbb bbbb bbxx
r: 1111 1111 1100 0000 0000 0000 0000 0000 hex: ffc00000
g: 0000 0000 0011 1111 1111 0000 0000 0000 hex: 003ff000
b: 0000 0000 0000 0000 0000 1111 1111 1100 hex: 00000ffcJetzt sollen aus den 10-bit werten 8 bit werte werden, wo man erstmal definieren muß welche beiden bits wegfallen sollen (most oder least significant). Ich würde auf letzte tippen, also sähe das so aus:
(zwischenwerte)
r1 = wert & 0xff000000
g1 = wert & 0x003fc000
b1 = wert & 0x00000ff0Jetzt sollen die ja in r8g8b8x8 umgewandelt werden:
rrrr rrrr gggg gggg bbbb bbbb xxxx xxxx
also schieben wir:ergebnis = r1 | (g1 << 2) | (b1 << 4);
Natürlich müste man jetzt noch big- und littel endian berücksichtigen...
-
muli schrieb:
ff6 sind 10 einsen in Folge...
Fast.
f: 1111
6: 0110 (2 + 4)ff6 = 1111 1111 0110
-
#include <cassert> template<int bits> struct rgb { unsigned int r : bits; unsigned int g : bits; unsigned int b : bits; }; int main() { rgb<8> grau8bit; grau8bit.r = 127; grau8bit.g = 127; grau8bit.b = 127; assert(sizeof(grau8bit)== sizeof(int)); rgb<10> grau10bit; grau10bit.r = 511; grau10bit.g = 511; grau10bit.b = 511; assert(sizeof(grau10bit)== sizeof(int)); return 0; }}Gruß
Drehleiter
-
Ok dann versuch ich es mal mit 'ffc' statt dessen

-
Drehleiter schrieb:
template<int bits> struct rgb { unsigned int r : bits; unsigned int g : bits; unsigned int b : bits; };Wie ist den diese Syntax zu verstehen? Gibt das Speicher mit exakt 'bits' Speicherbreite?
-
Google mal nach C++ und bitset
Die Lösung von Drehleiter dürfte auf den meisten Rechnern funktionieren. Aber ich finde es besser, das alignment explizit zu machen.
template<int bits, int offset> struct rgb { unsigned int r : bits; unsigned int g : bits; unsigned int b : bits; unsigned int x : offset; }; int main() { rgb<8, 8> grau8bit; // rgbxrgbx grau8bit.r = 127; grau8bit.g = 127; grau8bit.b = 127; assert(sizeof(grau8bit)== sizeof(int)); rgb<10, 2> grau10bit; grau10bit.r = 511; grau10bit.g = 511; grau10bit.b = 511; assert(sizeof(grau10bit)== sizeof(int)); return 0; }}Aber Achtung: M.W. sind bitsets nicht sehr genau im Standard definiert, sprich: Vieles ist implementierungsabhänging. Das betrifft IIRC insbesondere das Alignment der einzelnen Elemente.
-
pospiech schrieb:
Wie ist den diese Syntax zu verstehen? Gibt das Speicher mit exakt 'bits' Speicherbreite?
Ja, das sind "bitfields". Aber das Layout ist nicht standardisiert und daher kannst du das so nicht portabel benutzen. Geh auf Nummer sicher: shift/and