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

Traitement d'images Discussion :

Problème dans la rotation d'image, image décalé à droite


Sujet :

Traitement d'images

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Etudiant
    Inscrit en
    Mars 2024
    Messages
    1
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Etudiant

    Informations forums :
    Inscription : Mars 2024
    Messages : 1
    Points : 1
    Points
    1
    Par défaut Problème dans la rotation d'image, image décalé à droite
    Bonjour, j'essaye de faire une fonction qui fait tourner une image selon un certain angle mais le problème c'est que mon image de sortie est toujours décalé sur la droite et je ne comprend pas pourquoi, vous sauriez quel est le problème ?

    Mon code :
    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
    public void Rotation(float angle)
            {
                (int, int, int)[,] image_bis = ((int, int, int)[,])this.image.Clone();
                int x = image_bis.GetLength(1) / 2;
                int y = image_bis.GetLength(0) / 2;
     
                if (angle > 360)
                {
                    angle = angle % 360;
                }
     
                double angleRad = -angle * Math.PI / 180.0;
                double Acos = Math.Cos(angleRad);
                double Asin = Math.Sin(angleRad);
     
                this.largeur = Convert.ToInt32((image_bis.GetLength(1) * Math.Abs(Acos)) + (image_bis.GetLength(0) * Math.Abs(Asin)));
                this.hauteur = Convert.ToInt32(image_bis.GetLength(1) * Math.Abs(Asin) + (image_bis.GetLength(0) * Math.Abs(Acos)));
     
                this.hauteur -= this.hauteur % 4;
                this.largeur -= this.largeur % 4;
     
                this.image = new (int, int, int)[this.hauteur, this.largeur];
     
                int X = this.largeur / 2;
                int Y = this.hauteur / 2;
     
                for(int i = 0; i < this.hauteur; i++)
                {
                    for (int j = 0; j < this.largeur; j++)
                    {
                        int posX = Convert.ToInt16((Acos * (i - X)) + (Asin * (j - Y)) + x);
                        int posY = Convert.ToInt16((-Asin * (i - X)) + (Acos * (j - Y)) + y);
     
                        if( posX < image_bis.GetLength(0) && posX > 0 && posY < image_bis.GetLength(1) && posY > 0)
                        {
                            this.image[i, j] = image_bis[posX, posY];
                        }
                    }
                }
            }
    L'image final avec angle de 30 :
    Nom : Capture d'écran 2024-03-17 135033.png
Affichages : 182
Taille : 133,8 Ko

  2. #2
    Expert confirmé

    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2013
    Messages
    1 334
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2013
    Messages : 1 334
    Points : 4 156
    Points
    4 156
    Par défaut
    Bonjour,

    Il n'y a pas 1 centre mais 2 centres : celui de l'image source, appelons le (Xcs, Ycs) et celui de l'image destination, appelons le (Xcd, Ycd).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
      int Xcs = image_bis.GetLength(1) / 2;
      int Ycs = image_bis.GetLength(0) / 2;
    ...
       int Xcd = this.largeur / 2;
       int Ycd = this.hauteur / 2;
    ...
             int posX = Convert.ToInt16( Acos * (i - Xcd) + Asin * (j - Ycd) + Xcs);
             int posY = Convert.ToInt16(-Asin * (i - Xcd) + Acos * (j - Ycd) + Ycs);
    Normalement cela devrait corriger le problème.

    Cependant, l'utilisation dans la boucle de multiples multiplications flottantes et donc de conversions représente une implémentation très lente. En se rappelant que chaque droite est remplacée par une autre droite on peut utiliser l'algorithme de Bresenham ou du demi point qui ne nécessite que des opérations simples (additions, soustractions sur des entiers).
    Nom : Image rotation.png
Affichages : 123
Taille : 313,6 Ko
    Illustration sans anti-aliasing

    Salutations
    Ever tried. Ever failed. No matter. Try Again. Fail again. Fail better. (Samuel Beckett)

  3. #3
    Expert confirmé

    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2013
    Messages
    1 334
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2013
    Messages : 1 334
    Points : 4 156
    Points
    4 156
    Par défaut
    Bonjour,

    Par ailleurs, le calcul de la largeur (LX ci-après) et hauteur (LY ci-après) de l'image d'accueil me semble faux même s'il peut fonctionner pour certains angles (premier et troisième quartier).

    Pour les évaluer, il faut calculer les transformées des diagonales. Comme la rotation ne change pas les longueurs, on peut choisir le centre de rotation qui arrange : (0, 0) pour la première diagonale et (0, ymax) pour la seconde.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
       LX1 = abs(Convert.ToInt16( Acos * Xmax + Asin * Ymax);
       LY1 = abs(Convert.ToInt16(-Asin * Xmax + Acos * Ymax));
     
       LX2 = abs(Convert.ToInt16( Acos * Xmax - Asin * Ymax));
       LY2 = abs(Convert.ToInt16((-Asin * Xmax - Acos * Ymax));
     
       LX = max(LX1, LX2):
       LY = max(LY1, LY2):
    Le calcul peut être allégé en constatant que si LX1 < LX2 alors LY1 > LY2, donc on évite de calculer LY2 (et réciproquement bien sûr).

    En outre je ne comprends pas les % 4 ici. Si c'est pour un alignement bas sur des multiples de 4 (et pourquoi), on écrira plutôt a = (a + 3) & -4 pour avoir une valeur par excès sans division.

    Conseil : faire un dessin pour ce genre de processus évite bien des problèmes. Il faut porter les variables clés sur le dessin pour simplifier l'écriture du code.

    Salutations
    Ever tried. Ever failed. No matter. Try Again. Fail again. Fail better. (Samuel Beckett)

  4. #4
    Membre émérite

    Homme Profil pro
    Formation: Chimie et Physique (structure de la matière)
    Inscrit en
    Décembre 2010
    Messages
    1 333
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 77
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Formation: Chimie et Physique (structure de la matière)
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2010
    Messages : 1 333
    Points : 2 570
    Points
    2 570
    Billets dans le blog
    9
    Par défaut Problème dans la rotation d'image, image décalé à droite
    Bonjour,

    Le défaut des calculs initiaux apparaît immédiatement sur un simple graphique:

    Nom : Images décalées.png
Affichages : 132
Taille : 143,6 Ko

    les centres (C0, C1) des deux images ne sont pas superposés.

    Si l'on convient de noter
    X0 = F(X1, Y1)
    Y0 = G(X1, Y1)
    les relations donnant les coordonnées d'un point de l'image initiale (Im0) en fonction de celles du point correspondant de la nouvelle image (Im1),
    celles-ci doivent impérativement vérifier la correspondance entre les centres, soit:
    Xc0 = F(Xc1, Yc1)
    Yc0 = G(Xc1, Yc1)

    Une rotation d'angle (θ) s'exprime ainsi par les relations linéaires:
    X0 = Xc0 + (X1 - Xc1)*Cos(θ) - (Y1 - Yc1)*Sin(θ)
    Y0 = Yc0 + (X1 - Xc1)*Sin(θ) + (Y1 - Yc1)*Cos(θ)
    On vérifie facilement que l'expression des anciennes coordonnées en fonction des nouvelles respecte la superposition des centres.

    Je laisse le soin à l'intéressé d'adapter ces relations à des arrondis ou d'éventuelles interpolations.


    Le français, notre affaire à tous
    Grand Dictionnaire Terminologique

  5. #5
    Expert confirmé

    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2013
    Messages
    1 334
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2013
    Messages : 1 334
    Points : 4 156
    Points
    4 156
    Par défaut
    Bonjour,

    Il y a un calcul étrange de modulo sur un flottant : angle % 360 ?

    On passe d'un angle float à un double.

    Le test posX > 0 exclut posX == 0. Pourquoi ? Idem ppur posY.

    Ceci étant, même si l'usage de x et X, y et Y m'ont laissé croire à une confusion des centres, le calcul devrait garder les centres en coïncidence. Ce qui ne semble pas le cas à moins que l'image soit tronquée à droite.

    Salutations
    Ever tried. Ever failed. No matter. Try Again. Fail again. Fail better. (Samuel Beckett)

  6. #6
    Expert confirmé

    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2013
    Messages
    1 334
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2013
    Messages : 1 334
    Points : 4 156
    Points
    4 156
    Par défaut
    Bonjour,

    Je vais laisser ce sujet car je pense que c'est le produit d'un troll .

    Les formules d'itération étant correctes, les deux centres ne peuvent qu'être confondus comme l'a signalé wiwaxia.

    Ce n'est pas ce que l'image montre, donc l'image ne correspond pas au programme. Cela ne peut être que volontaire.

    Soit le PO est l'auteur de ce code sous optimal mais opérationnel et lui a trouvé un emploi ici. Soit le PO n'en est même pas l'auteur, a collé une image quelconque et se délecte de sa prouesse .

    Si les autres intervenants en sont d'accord, je demanderais le retrait de ce "sujet".

    Salutations
    Ever tried. Ever failed. No matter. Try Again. Fail again. Fail better. (Samuel Beckett)

  7. #7
    Membre émérite

    Homme Profil pro
    Formation: Chimie et Physique (structure de la matière)
    Inscrit en
    Décembre 2010
    Messages
    1 333
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 77
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Formation: Chimie et Physique (structure de la matière)
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2010
    Messages : 1 333
    Points : 2 570
    Points
    2 570
    Billets dans le blog
    9
    Par défaut Problème dans la rotation d'image, image décalé à droite
    Bonjour Guesset,

    Tu as peut-être bien raison, d'autant que le primo-intervenant ne montre aucune réactivité ...


    Le français, notre affaire à tous
    Grand Dictionnaire Terminologique

  8. #8
    Membre régulier
    Avatar de Alex64
    Homme Profil pro
    Senior . Formation : topographe
    Inscrit en
    Août 2014
    Messages
    58
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Senior . Formation : topographe
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Août 2014
    Messages : 58
    Points : 112
    Points
    112
    Billets dans le blog
    1
    Par défaut utiliser une autre formule du changement de base
    Bonjour

    A mon avis une autre formule du changement de base est nécessaire.
    voir page 36 de ce formulaire.pdf :
    Courbes de Bézier formulaire V7.pdf

    Elle permet de bien maitriser un changement de base car on peut définir un centre de rotation "omega" et une translation
    Dans l'exemple de la discussion alpha =+30° et "omega" est le centre de l'image.

    NB : si l'image de départ n'est pas centrée sur le fond noir il faudra appliquer une translation .
    "le bonheur est la seule chose que l'on peut donner sans l'avoir" (Txiki)

  9. #9
    Expert confirmé

    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2013
    Messages
    1 334
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2013
    Messages : 1 334
    Points : 4 156
    Points
    4 156
    Par défaut
    Bonjour Alex64,

    Citation Envoyé par Alex64 Voir le message
    ...A mon avis une autre formule du changement de base est nécessaire...
    Ce document est intéressant mais le changement de base qu'il propose n'est, ni plus ni moins, celui utilisé : translation, rotation puis translation.

    La seule différence n'est que cosmétique dans le sens où le second vecteur de translation est exprimé sous la forme du premier vercteur de translation complété d'un vecteur delta. C'est intéressant quand les 2 centres coïncident déjà car le vecteur delta devient nul.

    Dans le cas posé, cela ne change rien au résultat. Après rotation les centres doivent coïncider. Le code le montre mais pas l'image.

    Salut
    Ever tried. Ever failed. No matter. Try Again. Fail again. Fail better. (Samuel Beckett)

  10. #10
    Membre régulier
    Avatar de Alex64
    Homme Profil pro
    Senior . Formation : topographe
    Inscrit en
    Août 2014
    Messages
    58
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Senior . Formation : topographe
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Août 2014
    Messages : 58
    Points : 112
    Points
    112
    Billets dans le blog
    1
    Par défaut merci Guesset pour ton analyse
    [QUOTE=Guesset;12012503]Bonjour Alex64,


    Ce document est intéressant mais le changement de base qu'il propose n'est, ni plus ni moins, celui utilisé : translation, rotation puis translation.

    A mon avis , dans le code, il ne faut pas appliquer de translation sur l'axe X
    Mais j'ai du mal à interpréter ce code (je le connait pas).
    il faudrait mettre tout "à plat" concernant les datas de départ en "language" simple
    par exemple
    format du fond noir et coord. de son centre
    format de l'image et coord. de son centre


    Nom : image discussion.png
Affichages : 92
Taille : 28,4 Ko
    "le bonheur est la seule chose que l'on peut donner sans l'avoir" (Txiki)

  11. #11
    Membre émérite

    Homme Profil pro
    Formation: Chimie et Physique (structure de la matière)
    Inscrit en
    Décembre 2010
    Messages
    1 333
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 77
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Formation: Chimie et Physique (structure de la matière)
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2010
    Messages : 1 333
    Points : 2 570
    Points
    2 570
    Billets dans le blog
    9
    Par défaut Problème dans la rotation d'image, image décalé à droite
    Bonjour,

    Les deux translations sont implicitement présentes dans les expressions des écarts (X0 - Xc0, Y0 - Yc0) en fonction de (X1 - Xc1, Y1 - Yc1).

    Il ne reste qu'à définir les coordonnées des centres en fonction des dimensions des deux fichiers image:
    Xc0 = 0.5*(La0 - 1) ; Yc0 = 0.5*(Ha0 - 1) ;
    Xc1 = 0.5*(La1 - 1) ; Yc1 = 0.5*(Ha1 - 1) .

    La rotation ne produit pas de débordement si les dimensions du second fichier sont suffisamment élevées, et vérifient:
    La1 et Ha1 > Max(X0max, Y0max)
    - en supposant bien sûr que le domaine du premier fichier image et celui de son contenu pictural sont concentriques.


    Le français, notre affaire à tous
    Grand Dictionnaire Terminologique

  12. #12
    Expert confirmé

    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2013
    Messages
    1 334
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2013
    Messages : 1 334
    Points : 4 156
    Points
    4 156
    Par défaut
    Bonjour,

    La lecture est assez simple pour la partie effective de la rotation (dans la boucle) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
       int posX = Convert.ToInt16(( Acos * (i - X)) + (Asin * (j - Y)) + x);
       int posY = Convert.ToInt16((-Asin * (i - X)) + (Acos * (j - Y)) + y);
    Au centre (X, Y) de l'image de destination, (i, j) = (X, Y) par définition. Il s'ensuit que les différences sont nulles dans le calcul de la position :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
       int posX = Convert.ToInt16(( Acos * 0) + (Asin * 0) + x);   // posX = x
       int posY = Convert.ToInt16((-Asin * 0) + (Acos * 0) + y);   // posY = y
    Donc le point central (X, Y) de l'image de destination correspond au point central (x, y) de l'image source. Ce qui est contradictoire avec l'image présentée comme en résultant (voire l'illustration de wiwaxia).

    Salutations
    Ever tried. Ever failed. No matter. Try Again. Fail again. Fail better. (Samuel Beckett)

  13. #13
    Membre émérite

    Homme Profil pro
    Formation: Chimie et Physique (structure de la matière)
    Inscrit en
    Décembre 2010
    Messages
    1 333
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 77
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Formation: Chimie et Physique (structure de la matière)
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2010
    Messages : 1 333
    Points : 2 570
    Points
    2 570
    Billets dans le blog
    9
    Par défaut Problème dans la rotation d'image, image décalé à droite
    Deux erreurs aisément rectifiables sont à corriger dans ce qui a été donné en #11:
    a) l'angle de rotation a été inversé, et il faut changer le signe du facteur Sin(θ) dans les relations exprimant le changement de coordonnées:
    X0 = Xc0 + (X1 - Xc1)*Cos(θ) + (Y1 - Yc1)*Sin(θ) ,
    Y0 = Yc0 - (X1 - Xc1)*Sin(θ) + (Y1 - Yc1)*Cos(θ) ;
    b) les dimensions du fichier final sont minorées par la longueur de la diagonale de l'image initiale, et la condition de non-débordement s'exprime par les inégalités:
    La1 et Ha1 ≥ (La02 + Ha02)1/2 .

    Voici ce que donne le traitement de l'image originale repêchée sur la Toile, de dimensions 466x350, pour une rotation de 30° dans un domaine carré de côté 583 = √(4662 + 3502)

    Nom : F_1a.png
