コード例 #1
0
        public override double Process(Segmentation s1, Segmentation s2)
        {
            if (s1 == null || s2 == null)
                return 0;
            if (s1 == s2)
                return 1;
            double result = 0;
            //En cls van a estar los subconjuntos comunes en las dos particiones concatenados los nombres de los clusters por un &, ademas se guarda la cantidad de elementos del subconjunto.
            Dictionary<string, long> cls = new Dictionary<string, long>();
            for (int i = 0; i < s1.Labels.Length; i++)
            {
                if (cls.ContainsKey(s1.Labels[i] + "&" + s2.Labels[i]))
                    cls[s1.Labels[i] + "&" + s2.Labels[i]] += 1;
                else
                    cls.Add(s1.Labels[i] + "&" + s2.Labels[i], 1);
            }

            string[] aux;
            //Tamanno de los cluster que contienen al subconjunto en P1 y P2 respectivamente.
            int c1 = 0, c2 = 0;
            //Calcular para cada subconjunto el valor de similaridad asociado.
            foreach (string str in cls.Keys)
            {
                aux = str.Split('&');
                c1 = s1.Clusters[int.Parse(aux[0])].Count;
                c2 = s2.Clusters[int.Parse(aux[1])].Count;
                result += similarity(cls[str], c1, c2);
            }

            return result / Math.Sqrt(ComputeNorm(s1) * ComputeNorm(s2));
        }
コード例 #2
0
 private double ComputeNorm(Segmentation s)
 {
     double norm = 0;
     foreach (int str in s.Clusters.Keys)
         norm += similarity(s.Clusters[str].Count, s.Clusters[str].Count, s.Clusters[str].Count);
     return norm;
 }
コード例 #3
0
        //Aqui estoy asumiendo q ya la segmentacion inicial tiene k clusters, con k el valor q quiero q tengan todas.
        public Segmentation GetNeighborKFIJO(SuperPixelGraph spg)
        {
            int[] newLabels = new int[Labels.Length];
            for (int i = 0; i < Labels.Length; i++)
                newLabels[i] = Labels[i];
            Random r = new Random();

            //posicion del objeto q voy a cambiar de region
            int pos = 0;
            do
            {
                pos = r.Next(0, Labels.Length);
            }
            while (this.Clusters[Labels[pos]].Count <= 1);

            //numero de la nueva region a seleccionar entre las posibles segun el grafo de la imagen
            int reg = r.Next(0, spg.AdjList[pos].Count);

            //este es el superpixel con el q me voy a pegar en el mismo cluster.
            int sp = spg.AdjList[pos][reg];

            //Esta es la etiqueta del cluster al q voy a ser asignado.
            int newL = Labels[sp];

            //Tiene el problema de q si es la misma etiqueta...estoy generando la misma segmentacion de nuevo!!
            newLabels[pos] = newL;
            Segmentation result = new Segmentation(newLabels);
            return result;
        }
コード例 #4
0
        public Segmentation GetNeighbor(SuperPixelGraph spg)
        {
            int[] newLabels = new int[Labels.Length];
            for (int i = 0; i < Labels.Length; i++)
                newLabels[i] = Labels[i];
            Random r = new Random();

            //posicion del objeto q voy a cambiar de region
            int pos = r.Next(0, Labels.Length-1);  //le meti el -1..analizar

            //numero de la nueva region a seleccionar entre las posibles segun el grafo de la imagen
            int reg = r.Next(0, spg.AdjList[pos].Count - 1);  //le meti el -1..analizar

            //este es el superpixel con el q me voy a pegar en el mismo cluster.
            int sp = spg.AdjList[pos][reg];

            //Esta es la etiqueta del cluster al q voy a ser asignado.
            int newL = Labels[sp];

            //Si la nueva posicion es la misma, cojo esta posibilidad para poner el elemento en un nuevo cluster donde esta el solo.
            if (newLabels[pos] == newL)
                newLabels[pos] = this.maxLabel + 1;
            else
                newLabels[pos] = newL;
            Segmentation result = new Segmentation(newLabels);
            return result;
        }
