Réduction d'images

Réduction d'images - Algo - Programmation

Marsh Posté le 10-06-2004 à 01:30:38    

Quel est l'algo le plus simple à implémenter pour réduire des images d'une résolution à une autre quelconque mais inférieure ?

Reply

Marsh Posté le 10-06-2004 à 01:30:38   

Reply

Marsh Posté le 10-06-2004 à 01:34:53    

tu prend un pixel sur nouvelle taille/ancienne taille (enfin, on fait pas comme ça exactement sinon ça tombe pas juste, mais c'est l'idée).
 
C'est le plus simple et le moins beau.


---------------
trainoo.com, c'est fini
Reply

Marsh Posté le 10-06-2004 à 01:53:13    

oui mais justement quand on a pasdes diviseurs "ronds" ca marche pas ... Je me souviens qu'en analyse harmonique on faisait destrucs de ce style avec du bilinéaire, mais y'a pas un algo plus simple (et qui m'obligerait pas à me replonger dans mes polys ;-) )

Reply

Marsh Posté le 10-06-2004 à 02:09:11    

bon, j'y vais alors :
 
en 1D, (c'est linéairement séparable) :

Code :
  1. for (int i = 0; i < nouvelleLongueur; i++) {
  2.   int iSurLAncienneImage = i * ancienneLongueur / nouvelleLongeur;
  3.   nouvelleImage[i] = ancienneImage[iSurLAncienneImage];
  4. }


 
pour des très très grandes images (anciennetaille*nouvelletaille > 2^32 ou 31), il faudra changer de stratégie car la multiplication va dépasser.
 
 
edit : la magie du truc vient de la division entière et de la multiplication faite *avant* la division.


Message édité par nraynaud le 10-06-2004 à 02:10:21

---------------
trainoo.com, c'est fini
Reply

Marsh Posté le 10-06-2004 à 03:25:57    

sinon, tu peux aussi faire avec un accu, histoire d'avoir un rendu pas trop crade (le point sampling, c'est assez moyen, même si c'est rapide ... tout dépend de ce que tu veux)
 
en gros, pour chaque point de ton image de départ, tu fais la transformation du point dans le repère de ton image destination, tu regardes entre quels pixels il tombe (généralement : 4 pixels) et tu additionne les valeurs de couleur pondérées par la distance à chaque pixel ...
 
(évidemment, ca ne marche effectivement qu'avec une réduction d'image, mais ca a le mérite d'être facilement adaptable si tu fais une rotation de l'image autour de Z)

Reply

Marsh Posté le 10-06-2004 à 09:26:29    

merci

Reply

Marsh Posté le 10-06-2004 à 09:39:27    

Sinon tu peux utiliser une lib qui fait déjà ça très bien.


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
Reply

Marsh Posté le 10-06-2004 à 16:15:54    

Merci à tous.
 
Pour vous "remercier", je vous met à disposition la classe Delphi que j'ai codé à prtir de vos indications :  
 

Code :
  1. unit U_BitmapResize;
  2. interface
  3. uses classes,graphics;
  4. type
  5.   DWORD = LongWord;
  6.   PIXEL_RGB = packed record
  7.     Red:Byte;
  8.     Green:Byte;
  9.     Blue:Byte;
  10.   end;
  11.   TBITMAPHEADER = packed record
  12.     ID:Array[0..1] of char;
  13.     dwTotalSize:DWORD;
  14.     dwReserved:DWORD;
  15.     dwOffset:DWORD;
  16.     dwHeaderSize:DWORD;
  17.     dwWidth:DWORD;
  18.     dwHeight:DWORD;
  19.     wPlanes:WORD;
  20.     wBitsPerPixels:WORD;
  21.     dwCompression:DWORD;
  22.     dwDataSize:DWORD;
  23.     dwHPixPerMeter:DWORD;
  24.     dwVPixPerMeter:DWORD;
  25.     dwColors:DWORD;
  26.     dwImportantColors:DWORD;
  27.   end;
  28. TBitmapResize = class
  29.  private
  30.     public
  31.       function resizeBitmap(bmp:TBitmap; Width,Height:Integer):boolean;
  32.       constructor Create();
  33.   end;
  34. implementation
  35. { TBitmapResize }
  36. constructor TBitmapResize.Create;
  37. begin
  38. end;
  39. function TBitmapResize.resizeBitmap(bmp: TBitmap; Width, Height: Integer): boolean;
  40. var
  41.   x,y,y_old,x_old :integer;
  42.   M : TMemoryStream;
  43.   Mold : TMemoryStream;
  44.   bmph:TBITMAPHEADER;
  45.   px:PIXEL_RGB;
  46. begin
  47.   Result:=False;
  48.   if(Width>=bmp.Width) or (Height>=bmp.Height) then Exit;
  49.   M:=TMemoryStream.Create;
  50.   Mold := TMemoryStream.Create;
  51.   //On récupère le header
  52.   bmp.SaveToStream(M);
  53.   M.Position:=0;
  54.   M.Read(bmph,sizeof(bmph));
  55.   //on récupère l'image initiale
  56.   Mold.SetSize(M.Size-M.Position);
  57.   Mold.CopyFrom(M,Mold.Size);
  58.   Mold.Position:=0;
  59.   //on modifie le header
  60.   bmph.dwWidth:=Width;
  61.   bmph.dwHeight:=Height;
  62.   bmph.dwDataSize:=3*Width*Height;
  63.   bmph.dwOffset:=sizeof(bmph);
  64.   bmph.dwTotalSize:=bmph.dwDataSize+bmph.dwOffset;
  65.   //Ecriture du nouveau header
  66.   M.Position:=0;
  67.   M.Write(bmph,sizeof(bmph));
  68.   //Formattage de la taille de l'image en mémoire
  69.   M.SetSize(bmph.dwTotalSize);
  70.   //On redimensionne
  71.   try
  72.     for y := 0 to Height-1 do
  73.     begin
  74.       y_old := Round((y * bmp.Height)/Height);
  75.       for x := 0 to Width-1 do
  76.       begin
  77.         x_old := Round((x * bmp.Width)/Width);
  78.         Mold.Position := 3*(y_old*bmp.Width+x_old);
  79.         Mold.read(px,sizeof(px));
  80.         M.Write(px,sizeof(px));
  81.       end;
  82.     end;
  83.     //on charge dans le TBitmap
  84.     M.position:=0;
  85.     bmp.LoadFromStream(M);
  86.     Result:=True;
  87.   finally
  88.     Mold.Free;
  89.     M.free;
  90.   end;
  91. end;
  92. end.

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed