IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

rotation d'une matrice


Sujet :

C

Vue hybride

romain1986 rotation d'une matrice 05/05/2007, 15h56
diogene - Même si le résultat y... 05/05/2007, 19h07
souviron34 pour une rotation d'iage,... 06/05/2007, 02h18
romain1986 bonjour 07/05/2007, 19h52
diogene - Pour une rotation de... 08/05/2007, 15h50
Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Avril 2007
    Messages
    21
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 21
    Par défaut rotation d'une matrice
    Bonjour voici ma fonction qui a pour but de faire la rotation de ma matrice! C'est à dire que je dois faire la rotation d'une image de format .ppm! Mais avec mon code ci dessous j'arrive à faire la rotation mais ce n'est que la moitié de l'image qui est tourné de 90°! Et je ne comprends pas pourquoi!
    //colonne signifie le nombre de colonnes
    //ligne signifie le nombre de lignes

    Je n'ai pas tout mon code mtn ici sur cette rubrique car cela prendrai trop de place mais j'espère que vous avez assez d'informations pour comprende mon problème et pouvoir m'aider! Le code pour ecrire fonctionne car j'ai deja réaliser d'autres fonctions et cela va tres bien! Merci d'avance

    le code de ma fonction:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    struct pixel 
    {
    	int R;
    	int G;
    	int B;
    };
     
    struct pixel temp[MAX][MAX];
     
    void rotation (struct pixel mat[MAX][MAX],int colonne, int ligne)
    {
    	int i,j;
    	for(i=0;i<=ligne;i++) 
          {
                for(j=colonne;j>=1;j--) 
                {
    	            temp[j][i].R =mat[i][j].R;
    	            temp[j][i].G =mat[i][j].G; 
    	            temp[j][i].B =mat[i][j].B;
    	        }
    	  } 
    	for(i=1;i<=(ligne);i++) 
        {
    	   for(j=1;j<=(colonne);j++) 
    	       { 
    		       mat[i][j].R = temp[i][j].R;  
    		       mat[i][j].G = temp[i][j].G; 
    		       mat[i][j].B = temp[i][j].B;
    		   }
    	}
    }

  2. #2
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    - Même si le résultat y ressemble, ce n'est pas une rotation de 90° que tu as programmé puisque tous les pixels pour lequel i=j n'ont pas bougé. Une rotation laisse un seul point invariant : le centre de rotation
    - Pour ton problème qui doit se produire si l'image n'est pas carrée,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    for(i=0;i<=ligne;i++) 
                for(j=colonne;j>=1;j--) 
                {
    	            temp[j][i].R =mat[i][j].R;
                         ....
    	        }
    fait que si l'image d'origine a ligne lignes et colonne colonnes, dans temp, elle a colonne ligne et ligne colonnes
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    	for(i=1;i<=(ligne);i++) 
        {
    	   for(j=1;j<=(colonne);j++) 
    	       { 
    		       mat[i][j].R = temp[i][j].R;
                           ....
    copie dans l'image d'origine le contenu de temp de ligne lignes et colonne colonnes, donc pas le contenu "utile".
    Par exemple, si l'image a 5 lignes et 10 colonnes, temp a 10 lignes et 5 colonnes " utiles" (les colonnes suivantes de temp sont à zéro puisque temp est semble t-il en global) et je recopie 5 lignes et 10 colonnes de temp dans l'image. L'image finale n'est modifiée que pour le carré de 5 lignes et 5 colonnes , le reste est noir.

    si l'image a 10 lignes et 5 colonnes, temp a 5 lignes et 10 colonnes " utiles" (les lignes suivantes de temp sont à 0) et je recopie 10 lignes et 5 colonnes de temp dans l'image. L'image finale n'est modifiée que pour le carré de 5 lignes et 5 colonnes , les 5 colonnes suivantes sont celles de l'image originale et le reste est noir.

  3. #3
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    pour une rotation d'iage, TOUJOURS partir du pixel résultat et calculer le pixel d'origine, à cause des erreurs d'arrondi qui donneront dans l'image résultante des pixels noirs, et donc des effets de moirés.

    De plus, ton image résultante n'aura pas les mêmes dimensions, et aura des angles noirs (sauf si tu coupes après coup).

    Donc, primo, calculer les coordonnées limites (par calcul de la rotation des sommets, puis min/max des (x,y) pour ces 4 points.

    Secondo, il est plus pratique de faire une fonction qui effectue la rotation.

    Tertio, par conséquent, il faut écrire, pour effectuer une rotation Angle de l'image originale IM1, pour un résultat dans IM2 :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
     
    /*
     * Fonction de rotation
     */
    static void RotateInteger ( int Xc, int Yc, int Xin, int Yin, double Angle, 
                                         int *Xout, int *Yout ) 
    {
      *Xout = Xc + (int)(((Xin - Xc) * cos(Angle)) + ((Yin - Yc) * sin(Angle))) ;
      *Yout = Yc + (int)(- ((Xin - Xc) * sin(Angle)) + ((Yin - Yc) * cos(Angle))) ;
    }
     
    /* 
     * Rotation d'une image
     */
    int RotateImage ( unsigned char *IM1, int Dimx1, int Dimy1, double Angle,
                             unsigned char **IM2, int *Dimx2, int *Dimy2 )
    {
    int                  i, j ; /* Indices de boucle */
    int                  x1, y1 ; /* Pour les coordonnées dans l'image initiale */
    int                  x[4], y[4] ;  /* Pour calculer les limites de la nouvelle image */
    int                  xc1, yc1, xc2, yc2 ;  /* Coordonnées du centre */
    int                  xmin, xmax=0, ymin, ymax=0 ;
     
     
    /* Calcul du centre */
     
    xc1 = Dimx1/2 ;
    yc1 = Dimy1/2 ;
     
     
    /* Calcul des limites */
     
    RotateInteger ( xc1, yc1, 0, 0, Angle, &x[0], &y[0] );
    RotateInteger ( xc1, yc1, Dimx1, 0, Angle, &x[1], &y[1] );
    RotateInteger ( xc1, yc1, 0, Dimy1, Angle, &x[2], &y[2] );
    RotateInteger ( xc1, yc1, Dimx1, Dimy1, Angle, &x[3], &y[3] );
     
    xmin = Dimx1 ;
    ymin = Dimy1 ;
     
    for ( i = 0 ; i < 4 ; i++ )
      {
         if ( x[i] < xmin )
            xmin = x[i] ;
         if ( x[i] > xmax )
            xmax = x[i] ;
         if ( y[i] < ymin )
            ymin = y[i] ;
         if ( y[i] > ymaw )
            ymax = y[i] ;
      }
     
    *Dimx2 = xmax - xmin + 1 ;
    *Dimy2 = ymax - ymin + 1 ;
     
     
    /* Allocation du buffer pour l'image resultat */
     
    *IM2 = calloc ( ((*Dimx2)*(*Dimy2)), sizeof(unsigned char) );
    if ( *IM2 == NULL )
      {
         *Dimx2 = 0 ;
         *Dimy2 = 0 ;
         return ERROR ;  
      }
     
     
    /* Calcul du centre image 2 */
     
    xc2 = *Dimx2/2 ;
    yc2 = *Dimy2/2 ;
     
    /* Remplissage du buffer */
     
    for ( i = 0 ; i < *Dimy2 ; i++ )
        for ( j = 0 ; j < *Dimx2 ; j++ )
          {
              RotateInteger ( xc2, yc2, j, i, -Angle, &x1, &y1 );
     
     
              /* Elimination des points qui tomberaient en dehors de IM1 */
     
              if ( ((int)fabs((double)(x1-xc)) > xc) || 
                   ((int)fabs((double)(y1-yc) > yc) )
                 continue ;
     
     
              /* Remplissage */
     
              (*IM2)[i*(*Dimx2)+j] = IM1[y1*Dimx1+x1] ;
          }
     
    return SUCCESS ;
    }

  4. #4
    Membre averti
    Inscrit en
    Avril 2007
    Messages
    21
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 21
    Par défaut bonjour
    Tout d'abord merci à vous deux de votre aide! Et bien mon problème est que nous avons vu pour le moment que tres peu de foncttionalités et methodes pour definir une fonction et algorithme! Pour cela je ne comprends pas du tout le dernier là! Désolé et j'aurais du mal à l'expliquer à mon professeur! :S Mais si la 1ère personnne saurais m'aider d'avantage pour restructurer ma fonction j'en serais tres reconnaissant! MERCI

  5. #5
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    - Pour une rotation de 90°(sens direct, inverse des aiguilles d'une montre) , le pixel de coordonnées (colonne = col, ligne = lg) doit se déplacer en (colonne = lg, ligne = N-1-col). (N = nombre de colonnes de l'image)
    - Pour une rotation de 90°(sens inverse, sens des aiguilles d'une montre) , le pixel de coordonnées (colonne = col, ligne = lg) doit se déplacer en (colonne = M-1-lg, ligne = col). (M = nombre de lignes de l'image)
    - L'image après rotation est de dimension M colonnes x N lignes

    - Tu utilises un tableau intermédiaire dans ton programme. Ce n'est pas obligatoire : La rotation peut se faire sur place, sans tableau intermédiaire MxN , mais nécessite de traiter simultanément 4 points : En rotation de sens direct
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    (col,lg) ->  (lg, N-1-col) -> (N-1-col, N-1-lg) -> (N-1-lg, col)
    Temp <- Point(col,lg)
    Point(col,lg) <- Point(N-1-lg, col)
    Point(N-1-lg, col) <- Point(N-1-col, N-1-lg)
    Point(N-1-col, N-1-lg) <- Point(lg, N-1-col)
    Point(lg, N-1-col) <- Temp
    Comme la rotation ne doit pas se produire plusieurs fois pour un même point, col et lg parcourent seulement 1/4 du plan NxN :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    0 <=  col < (N+1)/2 (division entière)
    0 <= lg < Minimum ((N+1)/2, M)

  6. #6
    Membre éprouvé

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 116
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 116
    Par défaut
    En algèbre linéaire on parle de 'matrice transposée', c'est ce qui correspond à une rotation de 90 degrés dans le sens horaire, additionnée d'un retournement 'miroir' horizontal (symétrie horizontale). Voilà pour la recherche google 'théorie'

Discussions similaires

  1. rotation d'une matrice
    Par paladice dans le forum Langage
    Réponses: 1
    Dernier message: 02/12/2010, 15h41
  2. Réponses: 3
    Dernier message: 17/04/2009, 11h32
  3. Réponses: 3
    Dernier message: 21/09/2007, 16h28
  4. Rotation d'une matrice
    Par timtim2007 dans le forum Prolog
    Réponses: 8
    Dernier message: 25/04/2007, 20h17
  5. Réponses: 8
    Dernier message: 07/09/2006, 09h08

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo