Exemple #1
0
        void FindRepresentativeColors(int size)           //==>⊖(D+E) ==> O(D)
        {
            replacedMatrix = new RGBPixel[256, 256, 256]; //⊖(1)
            newListRGB     = new List <RGBPixelD>();
            bool[] visited    = new bool[size];           //⊖(1)
            bool[] visitedcpd = new bool[size];           //⊖(1)

            for (int v = 0; v < size; v++)                //==>⊖(D)
            {
                if (!visited[v])                          //⊖(1)
                {
                    DFS_GetClusterColor(v, visited);      //⊖(egdes+nodes)

                    red   /= counter;                     //⊖(1)
                    green /= counter;                     //⊖(1)
                    blue  /= counter;                     //⊖(1)

                    min             = double.MaxValue;    //⊖(1)
                    minRGBPixelD    = listRGB[v];         //⊖(1)
                    rGBPixelD.red   = red;                //⊖(1)
                    rGBPixelD.green = green;              //⊖(1)
                    rGBPixelD.blue  = blue;               //⊖(1)

                    DfS_ColorReplace(v, visitedcpd);      //⊖(egdes+nodes)
                    newListRGB.Add(minRGBPixelD);         //⊖(size)

                    red = green = blue = counter = 0;     //⊖(1)
                }
            }
        }
Exemple #2
0
        //public void prim()//E Log(D)
        //{
        //    int size = listRGB.Count; // Number of Distincit Colors Θ(1)
        //    Console.WriteLine(int.MaxValue - (size * (size - 1)) / 2);
        //    MSTDictionary = new Dictionary<int, double>[size];//⊖(1)
        //    maxHeap = new MaxHeap(listRGB.Count - 1);//⊖(1)
        //    bool[] visited = new bool[size]; //Θ(1)
        //    int sizeHolder = ((size * (size - 1)) / 2);
        //    if (sizeHolder > int.MaxValue)
        //    {

        //        sizeHolder = int.MaxValue - 10000;
        //    }
        //    MinHeap edgesHeap = new MinHeap(sizeHolder ); //Θ(1)
        //    edgesHeap.insertEdge(new Edge(0, 0, 0)); // Edge(From, weight, to) takes O(log E)
        //    int edgeCounter = 0; //Θ(1)

        //    while (edgeCounter != size && !edgesHeap.isEmpty()) //iteration * body ===> E * O(Body) ==>  E * Log V
        //    {
        //        Edge edgeHolder = edgesHeap.getMinEdge(); //(log E)
        //        if (visited[edgeHolder.colorB]) //Θ(1)
        //            continue; //Θ(1)

        //        visited[edgeHolder.colorB] = true; //Θ(1)
        //        edgeCounter++; //Θ(1)
        //        sum += edgeHolder.weight; //Θ(1)
        //        if (edgeCounter != 1) //⊖(1)
        //        {
        //            if (MSTDictionary[edgeHolder.colorA] == null)//⊖(1)
        //                MSTDictionary[edgeHolder.colorA] = new Dictionary<int, double>();//⊖(1)
        //            if (MSTDictionary[edgeHolder.colorB] == null)//⊖(1)
        //                MSTDictionary[edgeHolder.colorB] = new Dictionary<int, double>();//⊖(1)
        //            MSTDictionary[edgeHolder.colorA][edgeHolder.colorB] = edgeHolder.weight;//⊖(1)
        //            MSTDictionary[edgeHolder.colorB][edgeHolder.colorA] = edgeHolder.weight;//⊖(1)
        //            maxHeap.insertEdge(edgeHolder);//⊖(log heap size)
        //        }
        //        for (int i = 0; i < size; i++) // iteration * body ===> E * O(body) ===> E * log V
        //        {
        //            if (!visited[i])
        //            {
        //                double weight = calcEuclideanDistance(listRGB[edgeHolder.colorB], listRGB[i]); //O(1)
        //                edgesHeap.insertEdge(new Edge(edgeHolder.colorB, weight, i)); //O(log E)
        //            }
        //        }
        //    }
        //    Console.WriteLine("Sum: " + sum); //Θ(1)
        //}



        /// <summary>
        /// Calculate distance between two colors
        /// </summary>
        /// <param name="firstColor">Node Color</param>
        /// <param name="secondColor">Node Color</param>
        /// <returns>Euclidean Distance</returns>
        public double calcEuclideanDistance(RGBPixelD firstColor, RGBPixelD secondColor)
        {
            double red = firstColor.red - secondColor.red;       //Θ(1)

            red *= red;                                          //Θ(1)
            double green = firstColor.green - secondColor.green; //Θ(1)

            green *= green;                                      //Θ(1)
            double blue = firstColor.blue - secondColor.blue;    //Θ(1)

            blue *= blue;                                        //Θ(1)
            return(Math.Sqrt(red + blue + green));               //Θ(1)
        }
