Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1482 connectés 

  FORUM HardWare.fr
  Programmation

  [C++] Code pour compresser une image, ça marche pas... Help please

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[C++] Code pour compresser une image, ça marche pas... Help please

n°64104
Alload
Posté le 08-10-2001 à 22:15:34  profilanswer
 

J'ai écrit un code qui devrait normalement compresser grâce à la quantification vectorielle des images bitmaps, mais ça a pas l'air de marcher trop fort... Disons que le dictionnaire ne se crée pas correctement, si vous pouviez essayer de repérer les erreurs.
 
Merci d'avance.
:)
 
 
 
#include <windows.h>
#include <time.h>
#include <fstream>
#include <vector>
#include <iostream>
using namespace std;
 
#define for if(1) for
 
///////////////////////////////////////////////////////////////////
 
struct SBlock
{
 long vector[12];
 short tableref;
 long distance;
};
 
///////////////////////////////////////////////////////////////////
 
struct STable
{
 long vector[12];
 short nblock;
 vector<short> blockref;
};
 
///////////////////////////////////////////////////////////////////
 
int CompressImage(char szLoadPath[400], char szSavePath[400], short Width, short Height,
      short NVECTORTABLE, short NLOOPTABLE)
{
 //Chargement du bitmap à compresser
 
 cout << "Chargement du bitmap" << endl;
 
 HDC hdcImage;
 HBITMAP hbm;
 
 hbm = (HBITMAP)LoadImage( NULL, szLoadPath, IMAGE_BITMAP, Width, Height,
        LR_LOADFROMFILE | LR_CREATEDIBSECTION);
 
 if (hbm == NULL)
  return 1;
 
    hdcImage = CreateCompatibleDC(NULL);
    SelectObject(hdcImage, hbm);
 
 
 //Création des blocks 2*2 de vecteurs
 
 cout << "Creation des blocks" << endl;
 
 SBlock *block = new SBlock[(Width / 2) * (Height / 2)];
 short nBlock = 0;
 
 int pixelvalue;
 
 for (short y = 0; y < Height - 1; y += 2)
 {
  for (short x = 0; x < Width - 1; x += 2)
  {
   short r, g, b;
 
   pixelvalue = GetPixel(hdcImage, x, y);
   r = (pixelvalue & 0xFF);
   g = (pixelvalue & 0xFF00)>>8;
   b = (pixelvalue & 0xFF0000)>>16;
   block[nBlock].vector[0] = r;
   block[nBlock].vector[1] = g;
   block[nBlock].vector[2] = b;
 
   pixelvalue = GetPixel(hdcImage, x+1, y);
   r = (pixelvalue & 0xFF);
   g = (pixelvalue & 0xFF00)>>8;
   b = (pixelvalue & 0xFF0000)>>16;
   block[nBlock].vector[3] = r;
   block[nBlock].vector[4] = g;
   block[nBlock].vector[5] = b;
   
   pixelvalue = GetPixel(hdcImage, x, y+1);
   r = (pixelvalue & 0xFF);
   g = (pixelvalue & 0xFF00)>>8;
   b = (pixelvalue & 0xFF0000)>>16;
   block[nBlock].vector[6] = r;
   block[nBlock].vector[7] = g;
   block[nBlock].vector[8] = b;
   
   pixelvalue = GetPixel(hdcImage, x+1, y+1);
   r = (pixelvalue & 0xFF);
   g = (pixelvalue & 0xFF00)>>8;
   b = (pixelvalue & 0xFF0000)>>16;
   block[nBlock].vector[9] = r;
   block[nBlock].vector[10] = g;
   block[nBlock].vector[11] = b;
 
   nBlock++;
  }
 }
 
 
 //Création de la table initiale générée aléatoirement à partir des blocks
 
 cout << "Initialisation aleatoire de la table" << endl;
 
 STable *table = new STable[NVECTORTABLE];
 
 int randomblock = 0;
 int randomplus = nBlock / NVECTORTABLE;
 
 for (short i = 0; i < NVECTORTABLE; i++)
 {
  for (short y = 0; y < 12; y++)
   table[i].vector[y]= block[randomblock].vector[y];
 
  randomblock += randomplus - 1;
 }
 
 
 //Mise en référence de la table 0 pour tous les blocks
 
 cout << "Initialisation des blocks" << endl;
 
 for (short i = 0; i < nBlock; i++)
 {
  long distance = (table[0].vector[0] - block[i].vector[0]) * (table[0].vector[0] - block[i].vector[0]) +
      (table[0].vector[1] - block[i].vector[1]) * (table[0].vector[1] - block[i].vector[1]) +
      (table[0].vector[2] - block[i].vector[2]) * (table[0].vector[2] - block[i].vector[2]) +
      (table[0].vector[3] - block[i].vector[3]) * (table[0].vector[3] - block[i].vector[3]) +
      (table[0].vector[4] - block[i].vector[4]) * (table[0].vector[4] - block[i].vector[4]) +
      (table[0].vector[5] - block[i].vector[5]) * (table[0].vector[5] - block[i].vector[5]) +
      (table[0].vector[6] - block[i].vector[6]) * (table[0].vector[6] - block[i].vector[6]) +
      (table[0].vector[7] - block[i].vector[7]) * (table[0].vector[7] - block[i].vector[7]) +
      (table[0].vector[8] - block[i].vector[8]) * (table[0].vector[8] - block[i].vector[8]) +
      (table[0].vector[9] - block[i].vector[9]) * (table[0].vector[9] - block[i].vector[9]) +
      (table[0].vector[10] - block[i].vector[10]) * (table[0].vector[10] - block[i].vector[10]) +
      (table[0].vector[11] - block[i].vector[11]) * (table[0].vector[11] - block[i].vector[11]);
 
  block[i].tableref = 0;
  block[i].distance = distance;
 
  table[0].nblock++;
  table[0].blockref.push_back(i);
 }
 
 
 //Mise au point de la table
 
 cout << "Mise au point de la table" << endl;
 
 for (short loop = 0; loop < NLOOPTABLE; loop++)
 {
  //Recherche de la meilleur table pour chaque block
 
  cout << "1" << endl;
 
  for (short i = 0; i < nBlock; i++)
   for (short j = 0; j < NVECTORTABLE; j++)
   {
    long distance = (table[j].vector[0] - block[i].vector[0]) * (table[j].vector[0] - block[i].vector[0]) +
        (table[j].vector[1] - block[i].vector[1]) * (table[j].vector[1] - block[i].vector[1]) +
        (table[j].vector[2] - block[i].vector[2]) * (table[j].vector[2] - block[i].vector[2]) +
        (table[j].vector[3] - block[i].vector[3]) * (table[j].vector[3] - block[i].vector[3]) +
        (table[j].vector[4] - block[i].vector[4]) * (table[j].vector[4] - block[i].vector[4]) +
        (table[j].vector[5] - block[i].vector[5]) * (table[j].vector[5] - block[i].vector[5]) +
        (table[j].vector[6] - block[i].vector[6]) * (table[j].vector[6] - block[i].vector[6]) +
        (table[j].vector[7] - block[i].vector[7]) * (table[j].vector[7] - block[i].vector[7]) +
        (table[j].vector[8] - block[i].vector[8]) * (table[j].vector[8] - block[i].vector[8]) +
        (table[j].vector[9] - block[i].vector[9]) * (table[j].vector[9] - block[i].vector[9]) +
        (table[j].vector[10] - block[i].vector[10]) * (table[j].vector[10] - block[i].vector[10]) +
        (table[j].vector[11] - block[i].vector[11]) * (table[j].vector[11] - block[i].vector[11]);
 
    if (distance < block[i].distance)
    {
     for (short k = 0; k < table[block[i].tableref].nblock; k++)
     {
      if (table[block[i].tableref].blockref[k] == i)
      {
       table[block[i].tableref].nblock--;
       table[block[i].tableref].blockref.erase(table[block
[i].tableref].blockref.begin() + i);
 
       block[i].distance = distance;
       block[i].tableref = j;
 
       table[j].nblock++;
       table[j].blockref.push_back(i);
 
       break;
      }
     }
    }
   }
 
   
  //Affinage de la table en calculant les isobarycentres des groupes de blocks
 
  cout << "2"<< endl;
 
  for (short i = 0; i < NVECTORTABLE; i++)
  {
   for (short j = 0; j < 12; j++)
   {
    double coord = 0;
 
    for (short k = 0; k < table[i].nblock; k++)
     coord += block[table[i].blockref[k]].vector[j];
 
    coord = coord / table[i].nblock;
    table[i].vector[j] = (long) coord;
   }
  }
 
 
  //Mise à jour de la distance entre les blocks et la nouvelle table
 
  cout << "3" << endl;
 
  for (short i = 0; i <= nBlock; i++)
  {
   long distance = (table[block[i].tableref].vector[0] - block[i].vector[0]) * (table[block[i].tableref].vector[0] - block[i].vector[0]) +
       (table[block[i].tableref].vector[1] - block[i].vector[1]) * (table[block[i].tableref].vector[1] - block[i].vector[1]) +
       (table[block[i].tableref].vector[2] - block[i].vector[2]) * (table[block[i].tableref].vector[2] - block[i].vector[2]) +
       (table[block[i].tableref].vector[3] - block[i].vector[3]) * (table[block[i].tableref].vector[3] - block[i].vector[3]) +
       (table[block[i].tableref].vector[4] - block[i].vector[4]) * (table[block[i].tableref].vector[4] - block[i].vector[4]) +
       (table[block[i].tableref].vector[5] - block[i].vector[5]) * (table[block[i].tableref].vector[5] - block[i].vector[5]) +
       (table[block[i].tableref].vector[6] - block[i].vector[6]) * (table[block[i].tableref].vector[6] - block[i].vector[6]) +
       (table[block[i].tableref].vector[7] - block[i].vector[7]) * (table[block[i].tableref].vector[7] - block[i].vector[7]) +
       (table[block[i].tableref].vector[8] - block[i].vector[8]) * (table[block[i].tableref].vector[8] - block[i].vector[8]) +
       (table[block[i].tableref].vector[9] - block[i].vector[9]) * (table[block[i].tableref].vector[9] - block[i].vector[9]) +
       (table[block[i].tableref].vector[10] - block[i].vector[10]) * (table[block[i].tableref].vector[10] - block[i].vector[10]) +
       (table[block[i].tableref].vector[11] - block[i].vector[11]) * (table[block[i].tableref].vector[11] - block[i].vector[11]);
 
   block[i].distance = distance;
  }
 }
 
 
 //Création de l'image compressée
 
 cout << "Creation du fichier" << endl;
 
 ofstream file(szSavePath);
 file << Width << " ";
 file << Height << " ";
 file << nBlock << " ";
 file << NVECTORTABLE;
 
 for (short i = 0; i < NVECTORTABLE; i++)
 {
  file << " " << table[i].vector[0];
  file << " " << table[i].vector[1];
  file << " " << table[i].vector[2];
  file << " " << table[i].vector[3];
  file << " " << table[i].vector[4];
  file << " " << table[i].vector[5];
  file << " " << table[i].vector[6];
  file << " " << table[i].vector[7];
  file << " " << table[i].vector[8];
  file << " " << table[i].vector[9];
  file << " " << table[i].vector[10];
  file << " " << table[i].vector[11];
 }
 
 for (short i = 0; i < nBlock; i++)
  file << " " << block[i].tableref;
 
 file << endl;
 
 file.close();
 
 return 0;
}
 
