예제 #1
0
        Dictionary <int, List <List <int> > > OperationsGenerator(int sommeMin, int sommeMax, int valUnitaireMax)
        {
            //génère toutes les sommes possibles (uniques, valeurs croissantes)
            Dictionary <string, List <int> > val = new Dictionary <string, List <int> >();

            for (int i = 0; i < valUnitaireMax + 1; i++)
            {
                for (int j = 0; j < valUnitaireMax + 1; j++)
                {
                    for (int k = 0; k < valUnitaireMax + 1; k++)
                    {
                        for (int l = 0; l < valUnitaireMax + 1; l++)
                        {
                            if (i <= j && j <= k && k <= l)
                            {
                                string clef = "";
                                if (i > 0)
                                {
                                    clef += $"{i},";
                                }
                                if (j > 0)
                                {
                                    clef += $"{j},";
                                }
                                if (k > 0)
                                {
                                    clef += $"{k},";
                                }
                                if (l > 0)
                                {
                                    clef += $"{l}";
                                }

                                if (i + j + k + l >= sommeMin && i + j + k + l <= sommeMax)
                                {
                                    List <int> entiers = new List <int>();

                                    if (i > 0)
                                    {
                                        entiers = new List <int>()
                                        {
                                            i, j, k, l
                                        }
                                    }
                                    ;
                                    else if (j > 0)
                                    {
                                        entiers = new List <int>()
                                        {
                                            j, k, l
                                        }
                                    }
                                    ;
                                    else if (k > 0)
                                    {
                                        entiers = new List <int>()
                                        {
                                            k, l
                                        }
                                    }
                                    ;
                                    else if (l > 0)
                                    {
                                        entiers = new List <int>()
                                        {
                                            l
                                        }
                                    }
                                    ;

                                    if (!val.ContainsKey(clef))
                                    {
                                        // 1 seul fois 1
                                        int nbr1 = 0;
                                        for (int ent = 0; ent < entiers.Count; ent++)
                                        {
                                            if (entiers[ent] == 1)
                                            {
                                                nbr1++;
                                            }
                                        }

                                        if (nbr1 < 2)
                                        {
                                            val.Add(clef, entiers);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            //rangement par somme
            Dictionary <int, List <List <int> > > operations = new Dictionary <int, List <List <int> > >();

            foreach (List <int> item in val.Values)
            {
                int somme = item.Sum();
                if (!operations.ContainsKey(somme))
                {
                    operations.Add(somme, new List <List <int> >());
                }
                operations[somme].Add(item);
            }
            return(operations);
        }

        Image <Rgba, byte> DrawRings(int D_ext, int separation_epaisseur, MCvScalar couleur, MCvScalar couleur_arriereplan,
                                     List <int> nbrBoutonsParAnneau, double angleDegres_OrigineParRapportAX, ref List <Bouton> boutons)
        {
            int nbrAnneaux = nbrBoutonsParAnneau.Count;

            //création de l'image
            Image <Rgba, byte> iMAGE = new Image <Rgba, byte>(D_ext, D_ext);
            int rows = iMAGE.Rows;
            int cols = iMAGE.Cols;

            //centre de l'image
            System.Drawing.Point centre = new System.Drawing.Point(cols / 2, rows / 2);

            //créations des rayons externe/interne de chaque anneau
            List <Tuple <int, int> > rayons = new List <Tuple <int, int> >();
            int rprecedent = 0;
            int epaisseur  = (int)(cols / 2 * 1f / nbrAnneaux);

            for (int i = nbrAnneaux - 1; i >= 0; i--)
            {
                int externe = (rayons.Count == 0) ? cols / 2 : rprecedent;
                int interne = (rayons.Count == nbrAnneaux - 1) ? 0 : externe - epaisseur;
                rayons.Add(new Tuple <int, int>(externe, interne));
                rprecedent = interne;
            }

            //dessine les anneaux puis y dessine les séparations
            for (int i = 0; i < nbrAnneaux; i++)
            {
                //cercle extèrieur
                CvInvoke.Circle(iMAGE, centre, rayons[i].Item1 - separation_epaisseur * 2, couleur, -1);

                //cercle intérieur (/!\ attention écrase tout l'intérieur !)
                if (rayons[i].Item2 > 0)
                {
                    CvInvoke.Circle(iMAGE, centre, rayons[i].Item2, couleur_arriereplan, -1);
                }

                //dessine les séparations
                if (nbrBoutonsParAnneau[nbrAnneaux - 1 - i] > 1)
                {
                    DrawSeparator(iMAGE,
                                  nbrBoutonsParAnneau[nbrAnneaux - 1 - i],
                                  angleDegres_OrigineParRapportAX,
                                  rayons[i].Item2,
                                  rayons[i].Item1 - separation_epaisseur * 2,
                                  rows / 2,
                                  cols / 2,
                                  couleur_arriereplan,
                                  separation_epaisseur,
                                  ref boutons);
                }

                #region ------------vieux code commenté
                //int rayon_0 = cols / 2;
                //int epaisseur_1 = (int)(rayon_0 * 1f / 3);
                //int rayon_1 = rayon_0 - epaisseur_1;

                //int epaisseur_2 = (int)(rayon_0 * 1f / 3);
                //int rayon_2 = rayon_1 - epaisseur_2;


                //double angle_OrigineParRapportAX = -90;

                ////cercle extèrieur
                //CvInvoke.Circle(masque, centre, rayon_0, couleur, -1);
                //CvInvoke.Circle(masque, centre, rayon_1, couleur_arriereplan, -1);
                //DrawSeparator(masque,
                //    10,
                //            angle_OrigineParRapportAX,
                //            rayon_1,
                //            rayon_0,
                //            rayon_0,
                //            rayon_0,
                //            couleur_arriereplan,
                //            separation_epaisseur);

                ////cercle intermédiaire
                //CvInvoke.Circle(masque, centre, rayon_1 - separation_epaisseur * 2, couleur, -1);
                //CvInvoke.Circle(masque, centre, rayon_2, couleur_arriereplan, -1);
                //DrawSeparator(masque,
                //    6,
                //            angle_OrigineParRapportAX,
                //            rayon_2,
                //            rayon_1 - separation_epaisseur * 2,
                //            rayon_0,
                //            rayon_0,
                //            couleur_arriereplan,
                //            separation_epaisseur);

                ////disque central
                //CvInvoke.Circle(masque, centre, rayon_2 - separation_epaisseur * 2, couleur, -1);
                //DrawSeparator(masque,
                //    3,
                //            angle_OrigineParRapportAX,
                //            0,
                //            rayon_2 - separation_epaisseur * 2,
                //            rayon_0,
                //            rayon_0,
                //            couleur_arriereplan,
                //            separation_epaisseur);
                #endregion
            }
            return(iMAGE);
        }

        void DrawSeparator(Image <Rgba, byte> masque, int nombre_de_part, double angle_OrigineParRapportAX,
                           int rayon_int, int rayon_ext, int RX, int RY, MCvScalar T, int epaisseur_trait,
                           ref List <Bouton> boutons)
        {
            double angle = 360 / nombre_de_part;
            Bouton bouton;
            double alpha, alpha_prec = angle_OrigineParRapportAX;

            for (int i = 0; i < nombre_de_part; i++)
            {
                alpha = angle_OrigineParRapportAX + angle * i;
                double alpha_rad = alpha / 180 * Math.PI;
                double X, Y; //repère sur cercle
                int    x, y; //repère image

                X = rayon_ext * Math.Cos(alpha_rad);
                Y = rayon_ext * Math.Sin(alpha_rad);
                x = (int)(X + RX);
                y = (int)(Y + RY);
                System.Drawing.Point P2 = new System.Drawing.Point(x, y);

                X = rayon_int * Math.Cos(alpha_rad);
                Y = rayon_int * Math.Sin(alpha_rad);
                x = (int)(X + RX);
                y = (int)(Y + RY);
                System.Drawing.Point P1 = new System.Drawing.Point(x, y);

                CvInvoke.Line(masque, P1, P2, T, epaisseur_trait);

                if (i > 0)
                {
                    bouton = new Bouton(new System.Drawing.Point(RX, RY), rayon_int, rayon_ext, alpha, alpha_prec);
                    boutons.Add(bouton);
                }
                alpha_prec = alpha;
            }

            bouton = new Bouton(new System.Drawing.Point(RX, RY), rayon_int, rayon_ext, alpha_prec - 360, angle_OrigineParRapportAX);
            boutons.Add(bouton);
        }

        #endregion

        #region IHM
        void lv_sel_change(object sender, SelectionChangedEventArgs e)
        {
            if (lv.SelectedItem != null)
            {
                string clef = lv.SelectedItem.ToString();
                if (propositions.ContainsKey(clef))
                {
                    LV.SelectedItem = propositions[lv.SelectedItem.ToString()].pUC;
                }
            }
        }
예제 #2
0
        void Compute(Dictionary <int, List <List <int> > > operations,
                     int diametre, int epaisseur,
                     MCvScalar couleurFond, List <MCvScalar> couleurs)
        {
            int couleurindex = -1;

            //draw operations
            foreach (int x in operations.Keys)
            {
                couleurindex++;
                if (couleurindex == couleurs.Count)
                {
                    couleurindex = 0;
                }
                MCvScalar couleur = couleurs[couleurindex];

                Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background,
                                                           new Action(() =>
                {
                    TextBlock tb = new TextBlock()
                    {
                        Text       = x.ToString(),
                        Foreground = new SolidColorBrush(Color.FromArgb((byte)couleur.V3,
                                                                        (byte)couleur.V2,
                                                                        (byte)couleur.V1,
                                                                        (byte)couleur.V0))
                    };
                    Viewbox vb = new Viewbox()
                    {
                        Child = tb, Height = diametre, Width = diametre
                    };
                    LV.Items.Add(vb);
                }));

                foreach (List <int> entiers in operations[x])
                {
                    string        titre   = Proposition.SetSignature(entiers);
                    List <Bouton> boutons = new List <Bouton>();

                    Emgu.CV.Image <Rgba, byte> image = DrawRings(diametre,
                                                                 epaisseur,
                                                                 couleur,
                                                                 couleurFond,
                                                                 entiers,
                                                                 angleDegres_OrigineParRapportAX,
                                                                 ref boutons
                                                                 );

                    Image <Gray, byte> gray    = new Image <Gray, byte>(image.Width, image.Height);
                    Image <Gray, byte> binaire = new Image <Gray, byte>(image.Width, image.Height);

                    //Alpha to WHITE
                    SETAlphaPixelToColorPixel(image, new MCvScalar(255, 255, 255, 255));

                    CvInvoke.CvtColor(image.Mat, gray, ColorConversion.Bgra2Gray);     //color to grayscale
                    CvInvoke.Threshold(gray, binaire, 100, 255, ThresholdType.Binary); //Binary
                    CvInvoke.BitwiseNot(binaire, binaire);                             //Logical NOT

                    Emgu.CV.Util.VectorOfVectorOfPoint contours = new Emgu.CV.Util.VectorOfVectorOfPoint();
                    Mat hierarchy = new Mat();

                    CvInvoke.FindContours(binaire, contours, hierarchy, RetrType.External, ChainApproxMethod.ChainApproxSimple);
                    //CvInvoke.DrawContours(image.Mat, contours, -1, new MCvScalar(0, 255, 0));

                    //WHITE to Alpha
                    SETColorPixelToAlphaPixel(image, new MCvScalar(255, 255, 255, 255));

                    for (int b = 0; b < boutons.Count; b++)
                    {
                        Bouton bouton = boutons[b];

                        CvInvoke.Circle(image.Mat, bouton.barycentre, 2, new MCvScalar(0, 255, 0, 255), -1);

                        //Quel contour est concerné ?
                        int contour_index = 0;
                        for (contour_index = 0; contour_index < contours.Size; contour_index++)
                        {
                            double result = CvInvoke.PointPolygonTest(contours[contour_index], bouton.barycentre, false);
                            if (result > 0) // >0 : inside
                            {
                                break;
                            }
                        }

                        Mat btn = new Mat(image.Size, DepthType.Cv8U, 1);
                        //colorie tout (-1) l'intérieur en vert (0,255,0,255) du contour n°1
                        CvInvoke.DrawContours(btn, contours, contour_index, new MCvScalar(100), -1);

                        //optimisation sur 2 paramètres :
                        //- p position sur l'axe centre du cercle, barycentre (position comprise entre rayon max et rayon min)
                        //- t taille de l'icone
                        //La meilleure solution p aura t maximum

                        // first values
                        // p0 = barycentre (parfait ou trop prêt du centre)
                        // t0 = 1
                        // test : est ce qu'aucun pixels du carré n'est vide (on a une image vide avec "seulement" le bouton de dessiné)
                        // ==> on augmente t
                        // quand tmax atteint pour p donné, on change de p, avec p compris entre p0 et p sur axe avec D = rayon_ext - t

                        // puis dichtomie pour p en maximisant t à chaque essai.



                        int cote_px = 10;

                        List <int>               icon_cote_px_test = new List <int>();
                        System.Drawing.Size      icon_size;
                        System.Drawing.Rectangle rect = new System.Drawing.Rectangle();
                        System.Drawing.Point     icon_center;
                        ////int cote_px_retenu = 100;
                        //while (!icon_cote_px_test.Contains(cote_px))
                        //{
                        //    icon_cote_px_test.Add(cote_px);

                        //    icon_size = new System.Drawing.Size(cote_px, cote_px);
                        //    icon_center = new System.Drawing.Point(btn.barycentre.X - cote_px / 2, btn.barycentre.Y - cote_px / 2);
                        //    rect = new System.Drawing.Rectangle(icon_center, icon_size);

                        //    int area_theo = cote_px * cote_px;
                        //    Mat ROI = new Mat(image.Mat, rect);
                        //    int area_real = CvInvoke.CountNonZero(ROI);
                        //    int pixelvide = area_theo - area_real;
                        //    Console.WriteLine(cote_px + " ==> " + pixelvide);
                        //    if (pixelvide > 0)
                        //        cote_px--;
                        //    if (pixelvide <= 0)
                        //        cote_px++;
                        //}

                        //cote_px = icon_cote_px_test[icon_cote_px_test.Count - 2];
                        //icon_size = new System.Drawing.Size(cote_px, cote_px);
                        //icon_center = new System.Drawing.Point(btn.barycentre.X - cote_px / 2, btn.barycentre.Y - cote_px / 2);
                        //rect = new System.Drawing.Rectangle(icon_center, icon_size);

                        //CvInvoke.Rectangle(image.Mat,
                        //    rect,
                        //    new MCvScalar(0, 0, 0, 255));
                    }



                    //for (int i = 0; i < contours.Size; i++)
                    //{
                    //    Mat btn = new Mat(image.Size, DepthType.Cv8U, 1);
                    //    //colorie tout (-1) l'intérieur en vert (0,255,0,255) du contour n°1
                    //    CvInvoke.DrawContours(btn, contours, i, new MCvScalar(100), -1);



                    //    //CHANGER : au lieu du centre de masse, prendre l'axe "parfait" = axe entre 2 séparations
                    //    //pourquoi pas commencer par le point sur cet axe le plus prêt du barycentre
                    //    //puis se balader sur l'axe



                    //    //barycentre (centre de masse)
                    //    MCvMoments mom = CvInvoke.Moments(contours[i]);
                    //    System.Drawing.Point center_of_mass = new System.Drawing.Point((int)((float)mom.M10 / mom.M00), (int)((float)mom.M01 / mom.M00));
                    //    CvInvoke.Circle(image.Mat, center_of_mass, 2, new MCvScalar(0, 255, 0, 255), -1);

                    //    int cote_px = 10;

                    //    List<int> icon_cote_px_test = new List<int>();
                    //    System.Drawing.Size icon_size;
                    //    System.Drawing.Rectangle rect = new System.Drawing.Rectangle();
                    //    System.Drawing.Point icon_center;
                    //    //int cote_px_retenu = 100;
                    //    while (!icon_cote_px_test.Contains(cote_px))
                    //    {
                    //        icon_cote_px_test.Add(cote_px);

                    //        icon_size = new System.Drawing.Size(cote_px, cote_px);
                    //        icon_center = new System.Drawing.Point(center_of_mass.X - cote_px / 2, center_of_mass.Y - cote_px / 2);
                    //        rect = new System.Drawing.Rectangle(icon_center, icon_size);

                    //        int area_theo = cote_px * cote_px;
                    //        Mat ROI = new Mat(btn, rect);
                    //        int area_real = CvInvoke.CountNonZero(ROI);
                    //        int pixelvide = area_theo - area_real;
                    //        Console.WriteLine(cote_px + " ==> " + pixelvide);
                    //        if (pixelvide > 0)
                    //            cote_px--;
                    //        if (pixelvide <= 0)
                    //            cote_px++;
                    //    }

                    //    cote_px = icon_cote_px_test[icon_cote_px_test.Count - 2];
                    //    icon_size = new System.Drawing.Size(cote_px, cote_px);
                    //    icon_center = new System.Drawing.Point(center_of_mass.X - cote_px / 2, center_of_mass.Y - cote_px / 2);
                    //    rect = new System.Drawing.Rectangle(icon_center, icon_size);

                    //    CvInvoke.Rectangle(image.Mat,
                    //        rect,
                    //        new MCvScalar(0, 0, 0, 255));



                    //    //int nbr = 100000;
                    //    //while (nbr > 50)
                    //    //{
                    //    //    CvInvoke.Erode(btn_prec, btn, element, new System.Drawing.Point(-1, -1), 1, BorderType.Reflect, default(MCvScalar));
                    //    //    nbr = CvInvoke.CountNonZero(btn);
                    //    //    if (nbr > 50)
                    //    //        btn_prec = btn;
                    //    //    //Console.WriteLine(nbr);
                    //    //    //Mat btn_cpy = new Mat();
                    //    //    //btn.CopyTo(btn_cpy);
                    //    //    //Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background,
                    //    //    //    new Action(() =>
                    //    //    //    {
                    //    //    //        Proposition p = new Proposition(entiers, btn_cpy, titre, this);
                    //    //    //        LV.Items.Add(p.pUC);
                    //    //    //    }));
                    //    //}
                    //    //btn = btn_prec;

                    //    //Emgu.CV.Util.VectorOfVectorOfPoint contourBouton = new Emgu.CV.Util.VectorOfVectorOfPoint();
                    //    //Mat hierarchyBouton = new Mat();

                    //    //CvInvoke.FindContours(btn, contourBouton, hierarchyBouton, RetrType.External, ChainApproxMethod.ChainApproxSimple);
                    //    //System.Drawing.Rectangle rect = CvInvoke.BoundingRectangle(contourBouton[0]);


                    //    //System.Drawing.Point centre = new System.Drawing.Point(rect.X + rect.Width / 2, rect.Y + rect.Height / 2);
                    //    //CvInvoke.Circle(image.Mat, geometric_center, 2, new MCvScalar(0, 0, 255, 255), -1);


                    //}



                    #region BoundingBox
                    //Dictionary<int, double> dict = new Dictionary<int, double>();
                    //for (int i = 0; i < contours.Size; i++)
                    //{
                    //    double aera = CvInvoke.ContourArea(contours[i]);
                    //    System.Drawing.Rectangle rect = CvInvoke.BoundingRectangle(contours[i]);

                    //    dict.Add(i, aera);
                    //}

                    //foreach (var it in dict)//item)
                    //{
                    //    int key = int.Parse(it.Key.ToString());
                    //    System.Drawing.Rectangle rect = CvInvoke.BoundingRectangle(contours[key]);
                    //    CvInvoke.Rectangle(image.Mat, rect, new MCvScalar(0, 0, 255), 1);
                    //}
                    #endregion

                    //ajout de l'image dans l'interface
                    Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background,
                                                               new Action(() =>
                    {
                        //Proposition_UC pUC = AddImageToIHM();
                        Proposition p = new Proposition(entiers, image.Mat, titre, this, boutons);
                        propositions.Add(titre, p);
                        LV.Items.Add(p.pUC);
                    }));
                }
            }
        }