Exemple #3
0
        //  total function's complexity --> Exact (K * D) -->  K = number of clusters, D = number of distinct colors


        public static void avgcolor_BFS(List <Color> index_color, int Pindex, RGBPixelD[,,] pallete, bool[] v, List <node2>[] adj)
        {
            int             count = 1;                     //O(1)
            RGBPixelD       avg   = new RGBPixelD();       //O(1)
            Queue <int>     Q     = new Queue <int>();     //O(1)
            List <RGBPixel> ch    = new List <RGBPixel>(); //O(1)


            Q.Enqueue(Pindex);   //O(1)
            while (Q.Count != 0) //Exact(E) --> E = number of edges in cluster
            {
                int      root     = Q.Dequeue();
                RGBPixel ch_color = index_color[root].val; //O(1)
                ch.Add(ch_color);                          //O(1)
                avg.red   += ch_color.red;                 //O(1)
                avg.blue  += ch_color.blue;                //O(1)
                avg.green += ch_color.green;               //O(1)


                for (int r = 0; r < adj[root].Count; r++) //Exact(adj(D)) --> D = number of nodes
                {
                    if (v[adj[root][r].to] == false)      //O(1)
                    {
                        Q.Enqueue(adj[root][r].to);       //O(1)
                        count++;                          // O(1)
                    }
                }
                // total for loop --> Exact(adj(D)) --> D = number of nodes

                v[root] = true;//O(1)
            }
            // total while loop --> Exact(E) --> E = number of edges in cluster
            avg.red   /= count; //O(1)
            avg.blue  /= count; //O(1)
            avg.green /= count; //O(1)

            //assign the the cluster color with its represented color in the pallete
            foreach (var ch_color1 in ch)                                      // O(D)--> D = number of Distinct colors in this cluster
            {
                pallete[ch_color1.red, ch_color1.blue, ch_color1.green] = avg; // O(1)
            }
        }
Exemple #4
0
        void DfS_ColorReplace(int v, bool[] visited)//⊖(egdes+nodes)
        {
            // Mark the current node as visited and print it
            visited[v] = true;                                                                                    //⊖(1)
            replacedMatrix[(int)listRGB[v].red, (int)listRGB[v].green, (int)listRGB[v].blue].red   = (byte)red;   //⊖(1)
            replacedMatrix[(int)listRGB[v].red, (int)listRGB[v].green, (int)listRGB[v].blue].green = (byte)green; //⊖(1)
            replacedMatrix[(int)listRGB[v].red, (int)listRGB[v].green, (int)listRGB[v].blue].blue  = (byte)blue;  //⊖(1)

            distance = calcEuclideanDistance(listRGB[v], rGBPixelD);                                              //⊖(1)
            if (distance < min)
            {
                min          = distance;                                   //⊖(1)
                minRGBPixelD = listRGB[v];                                 //⊖(1)
            }
            foreach (KeyValuePair <int, double> color in MSTDictionary[v]) //⊖(E)
            {
                if (!visited[color.Key])                                   //⊖(1)
                {
                    DfS_ColorReplace(color.Key, visited);
                }
            }
        }
 //DP RECURION FUNCTION
 private int get_cluster(int j)
 {
     if (MSTree[j].source == -1)
     {
         MSTree[j].knum           = next_cluster;
         clusters[MSTree[j].knum] = new List <RGBPixel>();
         next_cluster++;
     }
     else if (MSTree[MSTree[j].source].visted)
     {
         MSTree[j].knum = MSTree[MSTree[j].source].knum;
     }
     else
     {
         MSTree[j].knum = get_cluster(MSTree[j].source);
     }
     if (cluster_centroid[MSTree[j].knum] == null)
     {
         cluster_centroid[MSTree[j].knum] = new List <RGBPixelD>();
         RGBPixelD color = new RGBPixelD();
         color.red   = colors[j].red;
         color.blue  = colors[j].blue;
         color.green = colors[j].green;
         cluster_centroid[MSTree[j].knum].Add(color);
     }
     else
     {
         RGBPixelD color = new RGBPixelD();
         color.red   = (cluster_centroid[MSTree[j].knum][0].red + colors[j].red) / 2;
         color.blue  = (cluster_centroid[MSTree[j].knum][0].blue + colors[j].blue) / 2;
         color.green = (cluster_centroid[MSTree[j].knum][0].green + colors[j].green) / 2;
         cluster_centroid[MSTree[j].knum][0] = color;
     }
     clusters[MSTree[j].knum].Add(colors[j]);
     MSTree[j].visted = true;
     return(MSTree[j].knum);
 }