int main()
{
 int last = GetTickCount();
 int current;
 int total;
 
 cout << "Debut" << endl;
 
 int x = CompressImage( "source.bmp",
       "sortie.txt",
       250, 300,
       4, 2);
 
 if (x)
  cout << "Erreur pendant la compression";
 
 current = GetTickCount();
 total = current - last;
 total = (total / 1000) / 60;
 
 cout << "Temps mis pour compresser l'image: " << total << " minutes" << endl;
 
 while(1)
 {
 }
 
 return 0;
}

mood
Publicité
Posté le 08-10-2001 à 22:15:34  profilanswer
 

n°64116
chrisbk
-
Posté le 09-10-2001 à 08:36:17  profilanswer
 

salut
 
 
J'ai pas tout lu, mais y'a un truc qui me chiffone
 
   if (distance < block[i].distance)
   {
    for (short k = 0; k < table[block[i].tableref].nblock; k++)
    {
     if (table[block[i].tableref].blockref[k] == i)
     {
      ....
      break;
     }
    }
   }
  }
donc avec ton break, tu t'arrete lorsque tu trouve un distance qui est inferieur a block[i].distance
S'pas ?
ce qui est pas bon, puisque rien ne te dis que la premiere entree dans le codebook pour laquelle (distance < block[i].distance) soit la bonne ....
OK ce sera peut etre affinee lors d'une passe ulterieur, a mois que tu n'atteignes ta limite de nombre de passes avant....
 
