public bool WithinSamePlane(ImageVector vector, double tolerance = 0.0) { if (tolerance == 0.0) { tolerance = vectorTolerance; } //if both our points have length zero then we are on the same plane as our slopes are NaN if (Length == 0.0 && vector.Length == 0.0) { return(true); } //If all of the X values are the same or all of the Y values are the same then we must be in the same plane if (MatchFour(Sx, Ex, vector.Sx, vector.Ex)) { return(true); } if (MatchFour(Sy, Ey, vector.Sy, vector.Ey)) { return(true); } //Check for diagonal vectors //If our slope and intercept are both valid numbers and the same within the tolerance these vectors are considered in the same plane as each other bool range1 = TestRange(Slope, vector.Slope * (1.0 - tolerance), vector.Slope * (1.0 + tolerance)); bool range2 = TestRange(Intercept, vector.Intercept * (1.0 - tolerance), vector.Intercept * (1.0 + tolerance)); return(range1 && range2); }
/// <summary> /// Converts the current ImageCube to a Bitmap object /// </summary> /// <param name="redIndex">The band index representing Red channel</param> /// <param name="greenIndex">The band index representing Green channel</param> /// <param name="blueIndex">The band index representing Blue channel</param> /// <returns>A bitmap of the current ImageCube</returns> public Bitmap ToBitmap(int redIndex, int greenIndex, int blueIndex) { int[, ,] triBandImageVector = NormalizeImageVectorForDisplay(redIndex, greenIndex, blueIndex); Bitmap inputImage = new Bitmap(ImageVector.GetLength(0), ImageVector.GetLength(1)); FastBitmap currentTRIBandImage = new FastBitmap(inputImage); currentTRIBandImage.LockImage(); for (int i = 0; i < inputImage.Width; i++) { for (int j = 0; j < inputImage.Height; j++) { currentTRIBandImage.SetPixel(i, j, Color.FromArgb(triBandImageVector[i, j, 0], triBandImageVector[i, j, 1], triBandImageVector[i, j, 2])); } } currentTRIBandImage.UnlockImage(); return(inputImage); }
/// <summary> /// Used internally to find the max. and min. values of the band. /// </summary> /// <param name="colorBandIndex">The band index</param> /// <returns>an array of 2 values , [0]: min value, [1]: Max. value</returns> private double[] RangeValuesFor(int colorBandIndex) { double[] maxValue = new double[2]; Parallel.For(0, ImageVector.GetLength(0), i => //for (int i = 0; i < ImageVector.GetLength(0); i++) { for (int j = 0; j < ImageVector.GetLength(1); j++) { if (maxValue[0] < ImageVector[i, j, colorBandIndex]) { maxValue[0] = ImageVector[i, j, colorBandIndex]; } //........................................................... if (maxValue[1] > ImageVector[i, j, colorBandIndex]) { maxValue[1] = ImageVector[i, j, colorBandIndex]; } } }); return(maxValue); }
/// <summary> /// Used interrnally to normalize the image vector for RGB display /// </summary> /// <param name="redIndex">The band index representing Red channel</param> /// <param name="greenIndex">The band index representing Green channel</param> /// <param name="blueIndex">The band index representing Blue channel</param> /// <returns>3-dimentional normalized image ready for display</returns> private int[, ,] NormalizeImageVectorForDisplay(int redIndex, int greenIndex, int blueIndex) { int[, ,] triBandImageVector = new int[ImageVector.GetLength(0), ImageVector.GetLength(1), 3]; //................................................................. double[] redmaxValue = RangeValuesFor(redIndex); double[] greenmaxValue = RangeValuesFor(greenIndex); double[] bluemaxValue = RangeValuesFor(blueIndex); //................................................................. int redRange = (int)(redmaxValue[0] - redmaxValue[1]); int greenRange = (int)(greenmaxValue[0] - greenmaxValue[1]); int blueRange = (int)(bluemaxValue[0] - bluemaxValue[1]); for (int i = 0; i < ImageVector.GetLength(0); i++) { for (int j = 0; j < ImageVector.GetLength(1); j++) { triBandImageVector[i, j, 0] = (int)(ImageVector[i, j, redIndex] * 255d / redmaxValue[0]); triBandImageVector[i, j, 1] = (int)(ImageVector[i, j, greenIndex] * 255d / greenmaxValue[0]); triBandImageVector[i, j, 2] = (int)(ImageVector[i, j, blueIndex] * 255d / bluemaxValue[0]); } } return(triBandImageVector); }
public void ExtendVerticies() { for (int i = 0; i < imageVectors.Count; i++) { if (!imageVectors[i].Alive) { continue; } for (int j = 0; j < imageVectors.Count; j++) { if (!imageVectors[j].Alive || (i == j)) { continue; } //If we are not within the same plane however a set of our vertexs are adjacent, then extend the appropriate vector. if (!imageVectors[i].WithinSamePlane(imageVectors[j])) { String prevJVector = imageVectors[j].ToString(); //Only update the vector if we are making it longer in the same plane if (PointsAreAdjacent(imageVectors[i].Sx, imageVectors[i].Sy, imageVectors[j].Sx, imageVectors[j].Sy)) { ImageVector newVector = new ImageVector(imageVectors[i].Sx, imageVectors[i].Sy, imageVectors[j].Ex, imageVectors[j].Ey); if ((newVector.Length > imageVectors[j].Length) && (newVector.Slope == imageVectors[j].Slope) && (newVector.Intercept == imageVectors[j].Intercept)) { imageVectors[j] = newVector; Console.WriteLine("i: " + i + " j: " + j + " Updated vector " + prevJVector + " to: " + imageVectors[j].ToString()); } } else if (PointsAreAdjacent(imageVectors[i].Sx, imageVectors[i].Sy, imageVectors[j].Ex, imageVectors[j].Ey)) { ImageVector newVector = new ImageVector(imageVectors[j].Sx, imageVectors[j].Sy, imageVectors[i].Sx, imageVectors[i].Sy); if ((newVector.Length > imageVectors[j].Length) && (newVector.Slope == imageVectors[j].Slope) && (newVector.Intercept == imageVectors[j].Intercept)) { imageVectors[j] = newVector; Console.WriteLine("i: " + i + " j: " + j + " Updated vector " + prevJVector + " to: " + imageVectors[j].ToString()); } } else if (PointsAreAdjacent(imageVectors[i].Ex, imageVectors[i].Ey, imageVectors[j].Sx, imageVectors[j].Sy)) { ImageVector newVector = new ImageVector(imageVectors[i].Ex, imageVectors[i].Ey, imageVectors[j].Ex, imageVectors[j].Ey); if ((newVector.Length > imageVectors[j].Length) && (newVector.Slope == imageVectors[j].Slope) && (newVector.Intercept == imageVectors[j].Intercept)) { imageVectors[j] = newVector; Console.WriteLine("i: " + i + " j: " + j + " Updated vector " + prevJVector + " to: " + imageVectors[j].ToString()); } } else if (PointsAreAdjacent(imageVectors[i].Ex, imageVectors[i].Ey, imageVectors[j].Ex, imageVectors[j].Ey)) { ImageVector newVector = new ImageVector(imageVectors[j].Sx, imageVectors[j].Sy, imageVectors[i].Ex, imageVectors[i].Ey); if ((newVector.Length > imageVectors[j].Length) && (newVector.Slope == imageVectors[j].Slope) && (newVector.Intercept == imageVectors[j].Intercept)) { imageVectors[j] = newVector; Console.WriteLine("i: " + i + " j: " + j + " Updated vector " + prevJVector + " to: " + imageVectors[j].ToString()); } } } } } }
public void JoinVectors() { for (int i = 0; i < imageVectors.Count; i++) { if (!imageVectors[i].Alive) { continue; } for (int j = 0; j < imageVectors.Count; j++) { ImageVector ivec = imageVectors[i]; ImageVector jvec = imageVectors[j]; if (!imageVectors[j].Alive || (i == j)) { continue; } //if vector has a start or end position within 1 unit of us and it is in the same plane, then join the vectors if (imageVectors[i].WithinSamePlane(imageVectors[j])) { //if v.Sx,Sy is adjacent to n.Sx,Sy OR //if v.Sx,Sy is adjacent to n.Ex,Ey OR //if v.Ex,Ey is adjacent to n.Sx,Sy OR //if v.Ex,Ey is adjacent to n.Ex,Ey OR //Join the vectors by updating the vector and deleting the neighbor Console.WriteLine("i: " + i + " j: " + j + " in the same plane"); String prevVector = imageVectors[i].ToString(); if (PointsAreAdjacent(imageVectors[i].Sx, imageVectors[i].Sy, imageVectors[j].Sx, imageVectors[j].Sy)) { imageVectors[i].Update(imageVectors[i].Ex, imageVectors[i].Ey, imageVectors[j].Ex, imageVectors[j].Ey); imageVectors[j].Alive = false; Console.WriteLine("1 i: " + i + " j: " + j + " Updated vector " + prevVector + " to: " + imageVectors[i].ToString()); Console.WriteLine("Removed vector " + imageVectors[j].ToString()); } else if (PointsAreAdjacent(imageVectors[i].Sx, imageVectors[i].Sy, imageVectors[j].Ex, imageVectors[j].Ey)) { imageVectors[i].Update(imageVectors[i].Ex, imageVectors[i].Ey, imageVectors[j].Sx, imageVectors[j].Sy); imageVectors[j].Alive = false; Console.WriteLine("2 i: " + i + " j: " + j + " Updated vector " + prevVector + " to: " + imageVectors[i].ToString()); Console.WriteLine("Removed vector " + imageVectors[j].ToString()); } else if (PointsAreAdjacent(imageVectors[i].Ex, imageVectors[i].Ey, imageVectors[j].Sx, imageVectors[j].Sy)) { imageVectors[i].Update(imageVectors[i].Sx, imageVectors[i].Sy, imageVectors[j].Ex, imageVectors[j].Ey); imageVectors[j].Alive = false; Console.WriteLine("3 i: " + i + " j: " + j + " Updated vector " + prevVector + " to: " + imageVectors[i].ToString()); Console.WriteLine("Removed vector " + imageVectors[j].ToString()); } else if (PointsAreAdjacent(imageVectors[i].Ex, imageVectors[i].Ey, imageVectors[j].Ex, imageVectors[j].Ey)) { imageVectors[i].Update(imageVectors[i].Sx, imageVectors[i].Sy, imageVectors[j].Sx, imageVectors[j].Sy); imageVectors[j].Alive = false; Console.WriteLine("4 i: " + i + " j: " + j + " Updated vector " + prevVector + " to: " + imageVectors[i].ToString()); Console.WriteLine("Removed vector " + imageVectors[j].ToString()); } } } } //Delete the dead vectors var newVectors = new List <ImageVector>(); foreach (ImageVector vector in imageVectors) { if (vector.Alive) { newVectors.Add(vector); } } imageVectors = newVectors; }