Esempio n. 1
0
        /// <summary>
        /// Pour rétrécir une image, on va faire la méthode "inverse" de l'agrandissement.
        /// C'est à dire que pour un pixel de l'image d'arrivée, on va prendre un nombre de pixels de l'image de départ
        /// correspondant à une matrice carrée de pixels de taille le facteur d'agrandissement et partant du pixel en haut à gauche.
        /// Ensuite, on fait la moyenne de toutes les intensités de couleurs (RGB) des pixels et on rentre ces valeurs dans
        /// le pixel de l'image d'arrivée.
        /// </summary>
        /// <param name="facteurRétrécissement">valeur entière correpondant au taux par lequelle on va rétrécir l'image</param>
        public void Retrecir(int facteurRétrécissement)
        {
            //Pour obtenir la hauteur et la largeur de notre matrice d'arrivée, on effectue une division de la hauteur d'origine
            //par le facteur de rétrécissement. Cependant lorsque l'on fait ce genre de division, on renvoie un entier alors que
            //les divisions ne se font pas toujours entre nombres multiples entre eux. On aura donc par la suite un problème
            //d'indexation. Il faut donc aussi prendre en compte le reste de ce quotient car il devient non négligeable dans le
            //cas où le facteur de rétrécissement est très grand. Dans le cas où la hauteur/largeur n'est pas divisible par
            //le facteur de rétrécissement, il faut donc rajouter une ligne/colonne dans l'image d'arrivée. C'est pour cela
            //que dans les formules si dessous on ajoute à la hauteur le facteur- le reste du quotient de la hauteur pour ensuite
            //le diviser par le facteur car cela nous donne un nombre entier correspondant à une unité de plus que le quotient
            //traditionnel de la hauteur par le facteur.
            int Newhauteur = (hauteur + (facteurRétrécissement - hauteur % facteurRétrécissement)) / facteurRétrécissement;
            int Newlargeur = (largeur + (facteurRétrécissement - largeur % facteurRétrécissement)) / facteurRétrécissement;

            Pixel[,] ImageArrivée = new Pixel[Newlargeur, Newhauteur];
            for (int ligne = 0; ligne < Newhauteur; ligne++)
            {
                for (int colonne = 0; colonne < Newlargeur; colonne++)
                {
                    //Comme à chaque fois que l'on change de pixel dans la matrice d'arrivée, on change de matrice de pixel
                    //dans la matrice de départ. Donc lorsque l'on a parcouru une matrice [3,3] de pixels, on passe à la suivante
                    //et on part dès lors de l'index [ligne,colonne*facteurRétrécissement] car on doit se décaler vu que les cases
                    //colonne jusqu'à colonne+facteurRétrécissement-1 auront déjà été utilisées.
                    Pixel pixeltransition = new Pixel(0, 0, 0);
                    //Ici, on doit vérifier que l'on est pas dans "l'extra colonne/ligne" de la nouvelle matrice pour éviter
                    //des erreurs d'indexation
                    int newligne   = ligne * facteurRétrécissement;
                    int newcolonne = colonne * facteurRétrécissement;
                    int endligne   = 0;
                    int endcolonne = 0;
                    if (ligne == Newhauteur - 1)
                    {
                        endligne = hauteur % facteurRétrécissement;
                    }
                    if (colonne == Newlargeur - 1)
                    {
                        endcolonne = largeur % facteurRétrécissement;
                    }

                    for (int i = newligne; i < newligne + facteurRétrécissement - endligne; i++)
                    {
                        for (int j = newcolonne; j < newcolonne + facteurRétrécissement - endcolonne; j++)
                        {
                            pixeltransition.AdditionnerPixels(image[newligne, newcolonne]);
                        }
                    }
                    //Une fois que l'on a additionner les valeurs des couleurs RGB des pixels, il faut diviser ces
                    //3 valeurs par le nombre de pixels étudier afin d'obtenir la moyenne des intensités de couleur
                    int diviseur = facteurRétrécissement * facteurRétrécissement;
                    pixeltransition.DiviserValeurs(diviseur);
                    ImageArrivée[ligne, colonne] = pixeltransition;
                }
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Méthode qui va appliquer le filtre sur l'image grâce à la matrice de convolution choisie à l'aide la méthode ChoisirFiltre.
        /// Pour appliquer le filtre, il faut multiplier chaque case et son contour par la matrice de convolution.
        /// La case et son contour doivent former une matrice carrée de dimensions égales à celles de la matrice de convolution.
        /// Mais il ne s'agit pas d'une multiplication de matrices classiques: on doit multiplier le 'pixel' en haut à gauche de la matrice de l'image
        /// par le nombre en haut à gauche de la matrice de convolution et ainsi de suite jusqu'à la fin.
        /// La somme de tous ses termes donne le nouveau pixel de l'image filtrée. On répète cette opération pour tous les pixels de l'image de départ.
        ///
        /// Cependant plusieurs problèmes se posent:
        /// - le premier est un problème d'index. En effet, si on prend le pixel en haut à gauche de l'image, ce dernier n'a pas
        /// de contour parfait, il lui manque cinq pixels si la matrice de convolution est de dimension 3*3. Il faut donc prendre
        /// chaque case cas par cas pour sélectionner la bonne matrice de contour de pixel.
        /// - le deuxième est que l'on traite des pixels et non des nombres ce qui fait que la multiplication est plus complexe:
        /// il faudrait multiplier chaque composante RGB du pixel par le nombre de la matrice de convolution puis additionner
        /// ces composantes pour donner le pixel final.
        /// </summary>
        public void MatriceFiltre()
        {
            int[,] MatriceConvolution = new int[3, 3];
            int coefficient = 0;//ce coefficient correspond à la somme des termes de la matrice de convolution

            Console.WriteLine("Quel filtre voulez-vous appliquer à votre image?");
            Console.WriteLine("- Flou (Tapez F)");
            Console.WriteLine("- Détection de contour (Tapez D)");
            Console.WriteLine("- Repoussage (Tapez R)");
            Console.WriteLine("- Renforcements des bords (Tapez B)");
            char touche = Convert.ToChar(Console.ReadLine());

            while (touche != 'F' && touche != 'D' && touche != 'R' && touche != 'B')
            {
                Console.WriteLine("Votre saisie est erronée. Veuillez réessayer (Faites attention à bien écrire les lettres en majuscules): ");
                touche = Convert.ToChar(Console.ReadLine());
            }
            if (touche == 'F')
            {
                int[,] matrice     = { { 1, 1, 1 }, { 1, 1, 1 }, { 1, 1, 1 } };
                MatriceConvolution = matrice;
                coefficient        = 9;
            }
            if (touche == 'D')
            {
                int[,] matrice     = { { 0, 1, 0 }, { 1, -4, 1 }, { 0, 1, 0 } };
                MatriceConvolution = matrice;
                coefficient        = 0;
            }
            if (touche == 'R')
            {
                int[,] matrice     = { { -2, -1, 0 }, { -1, 1, 1 }, { 0, 1, 2 } };
                MatriceConvolution = matrice;
                coefficient        = 1;
            }
            if (touche == 'B')
            {
                int[,] matrice     = { { 0, 0, 0 }, { -1, 1, 0 }, { 0, 0, 0 } };
                MatriceConvolution = matrice;
                coefficient        = 0;
            }
            Pixel[,] ImageArrivée    = new Pixel[hauteur, largeur];
            Pixel[,] ImageTransition = image;
            int NbrCases = (hauteur / 2) + 1;//nombre de lignes/colonnes après le point central de la matrice de convolution

            //On parcourt chaque pixels de l'image avec la double boucle for
            for (int ligne = 0; ligne < hauteur; ligne++)
            {
                for (int colonne = 0; colonne < largeur; colonne++)
                {
                    Pixel pixeltransition      = new Pixel(0, 0, 0);
                    int   décalageLigneFin     = 0;
                    int   décalageLigneDébut   = 0;
                    int   décalageColonneFin   = 0;
                    int   décalageColonneDébut = 0;
                    //On veut savoir si les cases de la matrice de convolution sont bien dans la matrice que l'on veut filtrer
                    if (ligne - NbrCases < 0)
                    //si le numéro de la ligne moins NbrCases est inférieur à 0, on est hors-index au dessus de la matrice.
                    //Il faut donc redéfinir la ligne d'où l'on commence la double itération pour faire la multiplication.
                    {
                        décalageLigneDébut = ligne + NbrCases;
                    }
                    if (ligne + NbrCases > hauteur - 1)//De même si la ligne + NbrCases est supérieure à la hauteur -1 de la matrice
                    {
                        décalageLigneFin = ligne - (hauteur - 1) + NbrCases;
                    }
                    if (colonne - NbrCases < 0)
                    {
                        décalageColonneDébut = colonne + NbrCases;
                    }
                    if (colonne + NbrCases > largeur - 1)
                    {
                        décalageColonneFin = colonne - (largeur - 1) + NbrCases;
                    }
                    //on doit déterminer les coordonnées (lignes et colonnes) du début de l'itération pour la multiplication
                    int newligne   = ligne - NbrCases;
                    int newcolonne = colonne - NbrCases;
                    for (int i = newligne + décalageLigneDébut; i < newligne + MatriceConvolution.GetLength(0) - décalageLigneFin; i++)
                    {
                        for (int j = newcolonne + décalageColonneDébut; j < newcolonne + MatriceConvolution.GetLength(1) - décalageColonneFin; j++)
                        {
                            // d'abord on fait la multiplication de du pixel de la matrice de convolution avec le pixel de l'image
                            image[i, j].MultiplierValeurs(MatriceConvolution[i - newligne, j - newcolonne]);
                            // Ensuite on additionne la valeur obtenue avec le/les pixels précédents
                            pixeltransition.AdditionnerPixels(image[i, j]);
                            // Pour ne pas modifier les pixels de l'image de départ, on égalise image[i,j] avec l'image de transition [i,j]
                            image[i, j] = ImageTransition[i, j];
                        }
                    }
                    //On divise le pixel de transition final (après avoir fait la somme de tous les produits) pour ne pas dépasser 255 ou 0
                    pixeltransition.DiviserValeurs(coefficient);
                    //On donne la valeur du pixel de transition final au pixel de l'image d'arrivée
                    ImageArrivée[ligne, colonne] = pixeltransition;
                }
            }
        }