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) } } }
//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) }
// 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) } }
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); }
/// <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); }
/* * 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) }
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); }