public SymImage addItem(int[,] imageMatrix) { //Check if image matrix size is correct if (imageMatrix.GetLength(0) != matrixSize || imageMatrix.GetLength(0) != matrixSize) { throw new ArgumentException("The image matrix must be " + matrixSize + "x" + matrixSize + "."); } //Create a new SymImage SymImage symImage = new SymImage(imageMatrix, generateID()); //Calculate distance to all other items in the list foreach (SymImage sImg in symImages) { symDistances.Add(new SymImageDistance(symImage, sImg)); } //Add item to symImages list. It is added after distance calculations are done, so it is note compared to itself. symImages.Add(symImage); //Perform hierarchy analysis createHierarchy(); //Return the new SymImage return(symImage); }
public void removeItem(SymImage symImage) { //Remove from symDistances list symDistances.RemoveAll(p => p.symImageA == symImage || p.symImageB == symImage); //Remove from symImages list symImages.Remove(symImage); }
public void createHierarchy() { //Create copy of original data List <SymImage> clusters = symImages.ToList(); List <SymImageDistance> clusterDistances = symDistances.ToList(); //Merge all pairs and until list is empty int AutoStop = 10; while (clusterDistances.Count > 0) { AutoStop--; if (AutoStop == 0) { AutoStop = 0; } //Sort the distance list clusterDistances = clusterDistances.OrderBy(p => p.Distance).ToList(); //Get first distance entry, since it is the nearest pair. SymImageDistance distEntry = clusterDistances[0]; //Remove all items referencing these two items. clusters.Remove(distEntry.symImageA); clusters.Remove(distEntry.symImageB); clusterDistances.RemoveAll(p => p.symImageA == distEntry.symImageA || p.symImageA == distEntry.symImageB); clusterDistances.RemoveAll(p => p.symImageB == distEntry.symImageA || p.symImageB == distEntry.symImageB); //Create a new cluster from the distEntry items SymImage newCluster = new SymImage(new List <SymImage>() { distEntry.symImageA, distEntry.symImageB }, generateID()); //Calculate distance to all existing clusters foreach (SymImage cluster in clusters) { clusterDistances.Add(new SymImageDistance(newCluster, cluster)); } //Add new cluster to list clusters.Add(newCluster); } //Save results clusterHierarchy = clusters.ToList(); }
//Constructors public SymImageDistance(SymImage symImage1, SymImage symImage2) { //Compare IDs and put lower ID in position A if (symImage1.ID < symImage2.ID) { a = symImage1; b = symImage2; } else { b = symImage1; a = symImage2; } //Calculate distance and save distance = a.distanceFrom(b); }
//Methods - Public public int distanceFrom(SymImage symImageB) { //Result variable int distance = 0; //Cycle through every X pixel of image A for (int aX = 0; aX < matrixSize; aX++) { //Cycle through every Y pixel of image A for (int aY = 0; aY < matrixSize; aY++) { //Check if pixel A is white. Skip these if (this.ImageMatrix[aX, aY] == 0) { continue; } //Cycle through every X pixel of image B for (int bX = 0; bX < matrixSize; bX++) { //Cycle through every Y pixel of image B for (int bY = 0; bY < matrixSize; bY++) { //Check if pixel B is white. Skip these if (symImageB.ImageMatrix[bX, bY] == 0) { continue; } //Calculate difference between coordinates distance += Convert.ToInt32(Math.Sqrt(Math.Pow(aX - bX, 2) + Math.Pow(aY - bY, 2))); } } } } //Normalized the distance by dividing by number of black pixels distance = distance / ((this.numBlackPixels + symImageB.numBlackPixels) / 2); return(distance); }