Ensuite, je ne suis pas convaincu que ta methode soit tres bonne
tu initialise ton codebook avec des valeurs choisies au hasard parmis l'image . et ensuite ton codebook n'est plus updater qu'avec ton calcul de barycentre  
Mais que se passe t'il si jamais tu a choisi deux fois le meme endroit lors de ton tirage aleatoire (ou deux endroits different de position mais identique de couleur) ?
tu te retrouve avec une ou plusieurs entree du codebook (presque) inutile  
 
Aussi faudrait que tu voye pour ajouter des conditions d'arret, le VQ c plutot long alors si on peut faire au plus vite..
 
Je m etends pas trop j'ai deja fait tout une doc sur le sujet :
 
http://www.alrj.org/docs/algo/vqfr/
 
 
 
 
PS : heuh, les #define for if(1) for , t'es sur ? :)

 

[edtdd]--Message édité par chrisbk--[/edtdd]


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation

  [C++] Code pour compresser une image, ça marche pas... Help please

 

Sujets relatifs
[DELPHI] Champ agregat HELP!!![VB] lire des lignes quand line input ne marche pas
Pros de Netscape, Help please....!!![HTML] code formulaire...
requete sql help!!Help siouxplé bête pb sur VC++
[ASP]pourquoi ça marche po ?Help !!! c koi ???
HELP URGENT !!!!!!comment ca marche un serveur de jeu masivemnt online?
Plus de sujets relatifs à : [C++] Code pour compresser une image, ça marche pas... Help please


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR