15 votes

Comment faire pivoter une image ?

Voir aussi : Pourquoi l'algorithme de rotation de mon image ne fonctionne-t-il pas ?

Cette question n'est pas spécifique à une langue, c'est un problème de mathématiques. Je vais cependant utiliser du code C++ pour expliquer ce dont j'ai besoin, car je ne suis pas très doué en mathématiques.

Voici comment l'image est composée :

ImageMatrix image;
image[0][0][0] = 1;
image[0][1][0] = 2;
image[0][2][0] = 1;
image[1][0][0] = 0;
image[1][1][0] = 0;
image[1][2][0] = 0;
image[2][0][0] = -1;
image[2][1][0] = -2;
image[2][2][0] = -1;

Voici le prototype de la fonction que j'essaie de créer :

ImageMatrix rotateImage(ImageMatrix image, double angle);

Je voudrais faire pivoter uniquement les deux premiers indices (lignes et colonnes) mais pas le canal.

37voto

Hannes Ovrén Points 5781

La façon habituelle de résoudre ce problème est de procéder à l'envers. Au lieu de calculer l'emplacement de chaque pixel de l'image d'entrée dans l'image de sortie, vous calculez l'emplacement de chaque pixel de l'image de sortie dans l'image d'entrée (en effectuant la même rotation que celle de l'image d'entrée). dans l'autre sens . De cette façon, vous pouvez être sûr que tous les pixels de l'image de sortie auront une valeur.

output = new Image(input.size())

for each pixel in input:
{
  p2 = rotate(pixel, -angle);
  value = interpolate(input, p2)
  output(pixel) = value
}

Il existe différentes façons de procéder à l'interpolation. Pour la formule de rotation, je pense que vous devriez vérifier https://en.wikipedia.org/wiki/Rotation_matrix#In_two_dimensions

Mais juste pour être gentil, le voici (rotation du point (x,y) angle degrés/radians) :

 newX = cos(angle)*x - sin(angle)*y
 newY = sin(angle)*x + cos(angle)*y

3voto

Frans Bouma Points 6015

Pour faire pivoter une image, vous créez 3 points :

A----B 
|
|
C

et faites-la pivoter autour de A. Pour obtenir la nouvelle image pivotée, faites ceci :

  • faire pivoter ABC autour de A en 2D, il s'agit donc d'une seule rotation d'euler
  • vous vous déplacez dans l'état de rotation de A à B. Pour chaque pixel, vous vous déplacez également de gauche à droite sur la ligne horizontale de l'image originale. Ainsi, si l'image est une image de largeur 100 et de hauteur 50, vous vous déplacerez de A à B en 100 étapes et de A à C en 50 étapes, en traçant 50 lignes de 100 pixels dans la zone formée par ABC dans leur état de rotation.

Cela peut sembler compliqué, mais ce n'est pas le cas. Veuillez consulter ce code C# que j'ai écrit il y a quelque temps : rotoZoomer par moi

Lorsque je dessine, je modifie un peu les pointeurs source pour obtenir un effet de caoutchouc, mais si vous désactivez cela, vous verrez que le code fait tourner l'image sans problème. Bien sûr, sur certains angles, vous obtiendrez une image qui semble légèrement déformée. Le code source contient des commentaires sur ce qui se passe, donc vous devriez être en mesure de saisir les mathématiques/logiques derrière cela facilement.

Si vous préférez Java, j'ai aussi fait une version java une fois, il y a environ 14 ans ;) -> http://www.xs4all.nl/~perseus/zoom/zoom.java

2voto

heeen Points 1836

Notez qu'il existe une autre solution que les matrices de rotation, qui ne perd pas d'informations sur l'image à cause du crénelage. Vous pouvez séparer la rotation de l'image 2D en obliquités et mises à l'échelle qui préservent la qualité de l'image.

Voici une explication plus simple

0voto

Maleev Points 420

Il semble que l'exemple que vous avez fourni soit un noyau de détection des bords. Donc, si vous voulez détecter des bords de différents angles, vous devriez choisir une fonction continue (qui, dans votre cas, pourrait être une gaussienne paramétrée de x1 multiplié par x2) et ensuite la faire tourner selon les formules fournies par kigurai. Ainsi, vous serez en mesure de produire un noyau discret plus efficacement et sans aliasing.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X