Exemplo n.º 1
0
 public ArtGenerator(Settings settings, VectorOfVectorOfPoint objects)
 {
     this.settings = settings;
     this.objects  = objects;
     randomGen     = new Random(settings.Seed);
     gausRandomGen = new GaussianRandom(settings.Seed);
 }
        private void Generator_DoWork(object sender, DoWorkEventArgs e)
        {
            DataPass data = (DataPass)e.Argument;
            //e.Result = result;
            Random         randomGen     = new Random(data.settings.Seed);;
            GaussianRandom gausRandomGen = new GaussianRandom(data.settings.Seed);

            Dictionary <String, Detector[]> detectors = new Dictionary <string, Detector[]>();

            //Generate detectors
            foreach (String currentImage in data.inputData.Keys)
            {
                detectors.Add(currentImage, new Detector[data.settings.NumberOfNegativeDetectors]);

                for (int i = 0; i < data.settings.NumberOfNegativeDetectors; i++)
                {
                    int  attempts = 0;
                    bool found    = false;
                    while (!found && attempts < 10)
                    {
                        attempts++; // To prevent infinite loop
                        //TODO (Anthony): Width and height should be individual per image
                        int randomX = randomGen.Next(0, data.settings.Width);
                        int randomY = randomGen.Next(0, data.settings.Height);
                        //TODO (Anthony): Setting perhaps?
                        int      radius       = randomGen.Next(10, 50);
                        int      doubleRadius = radius * radius;
                        Detector newDetector  = new Detector(randomX, randomY, radius);

                        int numDetectSelf = 0;
                        //check for collisions with points in each image

                        foreach (System.Drawing.Point[] currentObjectList in data.inputData[currentImage].ToArrayOfArray()) // loop over each object in image
                        {
                            foreach (System.Drawing.Point point in currentObjectList)                                       // loop over each point
                            {
                                //check if detect self
                                if (Math.Pow(point.X - randomX, 2) + Math.Pow(point.Y - randomY, 2) < doubleRadius)
                                {
                                    numDetectSelf++;
                                }
                            }
                        }
                        //TODO (Anthony): Detting for maximum self detection
                        if (numDetectSelf < 10)
                        {
                            found = true;
                            detectors[currentImage][i] = newDetector;
                        }

                        /*
                         * //check for overlap with other detectors
                         * for (int k = 0; k < i;k++)
                         * {
                         *
                         * }
                         */
                    }
                }
            }

            //start generation and mutation

            //Step 1: generate initial
            //Step 2: mutate according to affinities
            //Step 3: calculate affinities
            //Step 4: Select best
            //Step 5: go to step 2 and repeat

            BoundBox[] sizes = new BoundBox[data.objects.Size];
            for (int i = 0; i < sizes.Length; i++)
            {
                sizes[i] = ImageManipulation.getBoundBox(data.objects[i]);
            }


            int numImagesClones = 20;
            //list of integer and vector of vector of points, where int is the affinities and VectorOfVectorOfPoint is each objects in scene
            List <Tuple <int, Emgu.CV.Util.VectorOfVectorOfPoint> > imagesObjects = new List <Tuple <int, Emgu.CV.Util.VectorOfVectorOfPoint> >();

            Emgu.CV.Util.VectorOfPoint[] objects = new Emgu.CV.Util.VectorOfPoint[data.settings.NumberOfObjects];
            for (int k = 0; k < numImagesClones; k++)
            {
                //generate image with affinity of zero
                int affinity = 0;
                for (int i = 0; i < data.settings.NumberOfObjects; i++)
                {
                    int objectIndex = randomGen.Next(data.objects.Size);
                    int shiftX      = Math.Max(0, data.settings.Width - sizes[objectIndex].Width);
                    int shiftY      = Math.Max(0, data.settings.Height - sizes[objectIndex].Height);
                    objects[i] = ImageManipulation.offsetContour(data.objects[objectIndex], new System.Drawing.Point(randomGen.Next(shiftX), randomGen.Next(shiftY)));
                }
                imagesObjects.Add(new Tuple <int, Emgu.CV.Util.VectorOfVectorOfPoint>(affinity, new Emgu.CV.Util.VectorOfVectorOfPoint(objects)));
            }

            int  maxIterations = 5;
            int  loopCounter   = 0;
            bool perfected     = false;

            while (loopCounter < maxIterations && !perfected)
            {
                loopCounter++;
                //calculate affinities
                for (int i = 0; i < numImagesClones; i++) // loop through each clone
                {
                    int affinity = 0;
                    //TODO (Anthony): Check affinities for all images
                    for (int k = 0; k < imagesObjects[i].Item2.Size; k++)        // loop through each object
                    {
                        for (int f = 0; f < imagesObjects[i].Item2[k].Size; f++) // loop through each point
                        {
                            foreach (Detector[] detectorsOfEachImage in detectors.Values)
                            {
                                for (int c = 0; c < detectorsOfEachImage.Length; c++)
                                {
                                    affinity += checkDistance(detectorsOfEachImage[c], imagesObjects[i].Item2[k][f]);
                                }
                            }
                        }
                    }
                    imagesObjects[i] = new Tuple <int, Emgu.CV.Util.VectorOfVectorOfPoint>(affinity, imagesObjects[i].Item2);
                }
                //mutate according to affinity
                for (int i = 0; i < numImagesClones; i++) // loop through each clone
                {
                    int affinity = imagesObjects[i].Item1;
                    //TODO (Anthony): Check affinities for all images
                    for (int k = 0; k < imagesObjects[i].Item2.Size; k++)        // loop through each object
                    {
                        for (int f = 0; f < imagesObjects[i].Item2[k].Size; f++) // loop through each point
                        {
                            int x = (int)(gausRandomGen.NextValue() * affinity);
                            int y = (int)(gausRandomGen.NextValue() * affinity);
                            imagesObjects[i].Item2[k][f].Offset(x, y);
                        }
                    }
                }
                //replace bad ones
            }

            e.Result = imagesObjects[randomGen.Next(numImagesClones)].Item2;
        }