Programme très lent

jojoduv Messages postés 3 Date d'inscription jeudi 31 mai 2007 Statut Membre Dernière intervention 1 juin 2007 - 31 mai 2007 à 13:25
jojoduv Messages postés 3 Date d'inscription jeudi 31 mai 2007 Statut Membre Dernière intervention 1 juin 2007 - 1 juin 2007 à 11:30
   Bonjour a tous, je suis en projet et je developpe une petite application qui gère les modifications géométrique d'une image. J'utilise une interpolation bilinéaire.
   Cependant lors de l'éxécution d'une fonction d'agrandissement sur X et Y, la programme met presque une minute à renvoyer l'image agrandie.
   Quelqu'un pourrait-il m'aider ou me donner des piste pour rendre mon programme plus rapide ?
   Merci d'avance   

7 réponses

cs_laurent1024 Messages postés 987 Date d'inscription mardi 31 mai 2005 Statut Membre Dernière intervention 30 août 2012 25
31 mai 2007 à 13:48
Premierement si ce n'est pas deja fait, tu peux mettre ton code en release au lieu qu'il soit de debug.
Après faut voir dans ton algo, peut etre que tu peut simplifier les boucles, et essayer de limiter les calculs couteux en temps de mémoire ( par exemple au lieu de faire sqrt(10) tu stocke la valeur dans une variable au lieu d'utiliser a chaque fois la fonction).
Sans le code, c'est difficile de dire ce que tu peux modifier d'autre.
++ 
0
cs_rt15 Messages postés 3874 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 7 novembre 2014 13
1 juin 2007 à 08:34
Salut,

Si ca ne te dérange pas d'utiliser les routines de windoze, tu peux utiliser StretchBlt (Ou StretchDIBits).

Pour avoir un beau résultat, il faut utiliser SetStretchBltMode avec HALFTONE en paramètre, sans oublier le SetBrushOrgEx comme précisé.
0
jojoduv Messages postés 3 Date d'inscription jeudi 31 mai 2007 Statut Membre Dernière intervention 1 juin 2007
1 juin 2007 à 08:45
Tout d'abord merci de prendre un peu de temps pour résoudre mon problème.
Mon code est déjà en release.
J'ai implémenté mon code de la façon la plus simple à mes yeux. Voici celui-ci:

void CImageBMP::agrandissement(CImageBMP& out, double factorX, double factorY)
{
 int imageType = m_iTypeImage;
 int HauteurIn = m_iHauteur;
 int LargeurIn = m_iLargeur;
 int HauteurOut = (int)ceil((double)HauteurIn * (double)factorY);
 int LargeurOut = (int)ceil((double)LargeurIn * (double)factorX);
 
 out.initialisation( HauteurOut,LargeurOut,imageType,-1);


 double iPrim;
 double jPrim;
 double x;
 double y;
 int flooriPrim;
 int floorjPrim;
 int ceiliPrim;
 int ceiljPrim;
 
   //parcour de l'image
  for (int i=0; i < HauteurOut; i++)
  {
   for (int j=0; j < LargeurOut; j++)
   {
    iPrim = (  ( i+1.0 ) / factorY  ) - 1.0;
    jPrim = (  ( j+1.0 ) / factorX  ) - 1.0;
     
    // interpolation bilineaire
    x = (double)iPrim - (int)iPrim; 
    y = (double)jPrim - (int)jPrim;
    
    flooriPrim = (int)(iPrim);
    floorjPrim = (int)(jPrim);
    ceiliPrim  = (int)(iPrim)+1;
    ceiljPrim  = (int)(jPrim)+1;

    //remplissage de l'image et gestion des bords
    if (((iPrim) <= HauteurIn-2)&&((jPrim) <= LargeurIn-2))
    {
     out (i, j) = (unsigned char) (m_ppucLigne[ flooriPrim ][ floorjPrim ] * ( (1-x) * (1-y) )  
      + m_ppucLigne[ flooriPrim ][ ceiljPrim  ] * ( (1-x) *   y   )
      + m_ppucLigne[ ceiliPrim  ][ floorjPrim ] * (   x   * (1-y) )
      +   m_ppucLigne[ ceiliPrim  ][ ceiljPrim  ] * (   x   *   y   ));  
    }
    else
    { 
     out (i, j) = 0;
    }      
   }
  }

Cette fonction permet l'agrandissement d'une image par des facteurs X et Y à l'aide d'une interpolation bilinéaire.
Mais lorsque je pose deux facteurs de 10, la fonction met presque une minute à me renvoyer la nouvelle image !!!
Pour moi, ce code est simplement deux boucles for imbriquée avec un calcul inséré.
Je ne vois pas les données que je pourrais stocker. 

 

 
0
cs_laurent1024 Messages postés 987 Date d'inscription mardi 31 mai 2005 Statut Membre Dernière intervention 30 août 2012 25
1 juin 2007 à 08:58
C'est normal que ce soit long si tu mets des grands facteurs sur des images assez grandes. La quantité d'informations à traiter devient forcément importante.  Tu pourrais peut etre essayer d'utiliser des threads qui travaillent chqu'un sur des parties de l'images, mais je ne suis pas sur que cela puisse te faire gagner beaucoup de temps.

++  
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
1 juin 2007 à 09:55
iPrim = ((i + 1.0) / factorY) - 1.0;
Pourquoi ce recalcul à chaque tour de j puisqu'il n'en dépend pas ???


jPrim = ((j + 1.0) / factorX) - 1.0;


Pour ces 2 calculs très lourds en cycles, il vaut mieux calculer au départ le pas d'incrémentation et faire une simple addition dans les boucles.

ciao...
BruNews, MVP VC++
0
luhtor Messages postés 2023 Date d'inscription mardi 24 septembre 2002 Statut Membre Dernière intervention 28 juillet 2008 6
1 juin 2007 à 10:37
D'utiliser des float au lieu des doubles, ca aiderait aussi.

De plus, quand tu fais ca:
    // interpolation bilineaire
    x = (double)iPrim - (int)iPrim; 
    y = (double)jPrim - (int)jPrim;
    
    flooriPrim = (int)(iPrim);
    floorjPrim = (int)(jPrim);
    ceiliPrim  = (int)(iPrim)+1;
    ceiljPrim  = (int)(jPrim)+1;

Tu convertis 3 fois de double en int la meme quantité, alors que tu pourrais le faire une seule fois:
    // interpolation bilineaire

    flooriPrim = (int)(iPrim);


    floorjPrim = (int)(jPrim);


    ceiliPrim  = flooriPrim +1;


    ceiljPrim  = floorjPrim +1;


    x = (double)iPrim - flooriPrim ; 

    y = (double)jPrim - floorjPrim ;

    

Mais c'est en passant en float, que tu vas gagner le plus. Le float te permettrait aussi d'utiliser le GPU pour faire ca. Il serait content de pouvoir t'aider :) il est spécialiser la dedans. Il te le ferait en 1/10sec ce calcul pour peu que ton image ne soit pas trop grande. Dans le cas contraire, il faudrait la découper et l'envoyer a la carte video par morceau.
0
jojoduv Messages postés 3 Date d'inscription jeudi 31 mai 2007 Statut Membre Dernière intervention 1 juin 2007
1 juin 2007 à 11:30
   Merci beeaucoup de tous ces renseignements  je fais un essai et vous tiens au courant !!!
0
Rejoignez-nous