コード例 #5
0
        private double MI(Segmentation s1, Segmentation s2)
        {
            double mi = 0;
            double aux = 0;
            Dictionary<string, long> cls = new Dictionary<string, long>();
            for (int i = 0; i < s1.Labels.Length; i++)
            {
                if (cls.ContainsKey(s1.Labels[i] + "&" + s2.Labels[i]))
                    cls[s1.Labels[i] + "&" + s2.Labels[i]] += 1;
                else
                    cls.Add(s1.Labels[i] + "&" + s2.Labels[i], 1);
            }

            //foreach (int cluster in cls.Values)
            //{
            //    aux = (((double)cluster) / ((double)s1.Labels.Length));
            //    if (aux != 0)
            //        mi += aux * Math.Log(aux, 2);
            //}

            foreach (int cS1 in s1.Clusters.Keys)
            {
                foreach (int cS2 in s2.Clusters.Keys)
                {
                    if (cls.ContainsKey(cS1.ToString() + "&" + cS2.ToString()))
                    {
                        aux = (((double)cls[cS1.ToString() + "&" + cS2.ToString()]) / ((double)s1.Labels.Length));
                        if (aux != 0)
                            mi += aux * Math.Log((aux * s1.Labels.Length * s1.Labels.Length) / ((double)(s1.Clusters[cS1].Count) * ((double)s2.Clusters[cS2].Count)), 2);
                    }
                }
            }
            return mi;
        }
コード例 #6
0
 private double Entropy(Segmentation s)
 {
     double entropy = 0;
     double aux = 0;
     foreach (int i in s.Clusters.Keys)
     {
         aux = (((double)s.Clusters[i].Count) / ((double)s.Labels.Length));
         entropy += aux * Math.Log(aux, 2);
     }
     return -1 * entropy;
 }
コード例 #7
0
 //Esto convierte el objeto segmentacion en la real segmantacion haciendo el proceso contrario al calculo de los superpixels.
 //El nuevo objeto segmentacion es mucho mas grande....la cardinalidad es la cantidad de pixels y no la cantidad de superpixels.
 private Segmentation GetSegmentationResult(Segmentation best)
 {
     int[] result = new int[this.prob.SuperPixelMatrix.Length];
     for (int i = 0; i < this.prob.SuperPixelMatrix.GetLength(0); i++)
     {
         for (int j = 0; j < this.prob.SuperPixelMatrix.GetLength(1); j++)
         {
             int sp = this.prob.SuperPixelMatrix[i, j];
             result[i * this.prob.SuperPixelMatrix.GetLength(1) + j] = best.Labels[sp];
         }
     }
     return new Segmentation(result);
 }
コード例 #8
0
 public abstract double Process(Segmentation s1, Segmentation s2);
コード例 #9
0
        //Evaluo la segmentacion con las medidas RandIndex, VI and NMI y dejo los resultados en el prob. Evaluo contra el mejor ground-truth y el promedio contra todos.
        private void EvaluateMatrixSegmentation(Segmentation segm)
        {
            RandIndexSegSim rand = new RandIndexSegSim();
            NMISegSim nmi = new NMISegSim();
            VISegSim vi = new VISegSim();

            //Calcular el rand
            double min = double.MaxValue;
            double ave = 0;
            double aux = 0;
            for (int i = 0; i < this.prob.GroundTruths.Count; i++)
            {
                aux = 1 - rand.Process(segm, this.prob.GroundTruths[i]);
                if (aux < min)
                    min = aux;
                ave += aux;
            }
            ave = ave / this.prob.GroundTruths.Count;
            this.prob.Best_RandEvaluation = min;
            this.prob.Ave_RandEvaluation = ave;

            //Calcular NMI
            min = double.MaxValue;
            ave = 0;
            aux = 0;
            for (int i = 0; i < this.prob.GroundTruths.Count; i++)
            {
                aux = 1 - nmi.Process(segm, this.prob.GroundTruths[i]);
                if (aux < min)
                    min = aux;
                ave += aux;
            }
            ave = ave / this.prob.GroundTruths.Count;
            this.prob.Best_NMIEvaluation = min;
            this.prob.Ave_NMIEvaluation = ave;

            //Calcular VI
            min = double.MaxValue;
            ave = 0;
            aux = 0;
            for (int i = 0; i < this.prob.GroundTruths.Count; i++)
            {
                aux = vi.Process(segm, this.prob.GroundTruths[i]);
                if (aux < min)
                    min = aux;
                ave += aux;
            }
            ave = ave / this.prob.GroundTruths.Count;
            this.prob.Best_VIEvaluation = min;
            this.prob.Ave_VIEvaluation = ave;
        }