Exemple #6
0
        /// <summary>
        /// Apply Gaussian smoothing filter to enhance the edge detection
        /// </summary>
        /// <param name="ImageMatrix">Colored image matrix</param>
        /// <param name="filterSize">Gaussian mask size</param>
        /// <param name="sigma">Gaussian sigma</param>
        /// <returns>smoothed color image</returns>
        public static RGBPixel[,] GaussianFilter1D(RGBPixel[,] ImageMatrix, int filterSize, double sigma)
        {
            int Height = GetHeight(ImageMatrix);
            int Width  = GetWidth(ImageMatrix);

            RGBPixelD[,] VerFiltered = new RGBPixelD[Height, Width];
            RGBPixel[,] Filtered     = new RGBPixel[Height, Width];


            // Create Filter in Spatial Domain:
            //=================================
            //make the filter ODD size
            if (filterSize % 2 == 0)
            {
                filterSize++;
            }

            double[] Filter = new double[filterSize];

            //Compute Filter in Spatial Domain :
            //==================================
            double Sum1     = 0;
            int    HalfSize = filterSize / 2;

            for (int y = -HalfSize; y <= HalfSize; y++)
            {
                //Filter[y+HalfSize] = (1.0 / (Math.Sqrt(2 * 22.0/7.0) * Segma)) * Math.Exp(-(double)(y*y) / (double)(2 * Segma * Segma)) ;
                Filter[y + HalfSize] = Math.Exp(-(double)(y * y) / (double)(2 * sigma * sigma));
                Sum1 += Filter[y + HalfSize];
            }
            for (int y = -HalfSize; y <= HalfSize; y++)
            {
                Filter[y + HalfSize] /= Sum1;
            }

            //Filter Original Image Vertically:
            //=================================
            int       ii, jj;
            RGBPixelD Sum;
            RGBPixel  Item1;
            RGBPixelD Item2;

            for (int j = 0; j < Width; j++)
            {
                for (int i = 0; i < Height; i++)
                {
                    Sum.red   = 0;
                    Sum.green = 0;
                    Sum.blue  = 0;
                    for (int y = -HalfSize; y <= HalfSize; y++)
                    {
                        ii = i + y;
                        if (ii >= 0 && ii < Height)
                        {
                            Item1      = ImageMatrix[ii, j];
                            Sum.red   += Filter[y + HalfSize] * Item1.red;
                            Sum.green += Filter[y + HalfSize] * Item1.green;
                            Sum.blue  += Filter[y + HalfSize] * Item1.blue;
                        }
                    }
                    VerFiltered[i, j] = Sum;
                }
            }

            //Filter Resulting Image Horizontally:
            //===================================
            for (int i = 0; i < Height; i++)
            {
                for (int j = 0; j < Width; j++)
                {
                    Sum.red   = 0;
                    Sum.green = 0;
                    Sum.blue  = 0;
                    for (int x = -HalfSize; x <= HalfSize; x++)
                    {
                        jj = j + x;
                        if (jj >= 0 && jj < Width)
                        {
                            Item2      = VerFiltered[i, jj];
                            Sum.red   += Filter[x + HalfSize] * Item2.red;
                            Sum.green += Filter[x + HalfSize] * Item2.green;
                            Sum.blue  += Filter[x + HalfSize] * Item2.blue;
                        }
                    }
                    Filtered[i, j].red   = (byte)Sum.red;
                    Filtered[i, j].green = (byte)Sum.green;
                    Filtered[i, j].blue  = (byte)Sum.blue;
                }
            }

            return(Filtered);
        }
Exemple #7
0
 /*
  * Euclidean Equation Function
  * Summary : Calculates distance between two pixels
  * Parameters : Two pixels as RGBPixelD
  * Return : Distance between two pixels as double
  */
 public static double euclideanEquation(RGBPixelD pix1, RGBPixelD pix2)                 //O(1)
 {
     return(Math.Sqrt((pix1.red - pix2.red) * (pix1.red - pix2.red) + ((pix1.green - pix2.green) * (pix1.green - pix2.green)) +
                      ((pix1.blue - pix2.blue) * (pix1.blue - pix2.blue)))); //O(1)
 }
