| Autor |
Beitrag |
Heiko
      
Beiträge: 3169
Erhaltene Danke: 11
|
Verfasst: Mi 27.06.07 09:10
Hallo,
wie kann ich ein I420-Bild (12Bit/Pixel) in ein RGB-Bild umwandeln? Direkt zu I420 finde ich da leider nichts  .
Grüße
Heiko
|
|
Horst_H
      
Beiträge: 1654
Erhaltene Danke: 244
WIN10,PuppyLinux
FreePascal,Lazarus
|
Verfasst: Mi 27.06.07 09:40
Hallo,
durch suchen
I420 = IYUV
im Beitrag
www.delphi-forum.de/...6&highlight=iyuv
dort von bbfan:
procedure YUV12toRGB(Src, Dst: Pointer; AWidth, AHeight: Integer); // I420, IYUV
var
..
Vielleicht funktioniert es sogar
Gruß Horst
|
|
Heiko 
      
Beiträge: 3169
Erhaltene Danke: 11
|
Verfasst: Mi 27.06.07 11:22
Hallo Horst,
den Quelli hatte ich schon gesehen, aber YUVtoBGRAPixel ist da nirgends definiert  . Ich habe zwar schon YUVtoRGB gefunden, aber bei dem gefundenen haben die auf Integer (um genau zu sein: y=0..1024 und die anderen beiden: -512..512) basiert.
Grüße
Heiko
|
|
Horst_H
      
Beiträge: 1654
Erhaltene Danke: 244
WIN10,PuppyLinux
FreePascal,Lazarus
|
Verfasst: Mi 27.06.07 12:04
Hallo,
wenn man international nach YUVtoBGRAPixel sucht kommt das
www.experts-exchange...49772.html#a16036693 original von delphi.pjh2.de/ Teil von CapDemoC.dpr
Hoffentlich ist es da was fehlt.
Gruß Horst
Einloggen, um Attachments anzusehen!
|
|
Phantom1
      
Beiträge: 390
|
Verfasst: Mi 27.06.07 13:12
hatte selbst sowas schonmal geschrieben:
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:
| type PARGB = ^TARGB; TARGB = packed record case Byte of 1: (B, G, R, A: Byte); 2: (Color: LongWord); end;
function YUVtoARGB(Y, U, V: Byte): TARGB; var ValueY, ValueU, ValueV, ValueR, ValueG, ValueB: Integer; begin ValueY:=Y-16; ValueU:=U-128; ValueV:=V-128;
ValueR:=(298*ValueY + 409*ValueV + 128) div 256; ValueG:=(298*ValueY - 100*ValueU - 208*ValueV + 128) div 256; ValueB:=(298*ValueY + 516*ValueU + 128) div 256;
with Result do begin if ValueR>255 then R:=255 else if ValueR<0 then R:=0 else R:=ValueR; if ValueG>255 then G:=255 else if ValueG<0 then G:=0 else G:=ValueG; if ValueB>255 then B:=255 else if ValueB<0 then B:=0 else B:=ValueB; A:=0; end; end;
procedure I420toARGB(Src: PByte; Dest: PARGB; Width, Height: Integer); var x, y, n: Integer; pY, pU, pV: PByte; begin pY:=src; pU:=PByte(Integer(Src)+Width*Height); pV:=PByte(Integer(pU)+Width*Height div 4); for y:=1 to Height div 2 do for n:=1 to 2 do begin for x:=1 to Width div 2 do begin Dest^:=YUVtoARGB(pY^, pU^, pV^); Inc(Dest); Inc(pY); Dest^:=YUVtoARGB(pY^, pU^, pV^); Inc(Dest); Inc(pY); Inc(pU); Inc(pV); end; if n=1 then begin Dec(pU, Width div 2); Dec(pV, Width div 2); end; end; end; |
|
|
Heiko 
      
Beiträge: 3169
Erhaltene Danke: 11
|
Verfasst: Do 28.06.07 08:17
Hallo Danke,
funktioniert soweit - außer das das Bild verkehrt herum ist  . Der BMP-HEader hat ja eigentlich ein Byte, in dem definiert ist, wie rum es gespeichert wurde (von oben nach unten oder umgekehrt). Kommt man da bei Delphi ran um das zu ändern? Denn mir fällt gerade keien Variante ein es mit den Zeigern gleich zu machen, denn dann würde es zwar horizonatl stimmen, aber nicht mehr vertikal. Und Pixelweises austauschen will ich aus Performancegründen nicht (der Algo vrbraucht jetzte schon den vollen CPu und schafft dabei nicht einmal die WebCam auszulasten  )
//EDIT:  Zeiger umdrehen reicht doch. Das BIld ist ja nicht nur hor. gespiegelt, sondern auch vert. da gehts doch  .
//EDIT2: Ok, vertikal ist es doch noch verkert herum. Einer ne Idee das zu beheben?
|
|
Phantom1
      
Beiträge: 390
|
Verfasst: Do 28.06.07 09:47
@Heiko: achso stimmt ja, mein Code ist für die Graphics32 Library. Versuche es doch mal damit, denn das TImage32 und TBitmap32 ist um einiges schneller als das normale TImage/TBitmap. Zudem wird das Bild dann auch richtig herum angezeigt.
Download: www.graphics32.org/wiki/
|
|
Heiko 
      
Beiträge: 3169
Erhaltene Danke: 11
|
Verfasst: Do 28.06.07 10:57
Das würde das Problem nur verlagern, denn die Cam liefert die BMP-Daten anders herum. Also wenn ich jetzte die Kompo für I420 nehmen würde, würde BMP verkehrtherum sein  . BMP wäre zwar leichter zu korrigieren, aber bei I420 dürfte es auch gehen. Nur ist das eine unbedeutende Kleinigkeit, wes wegen ich es vlt. verkehrtherum lasse  . (Es geht um die Positionsbestimmung eines Roboters per WebCam).
|
|
Horst_H
      
Beiträge: 1654
Erhaltene Danke: 244
WIN10,PuppyLinux
FreePascal,Lazarus
|
Verfasst: Do 28.06.07 12:10
Hallo,
falls YUVtoARGB die Bremse ist, gibt es auch MMX Versionen die schneller sind:
www.cs.berkeley.edu/...stBeta/intelMMX.html mit Vergleichszahlen:
lestourtereaux.free....pers/data/yuvrgb.pdf
Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9:
| Vergleich für P4 GCC-Compiler Floating-Point Code 39.5 Integer Multiplication 30.0 No Multiplications 12.6 No Conditionals 8.6 Four Pixels 7.2 Assembly Code 4.4 Non-Temporal Stores 3.5 Two Pixels 2.8 |
Da ist also etwas drin.
Gruß Horst
|
|
Heiko 
      
Beiträge: 3169
Erhaltene Danke: 11
|
Verfasst: Do 28.06.07 12:15
Ne, das abgreifen geht von der Verarbeitung (bei nem P4 0-1% CPU-Last). Das Problem ist die Auswertung dahinter. Die verschlingt soviel (viele Vergleiche eben...).
Und der Performanceeinbruch auf einem 400MHz-Rechner ist unwesentlich: 26FPS bei 24Bit-BMP (keine Convertierung erforderlich) und 25.4FPS bei I420.
|
|