コード例 #10
0
        //Devuelve la matriz del tamanno de la imagen final con los valores de los pixeles.
        private Bitmap GetFinalSegImage(Segmentation segm)
        {
            int[,] result = new int[this.prob.Image.Height, this.prob.Image.Width];
            for (int i = 0; i < result.GetLength(0); i++)
            {
                for (int j = 0; j < result.GetLength(1); j++)
                {
                    result[i, j] = segm.Labels[i * result.GetLength(1) + j];
                }
            }

            Bitmap image = new Bitmap(this.prob.Image.Width, this.prob.Image.Height, this.prob.Image.PixelFormat);
            BitmapData data = image.LockBits(new Rectangle(0, 0, image.Width, image.Height), ImageLockMode.ReadWrite, image.PixelFormat);
            unsafe
            {
                byte* imgPtr = (byte*)(data.Scan0);

                for (int i = 0; i < data.Height; i++)
                {
                    for (int j = 0; j < data.Width; j++)
                    {
                        imgPtr[0] = colors[Math.Min(67, result[i, j])].R;
                        imgPtr[1] = colors[Math.Min(67, result[i, j])].G;
                        imgPtr[2] = colors[Math.Min(67, result[i, j])].B;

                        imgPtr += 3;
                    }
                    imgPtr += data.Stride - data.Width * 3;
                }

                image.UnlockBits(data);

            }
            return image;
        }
コード例 #11
0
 private double DistConsensus(double[] normWeights, Segmentation seg)
 {
     //Sumo 1 del primer termino y 1 del tercero..solo falta restar el 2do termino de la ecuacion (10) en el paper PR.
     double result = 2;
     for (int i = 0; i < prob.Segmentations.Count; i++)
     {
         result -= 2 * normWeights[i] * rand.Process(seg, prob.Segmentations[i]);
     }
     return result;
 }
コード例 #12
0
 public abstract double Process(Segmentation s1, Segmentation s2);
コード例 #13
0
        //Rand es (n00 + n11) / (n(n-1)/2), pero n00+n01+n10+n11 = n(n-1)/2. Por tanto n00+n11 = n(n-1)/2 - ((n11+n10) + (n11+n01) -2*n11).
        //Hay una forma muy facil de calcular (n11+n10) + (n11+n01) y n11 se calcula en O(n).
        public override double Process(Segmentation s1, Segmentation s2)
        {
            double rand = 0;
            double t = 0;
            double n11_n01 = 0, n11_n10 = 0, n11=0;
            foreach (List<int> cluster in s1.Clusters.Values)
            {
                t = cluster.Count;
                n11_n10 += t * (t-1) / 2;
            }

            foreach (List<int> cluster in s2.Clusters.Values)
            {
                t = cluster.Count;
                n11_n01 += t * (t - 1) / 2;
            }

            Dictionary<string, int> cls = new Dictionary<string, int>();
            for (int i = 0; i < s1.Labels.Length; i++)
            {
                if (cls.ContainsKey(s1.Labels[i] + "&" + s2.Labels[i]))
                    cls[s1.Labels[i] + "&" + s2.Labels[i]] += 1;
                else
                    cls.Add(s1.Labels[i] + "&" + s2.Labels[i], 1);
            }

            foreach (int cluster in cls.Values)
                if (cluster >= 2)
                {
                    t = cluster;
                    n11 += t * (t - 1) / 2;
                }

                t = s1.Labels.Length;
                double pc = t * (t - 1) / 2;

            rand = ((double)(pc - n11_n10 - n11_n01 + 2*n11)) / ((double)pc);
            return rand;
        }