Exemple #8
0
        public static RGBPixelD[,,] Extract_color_palette(MST mst, int Num_of_clusters)
        {
            RGBPixelD[ , , ] Color_palette = new RGBPixelD[256, 256, 256]; //O(1)
            bool[]         v   = new bool[mst.parent.Length];              //O(1)
            List <node2>[] adj = new List <node2> [mst.parent.Length];     //O(1)

            ///<summary>
            ///make cluster of a tree
            /// </summary>
            for (int l = 0; l < Num_of_clusters - 1; l++) //E(K)
            {
                int    i     = 0;                         //O(1)
                int    index = 0;                         //O(1)
                double W     = double.MinValue;           //O(1)
                foreach (Node color in mst.tree)          //E(D)
                {
                    if (W < color.weight)                 //O(1)
                    {
                        W     = color.weight;             //O(1)
                        index = i;                        //O(1)
                    }
                    i++;                                  //O(1)
                }
                //total loop --> O(D) --> D = number of distinct colors

                mst.tree.RemoveAt(index);//O(D)
            }
            //total loop Order --> E(D*K)

            ///<summary>
            ///convert clustered tree from list representation to adjacent list representation
            /// </summary>
            for (int r = 0; r < mst.parent.Length; r++)
            {
                v[r] = false;//O(1)
            }
            //total loop --> O(D) --> D = number of distinct colors

            for (int i = 0; i < mst.parent.Length; i++) //O(D) --> D = number of distinct colors
            {
                adj[i] = new List <node2>();            //O(1)
            }
            //total loop --> O(D) --> D = number of distinct colors

            int k = 0;                       //O(1)

            foreach (Node color in mst.tree) //E(D)
            {
                if (k == 0)                  //O(1)
                {
                    k++;                     //O(1)
                    continue;                //O(1)
                }
                node2 n  = new node2();      //O(1)
                node2 n2 = new node2();      //O(1)
                n.weight  = color.weight;    //O(1)
                n.to      = color.to;        //O(1)
                n2.weight = color.weight;    //O(1)
                n2.to     = color.index;     //O(1)
                adj[color.index].Add(n);     //O(1)
                adj[color.to].Add(n2);       //O(1)
            }
            ///<summary>
            ///for loop to catch each root of the cluster and move forward
            /// to all his adjacent and make a pallete with new color
            /// </summary>
            for (int r = 0; r < mst.parent.Length; r++)                      // Exact(D) --> total number of disinct colors
            {
                if (v[r] == false)                                           //O(1)
                {
                    avgcolor_BFS(mst.index_color, r, Color_palette, v, adj); //Exact(E + D)
                }
            }
            //total for loop ---> Exact (K * D) -->  K = number of clusters, D = number of distinct colors
            //BFS was called , K = number of clusters

            return(Color_palette);
        }
 public static int getSum(int a, bool [] visited, int[] parent, RGBPixelD[] distinct, RGBPixelD accumulativeSum, int[] size)
 {
     if (a == parent[a])
     {
         distinct[a].blue  += accumulativeSum.blue;
         distinct[a].red   += accumulativeSum.red;
         distinct[a].green += accumulativeSum.green;
         return(a);
     }
     else if (!visited[a])
     {
         visited[a]             = true;
         accumulativeSum.blue  += distinct[a].blue;
         accumulativeSum.red   += distinct[a].red;
         accumulativeSum.green += distinct[a].green;
     }
     size[a] = 0;
     return(parent[a] = getSum(parent[a], visited, parent, distinct, accumulativeSum, size));
 }
        public static Dictionary <string, RGBPixelD> clustering(ResultSet[] mST, RGBPixel[] Distinct)
        {
            int[]       repres       = new int[Distinct.Length];
            int[]       size         = new int[Distinct.Length];
            RGBPixelD[] distClusters = new RGBPixelD[Distinct.Length];
            for (int i = 0; i < Distinct.Length; i++)
            {
                distClusters[i].blue  = Distinct[i].blue;
                distClusters[i].green = Distinct[i].green;
                distClusters[i].red   = Distinct[i].red;
            }

            for (int i = 0; i < Distinct.Length; i++)
            {
                repres[i] = i;
                size[i]   = 1;
            }
            int clusters = Distinct.Length;

            for (int i = mST.Length - 1; i >= 0; i--)
            {
                clusters = uniteSet(mST[i].current, mST[i].parent, repres, size, clusters);
                if (clusters == k)
                {
                    break;
                }
            }
            bool[]    visited = new bool[mST.Length];
            RGBPixelD accumSum;

            accumSum.blue  = 0;
            accumSum.green = 0;
            accumSum.red   = 0;

            for (int i = mST.Length - 1; i >= 0; i--)
            {
                repres[i] = getSum(i, visited, repres, distClusters, accumSum, size);
            }
            for (int i = mST.Length - 1; i >= 0; i--)
            {
                if (size[i] == 0)
                {
                    continue;
                }
                distClusters[i].blue  /= size[i];
                distClusters[i].green /= size[i];
                distClusters[i].red   /= size[i];
            }
            map = new Dictionary <string, RGBPixelD> ();

            for (int i = mST.Length - 1; i >= 0; i--)
            {
                string s = "";
                s  = Distinct[i].blue.ToString() + '-';
                s += Distinct[i].green.ToString() + '+';
                s += Distinct[i].red.ToString();

                if (size[i] == 0)
                {
                    map[s] = distClusters[repres[i]];
                }
                else
                {
                    map[s] = distClusters[i];
                }
            }
            Console.WriteLine("oooooooweeeeeee");
            return(map);
        }