Affichages : 94
Taille : 244,3 Ko
    Nom : F_2.png
Affichages : 68
Taille : 276,5 Ko

    La qualité médiocre de l'image initiale ne permet pas de comparer les effets des divers procédés d'approximation (recours au pixel le plus proche, interpolation bilinéaire, etc ...) - mais on sort ici du sujet.


    Le français, notre affaire à tous
    Grand Dictionnaire Terminologique

  14. #14
    Expert confirmé
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    3 421
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 421
    Points : 5 820
    Points
    5 820
    Par défaut
    Salut

    en résumé le cadre doit être égale ou supérieur à la diagonal (le plus grande segment ) de l'image et celle-ci doit être centré sur le cadre
    Nous souhaitons la vérité et nous trouvons qu'incertitude. [...]
    Nous sommes incapables de ne pas souhaiter la vérité et le bonheur, et sommes incapables ni de certitude ni de bonheur.
    Blaise Pascal
    PS : n'oubliez pas le tag

  15. #15
    Expert confirmé

    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2013
    Messages
    1 334
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2013
    Messages : 1 334
    Points : 4 156
    Points
    4 156
    Par défaut
    Bonjour,

    Dimension du cadre : oui si on souhaite un cadre carré mais il peut être plus ajusté. Il suffit de voir les bandes noires en haut et en bas.

    Le calcul de dimension du cadre du code d'origine était correct. J'ai eu un doute qu'un peu de réflexion aurait pu levé : une rotation alpha nécessite la même place qu'une rotation -alpha grâce aux symétries du rectangle.

    Salutations
    Ever tried. Ever failed. No matter. Try Again. Fail again. Fail better. (Samuel Beckett)

Discussions similaires

  1. Rotation d'image dans un état
    Par Papapetch dans le forum IHM
    Réponses: 3
    Dernier message: 10/06/2006, 18h02
  2. Reconnaître une position dans une séquence d'images
    Par echataig dans le forum Algorithmes et structures de données
    Réponses: 6
    Dernier message: 23/01/2006, 17h44
  3. Rotation d'image (matrice)
    Par AsmBoy dans le forum Algorithmes et structures de données
    Réponses: 1
    Dernier message: 16/01/2006, 07h49
  4. Faire une rotation d'image
    Par sozie9372 dans le forum 2D
    Réponses: 6
    Dernier message: 30/11/2005, 22h40
  5. [Image]Rotation d'image
    Par psychomatt dans le forum 2D
    Réponses: 6
    Dernier message: 16/12/2004, 20h18

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