コード例 #14
0
        //Devuelve una nueva segmentacion que se forma al unir "clusCount" pares de clusters en la segmentacion actual.
        public Segmentation Join(int clusCount, SuperPixelGraph spg)
        {
            int[] newLabels = new int[Labels.Length];
            for (int i = 0; i < Labels.Length; i++)
                newLabels[i] = Labels[i];
            Random r = new Random();

            for (int i = 0; i < clusCount; i++)
            {
                int pos = r.Next(0, Labels.Length);
                int reg = r.Next(0, spg.AdjList[pos].Count);
                int sp = spg.AdjList[pos][reg];
                int newL = newLabels[sp];

                int value = newLabels[pos];
                for (int j = 0; j < newLabels.Length; j++)
                {
                    if (newLabels[j] == value)
                        newLabels[j] = newL;
                }
            }
            Segmentation result = new Segmentation(newLabels);
            return result;
        }
コード例 #15
0
        private Segmentation SimulatedAnnealing(double[] normWeights, Segmentation s0, int maxIter)
        {
            Segmentation current = s0;
            Segmentation next = s0;
            Segmentation best = s0;
            double e0 = DistConsensus(normWeights, s0);
            double eCurrent = e0;
            double eNext = e0;
            double eBest = e0;
            int r = 0;
            double temp = 0.0001428;
            Random random = new Random();

            //int[] l0 = new int[s0.Labels.Length];
            //int[] l1 = new int[s0.Labels.Length];
            //for (int i = 0; i < l0.Length; i++)
            //    l0[i] = i;

            //Segmentation seg0 = new Segmentation(l0);
            //Segmentation seg1 = new Segmentation(l1);
            //double au0 = DistConsensus(normWeights, seg0);
            //double au1 = DistConsensus(normWeights, seg1);

            while (r < maxIter)
            {
                next = current.GetNeighbor(prob.SPGraph);
                eNext = DistConsensus(normWeights, next);
                if (eNext < eBest)
                {
                    best = next;
                    eBest = eNext;
                }
                if (Math.Exp(-1 * (eNext - eBest) / temp) > random.NextDouble())
                {
                    current = next;
                    eCurrent = eNext;
                }

                if (r > (maxIter * 4) / 5 && r < (maxIter * 9) / 10)
                    temp = temp * 1.002;
                r++;

            }

            this.prob.DistToConsensus = eBest;
            return best;
        }
コード例 #16
0
        //Devuelve una nueva segmentacion que se forma al separar "clusCount" clusters (en dos nuevos clusters) en la segmentacion actual.
        public Segmentation Split(int clusCount, SuperPixelGraph spg)
        {
            int[] newLabels = new int[Labels.Length];
            for (int i = 0; i < Labels.Length; i++)
                newLabels[i] = Labels[i];
            Random r = new Random();
            int last = this.maxLabel;

            for (int i = 0; i < clusCount; i++)
            {
                int pos = r.Next(0, Labels.Length);
                newLabels[pos] = last + 1;
                last++;

            }
            Segmentation result = new Segmentation(newLabels);
            return result;
        }
コード例 #17
0
 public override double Process(Segmentation s1, Segmentation s2)
 {
     return Entropy(s1) + Entropy(s2) - 2 * MI(s1, s2);
 }
コード例 #18
0
 public override double Process(Segmentation s1, Segmentation s2)
 {
     return(Entropy(s1) + Entropy(s2) - 2 * MI(s1, s2));
 }
コード例 #19
0
 public override double Process(Segmentation s1, Segmentation s2)
 {
     double ents = Entropy(s1) * Entropy(s2);
     if (ents != 0)
         return MI(s1, s2) / Math.Sqrt(ents);
     else
         return 1;
 }