public override object MeasurePlant(PlantInfo plant) { Point source = default(Point); double totalX = 0.0, totalY = 0.0; double count = 0; foreach (RootInfo root in plant) { if (root.RelativeID == "1.1") { source = root.Spline.Start; } SampledSpline s = root.Spline; foreach (Point p in s.SampledPoints) { totalX += p.X; totalY += p.Y; ++count; } } return(String.Format("{0}, {1}", Math.Round(totalX / count - source.X, 3), Math.Round(totalY / count - source.Y, 3))); }
public override object MeasurePlant(PlantInfo plant) { double min = Int32.MaxValue; double max = Int32.MinValue; HashSet <Point> rootPoints = new HashSet <Point>(); foreach (RootInfo root in plant) { SampledSpline s = root.Spline; Point[] splinePoints = s.Rasterise(); foreach (Point p in splinePoints) { rootPoints.Add(p); if (p.Y < min) { min = p.Y; } if (p.Y > max) { max = p.Y; } } } List <int>[] xs = new List <int> [(int)max - (int)min + 1]; for (int i = 0; i < xs.Length; i++) { xs[i] = new List <int>(); } foreach (Point p in rootPoints) { xs[(int)p.Y - (int)min].Add((int)p.X); } int widthmax = int.MinValue; for (int pos = 0; pos < xs.Length; pos++) { if (xs[pos].Count > 0) { int submin = xs[pos].Min(); int submax = xs[pos].Max(); int width = submax - submin + 1; if (widthmax < width) { widthmax = width; } } } return(widthmax); }
public override object MeasureRoot(RootInfo root, RootInfo parent = null) { // If parent == null, then this is a primary root and there is no emergence angle if (parent == null) { double angleMax = 30.0; Point start, end; if (angleMax > root.Spline.Length) { double newMinDistanceOffset = angleMax - root.Spline.Length; start = root.Spline.Start; end = root.Spline.GetPoint(root.Spline.GetPositionReference(root.Spline.Length)); } else { start = root.Spline.Start; end = root.Spline.GetPoint(root.Spline.GetPositionReference(angleMax)); } // Angle between horizontal and emergence vectors double angle = 90 - Vector.AngleBetween(new Vector(1, 0), end - start); return(Math.Round(angle > 180 ? angle - 360 : angle, 2)); } else { double angleMax = 30.0, angleMin = 10.0, parentAngleRadius = 20.0; Point start, end; if (angleMax > root.Spline.Length) { double newMinDistanceOffset = angleMax - root.Spline.Length; start = root.Spline.GetPoint(root.Spline.GetPositionReference(Math.Max(0.0, angleMin - newMinDistanceOffset))); end = root.Spline.GetPoint(root.Spline.GetPositionReference(root.Spline.Length)); } else { start = root.Spline.GetPoint(root.Spline.GetPositionReference(Math.Min(root.Spline.Length, angleMin))); end = root.Spline.GetPoint(root.Spline.GetPositionReference(angleMax)); } Vector rootVector = end - start; SampledSpline parentSpline = parent.Spline; double parentIntersectionDistance = parentSpline.GetLength(root.StartReference); Point parentStart = parentSpline.GetPoint(parentSpline.GetPositionReference(Math.Max(0.0, parentIntersectionDistance - parentAngleRadius))); Point parentEnd = parentSpline.GetPoint(parentSpline.GetPositionReference(Math.Min(parent.Spline.Length, parentIntersectionDistance + parentAngleRadius))); Vector parentVector = parentEnd - parentStart; return(Math.Round(Vector.AngleBetween(rootVector, parentVector), 2)); } }
public override object MeasureRoot(RootInfo root, RootInfo parent = null) { // If parent == null, then this is a primary root and there is no emergence angle if (parent == null) { return(""); } else { SampledSpline parentSpline = parent.Spline; double parentIntersectionDistance = parentSpline.GetLength(root.StartReference); return(Math.Round(parentIntersectionDistance, 2)); } }
public override object MeasurePlant(PlantInfo plant) { double maxdepth = double.MinValue; foreach (RootInfo root in plant) { SampledSpline s = root.Spline; if (s != null) { double depth = s.BoundingBox.Bottom; if (maxdepth < depth) { maxdepth = depth; } } else { // Bad Spline } } return(maxdepth); }
public override object MeasureRoot(RootInfo root, RootInfo parent = null) { // If parent == null, then this is a primary root and there is no emergence angle if (parent == null) { return(""); } else { double parentAngleRadius = 10.0; SampledSpline parentSpline = parent.Spline; double parentIntersectionDistance = parentSpline.GetLength(root.StartReference); Point parentStart = parentSpline.GetPoint(parentSpline.GetPositionReference(Math.Max(0.0, parentIntersectionDistance - parentAngleRadius))); Point parentEnd = parentSpline.GetPoint(parentSpline.GetPositionReference(Math.Min(parent.Spline.Length, parentIntersectionDistance + parentAngleRadius))); Vector parentVector = parentEnd - parentStart; double angle = 90 - Vector.AngleBetween(new Vector(1, 0), parentEnd - parentStart); return(Math.Round(angle > 180 ? angle - 360 : angle, 2)); } }
unsafe private void segmentedImagesMenuItem_Click(object sender, RoutedEventArgs e) { System.Windows.Forms.FolderBrowserDialog fbd = new System.Windows.Forms.FolderBrowserDialog() { SelectedPath = "G:\\Training Sets\\new" }; var result = fbd.ShowDialog(); if (result != System.Windows.Forms.DialogResult.OK) { return; } foreach (double penWidth in new double[] { 8 }) { bool useCrop = true; bool tipsOnly = false; bool primaryOnly = false; bool lateralOnly = false; bool conflictOnly = false; bool sourceOnly = false; bool outputOriginalImages = false; //double penWidth = 10; this.SnapsToDevicePixels = true; RenderOptions.SetEdgeMode(this, EdgeMode.Aliased); string[] supportedDatasets = new string[] { "RSDH00", "RSDH01", "RSDH02", "RSDH03", "RSDH04", "RSDH06", "RSDH07", "RSDH08", "RSDH09", "RSDH10" }; List <string> tags = rootReader.FilterTags(supportedDatasets, true); Random rand = new Random(); string path = fbd.SelectedPath; string segPath = path + "\\segmentation" + penWidth; string imagePath = path + "\\images"; int runningTotal = 0; int count = 0; if (!Directory.Exists(imagePath)) { Directory.CreateDirectory(imagePath); } if (!Directory.Exists(segPath)) { Directory.CreateDirectory(segPath); } foreach (string tag in tags) { var data = rootReader.Read(tag, true); // If no image, skip if (data.Item3 == null) { continue; } SceneMetadata metadata = data.Item1; SceneInfo scene = data.Item2; byte[] imageData = data.Item3; BitmapSource currentImage; using (MemoryStream ms = new MemoryStream(imageData)) { JpegBitmapDecoder decoder = new JpegBitmapDecoder(ms, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default); // Due to what appears to be a bug in .NET, wrapping in a WBMP causes a cache refresh and fixes some image corruption currentImage = new WriteableBitmap(decoder.Frames[0]); } SolidColorBrush scb = new SolidColorBrush(Colors.White); Pen p = new Pen(Brushes.White, penWidth); p.StartLineCap = PenLineCap.Round; p.EndLineCap = PenLineCap.Round; // Obtain all root information Dictionary <String, RootInfo> plantComponents = new Dictionary <string, RootInfo>(); foreach (PlantInfo plant in scene.Plants) { foreach (RootInfo root in plant) { plantComponents.Add(root.RelativeID, root); } } // Initialise conflict data int conflictScale = 30; int conflictWidth = currentImage.PixelWidth / conflictScale; int conflictHeight = currentImage.PixelHeight / conflictScale; int[] rootCount = new int[conflictWidth * conflictHeight]; bool[] rootCounted = new bool[conflictWidth * conflictHeight]; // Crop // Find global plant bounding box double left = double.MaxValue, right = double.MinValue, top = double.MaxValue, bottom = double.MinValue; foreach (var kvp in plantComponents) { SampledSpline spline = kvp.Value.Spline as SampledSpline; if (spline == null) { continue; } Rect r = spline.BoundingBox; if (r.Left < left) { left = r.Left; } if (r.Right > right) { right = r.Right; } if (r.Top < top) { top = r.Top; } if (r.Bottom > bottom) { bottom = r.Bottom; } // If detecting conflict if (conflictOnly) { RootInfo parent = plantComponents.ContainsKey(kvp.Key.Substring(0, kvp.Key.LastIndexOf("."))) ? plantComponents[kvp.Key.Substring(0, kvp.Key.LastIndexOf("."))] : null; if (parent == null) { Array.Clear(rootCounted, 0, rootCounted.Length); foreach (Point splinePoint in spline.SampledPoints) { int conflictX = (int)(splinePoint.X / conflictScale); int conflictY = (int)(splinePoint.Y / conflictScale); int conflictIndex = conflictY * conflictWidth + conflictX; if (!rootCounted[conflictIndex]) { rootCount[conflictIndex]++; rootCounted[conflictIndex] = true; } } } } } // Render to drawingVisual, then image int width = currentImage.PixelWidth; int height = currentImage.PixelHeight; // Optional Crop Int32Rect?cropRectangle = null; if (useCrop) { int cropPadding = 64; int l = Math.Max(0, (int)(left - cropPadding)); int r = Math.Min(width, (int)(right + cropPadding)); int t = Math.Max(0, (int)(top - cropPadding)); int b = Math.Min(height, (int)(bottom + cropPadding)); cropRectangle = new Int32Rect(l, t, r - l, b - t); } RenderTargetBitmap rtb = new RenderTargetBitmap(width, height, 96, 96, PixelFormats.Pbgra32); DrawingVisual drawingVisual = new DrawingVisual(); DrawingContext drawingContext = drawingVisual.RenderOpen(); SolidColorBrush background = new SolidColorBrush(Colors.Black); drawingContext.DrawRectangle(Brushes.Black, null, new Rect(0, 0, width, height)); // Draw splines StreamGeometry geometry = new StreamGeometry(); using (StreamGeometryContext sgc = geometry.Open()) { foreach (var kvp in plantComponents) { SampledSpline spline = kvp.Value.Spline as SampledSpline; if (spline != null) { Point[] points = spline.SampledPoints; // Optional line from start position on parent if (sourceOnly) { // First primary source if (kvp.Value.RelativeID == "1.1") { sgc.BeginFigure(points[0], false, false); sgc.LineTo(points[0], true, true); break; } } if (tipsOnly) { if (primaryOnly) { RootInfo parent = plantComponents.ContainsKey(kvp.Key.Substring(0, kvp.Key.LastIndexOf("."))) ? plantComponents[kvp.Key.Substring(0, kvp.Key.LastIndexOf("."))] : null; if (parent == null) { sgc.BeginFigure(points[points.Length - 2], false, false); sgc.LineTo(points[points.Length - 1], true, true); } } else if (lateralOnly) { RootInfo parent = plantComponents.ContainsKey(kvp.Key.Substring(0, kvp.Key.LastIndexOf("."))) ? plantComponents[kvp.Key.Substring(0, kvp.Key.LastIndexOf("."))] : null; if (parent != null) { sgc.BeginFigure(points[points.Length - 2], false, false); sgc.LineTo(points[points.Length - 1], true, true); } } else { sgc.BeginFigure(points[points.Length - 2], false, false); sgc.LineTo(points[points.Length - 1], true, true); } } else { RootInfo parent = plantComponents.ContainsKey(kvp.Key.Substring(0, kvp.Key.LastIndexOf("."))) ? plantComponents[kvp.Key.Substring(0, kvp.Key.LastIndexOf("."))] : null; if (parent != null) { Point start = parent.Spline.GetPoint(kvp.Value.StartReference); sgc.BeginFigure(new Point(start.X, start.Y), false, false); sgc.LineTo(new Point(points[0].X, points[0].Y), true, true); } else { sgc.BeginFigure(new Point(points[0].X, points[0].Y), false, false); } for (int i = 1; i < points.Length; i++) { sgc.LineTo(new Point(points[i].X, points[i].Y), true, true); } } } } } if (geometry.CanFreeze) { geometry.Freeze(); } drawingContext.DrawGeometry(p.Brush, p, geometry); drawingContext.Close(); rtb.Render(drawingVisual); if (rtb.CanFreeze) { rtb.Freeze(); } // Save original file BitmapEncoder Encoder; if (outputOriginalImages) { Encoder = new PngBitmapEncoder(); using (FileStream FS = File.Open(imagePath + "\\" + count + ".png", FileMode.OpenOrCreate)) { Encoder.Frames.Add(BitmapFrame.Create(useCrop ? new CroppedBitmap(currentImage, cropRectangle.Value) : currentImage)); Encoder.Save(FS); FS.Close(); } } // Create mask from RTB int renderStride = rtb.PixelWidth * 4; byte[] renderArr = new byte[rtb.PixelWidth * rtb.PixelHeight * 4]; rtb.CopyPixels(renderArr, rtb.PixelWidth * 4, 0); WriteableBitmap mask = new WriteableBitmap(rtb.PixelWidth, rtb.PixelHeight, 96.0, 96.0, PixelFormats.Gray8, null); mask.Lock(); byte *ptr = (byte *)mask.BackBuffer.ToPointer(); int stride = mask.BackBufferStride; for (int x = 0; x < mask.PixelWidth; x++) { for (int y = 0; y < mask.PixelHeight; y++) { // Obtain red pixel as representative of gray value byte current = renderArr[y * renderStride + (x * 4) + 1]; if (current > 127) { if (conflictOnly) { int index = (y / conflictScale) * conflictWidth + (x / conflictScale); if (rootCount[index] > 1) { *(ptr + y * stride + x) = 255; } } else { *(ptr + y * stride + x) = 255; } } } } mask.AddDirtyRect(new Int32Rect(0, 0, width, height)); mask.Unlock(); BitmapSource outputMask = mask; Encoder = new PngBitmapEncoder(); using (FileStream FS = File.Open(segPath + "\\" + count.ToString("D4") + ".png", FileMode.OpenOrCreate)) { Encoder.Frames.Add(BitmapFrame.Create(useCrop ? new CroppedBitmap(outputMask, cropRectangle.Value) : outputMask)); Encoder.Save(FS); FS.Close(); } count++; runningTotal++; if (runningTotal > 20) { runningTotal -= 20; GC.Collect(); GC.WaitForPendingFinalizers(); } } } }
private void ReadGeometry(XmlNode geometryNode, out Polyline polyLine, out SampledSpline spline) { polyLine = null; spline = null; // Polyline XmlNode polylineNode = geometryNode.SelectSingleNode("polyline"); if (polylineNode != null) { polyLine = new Polyline() { Points = new List <Point3D>() }; foreach (XmlNode pointNode in polylineNode.SelectNodes("point")) { polyLine.Points.Add(ReadPoint(pointNode)); } } // Load <spline></spline> tags if available XmlNode splineNode = geometryNode.SelectSingleNode("rootnavspline"); if (splineNode != null) { List <System.Windows.Point> controlPoints = new List <System.Windows.Point>(); foreach (XmlNode pointNode in splineNode.SelectNodes("point")) { Point3D p = ReadPoint(pointNode); controlPoints.Add(new System.Windows.Point(p.X, p.Y)); } XmlNode tensionAttr = splineNode.Attributes["tension"]; XmlNode separationAttr = splineNode.Attributes["controlpointseparation"]; double tension; int controlPointSeparation; if (tensionAttr == null || !double.TryParse(tensionAttr.InnerText, System.Globalization.NumberStyles.Any, nullInfo, out tension)) { tension = 0.5; } if (separationAttr == null || !Int32.TryParse(separationAttr.InnerText, out controlPointSeparation)) { controlPointSeparation = 40; } spline = new SampledSpline(); spline.InitialiseFromControlPoints(controlPoints, tension, controlPointSeparation); } else { // Create spline based on polyline List <System.Windows.Point> splinePoints = new List <System.Windows.Point>(); if (polyLine != null) { foreach (Point3D p in polyLine.Points) { splinePoints.Add(new System.Windows.Point(p.X, p.Y)); } } if (splinePoints.Count >= 2) { spline = new SampledSpline(); spline.InitialiseWithVectorList(splinePoints); } } return; }
private List <ImageSource> CreateSeparatePlantImages(List <PlantInfo> plants, out List <Point> sourcePositions) { sourcePositions = new List <Point>(); var outputImages = new List <ImageSource>(); Pen p = new Pen(Brushes.Black, 6.0); p.StartLineCap = PenLineCap.Round; p.EndLineCap = PenLineCap.Round; List <Dictionary <String, RootInfo> > plantComponents = new List <Dictionary <string, RootInfo> >(); int index = 0; foreach (PlantInfo plant in plants) { plantComponents.Insert(index, new Dictionary <string, RootInfo>()); foreach (RootInfo root in plant) { // Start of first primary is the plant source if (root.RelativeID == plant.RelativeID + ".1") { sourcePositions.Add(new Point(root.Spline.Start.X, root.Spline.Start.Y)); } plantComponents[index].Add(root.RelativeID, root); } index++; } // For each plant, create a new image for (int i = 0; i < plantComponents.Count; i++) { var plantComponentDictionary = plantComponents[i]; // Find global plant bounding box double left = double.MaxValue, right = double.MinValue, top = double.MaxValue, bottom = double.MinValue; foreach (var components in plantComponentDictionary.Values) { SampledSpline spline = components.Spline as SampledSpline; if (spline == null) { continue; } Rect r = spline.BoundingBox; if (r.Left < left) { left = r.Left; } if (r.Right > right) { right = r.Right; } if (r.Top < top) { top = r.Top; } if (r.Bottom > bottom) { bottom = r.Bottom; } } int width = (int)right - (int)left + 8; int height = (int)bottom - (int)top + 8; RenderTargetBitmap rtb = new RenderTargetBitmap(width, height, 96, 96, PixelFormats.Pbgra32); DrawingVisual drawingVisual = new DrawingVisual(); DrawingContext drawingContext = drawingVisual.RenderOpen(); drawingContext.DrawRectangle(Brushes.White, null, new Rect(0, 0, width, height)); // Draw splines StreamGeometry geometry = new StreamGeometry(); using (StreamGeometryContext sgc = geometry.Open()) { foreach (var kvp in plantComponentDictionary) { SampledSpline spline = kvp.Value.Spline as SampledSpline; if (spline != null) { Point[] points = spline.SampledPoints; // Optional line from start position on parent RootInfo parent = plantComponentDictionary.ContainsKey(kvp.Key.Substring(0, kvp.Key.LastIndexOf("."))) ? plantComponentDictionary[kvp.Key.Substring(0, kvp.Key.LastIndexOf("."))] : null; if (parent != null) { Point start = parent.Spline.GetPoint(kvp.Value.StartReference); sgc.BeginFigure(new Point(start.X - left + 4, start.Y - top + 4), false, false); sgc.LineTo(new Point(points[0].X - left + 4, points[0].Y - top + 4), true, true); } else { sgc.BeginFigure(new Point(points[0].X - left + 4, points[0].Y - top + 4), false, false); } for (int i2 = 1; i2 < points.Length; i2++) { sgc.LineTo(new Point(points[i2].X - left + 4, points[i2].Y - top + 4), true, true); } } } } if (geometry.CanFreeze) { geometry.Freeze(); } drawingContext.DrawGeometry(null, p, geometry); sourcePositions[i] = new Point(sourcePositions[i].X - left + 4, sourcePositions[i].Y - top + 4); drawingContext.Close(); rtb.Render(drawingVisual); if (rtb.CanFreeze) { rtb.Freeze(); } outputImages.Add(rtb); } return(outputImages); }
public override object MeasurePlant(PlantInfo plant) { double min = Int32.MaxValue; double max = Int32.MinValue; HashSet <Point> rootPoints = new HashSet <Point>(); foreach (RootInfo root in plant) { SampledSpline s = root.Spline; Point[] splinePoints = s.Rasterise(); foreach (Point p in splinePoints) { rootPoints.Add(p); if (p.Y < min) { min = p.Y; } if (p.Y > max) { max = p.Y; } } } List <int>[] xs = new List <int> [(int)max - (int)min + 1]; for (int i = 0; i < xs.Length; i++) { xs[i] = new List <int>(); } foreach (Point p in rootPoints) { xs[(int)p.Y - (int)min].Add((int)p.X); } int[] widths = new int[xs.Length]; for (int pos = 0; pos < xs.Length; pos++) { if (xs[pos].Count > 0) { int submin = xs[pos].Min(); int submax = xs[pos].Max(); widths[pos] = submax - submin + 1; } else { widths[pos] = 0; } } int rowCount = widths.Length; List <List <object> > data = new List <List <object> >() { new List <object>(), new List <object>() }; data[0].Add("Distance"); data[1].Add(""); // Obtain the curvature profile at the specified resolution for (int row = 0; row < rowCount; row++) { data[0].Add(row); data[1].Add(widths[row]); } return(data); }
public Tuple <SceneMetadata, SceneInfo, byte[]> Read(String tag, bool image) { SceneInfo scene; SceneMetadata metadata; MySqlConnection connection = dbm.Connection as MySqlConnection; MySqlCommand selectCommand = new MySqlCommand("SELECT Stamp, RelativeID, StartReference, Spline, Label, CompleteArchitecture, User, HullArea FROM rootdata WHERE Tag = (?tag)", connection); selectCommand.Parameters.AddWithValue("?tag", tag); Dictionary <Tuple <String, DateTime>, List <RootInfo> > roots = new Dictionary <Tuple <String, DateTime>, List <RootInfo> >(); DateTime stamp = DateTime.Now; bool complete = true; HashSet <String> plantIDs = new HashSet <string>(); string user = ""; using (MySqlDataReader Reader = selectCommand.ExecuteReader()) { while (Reader.Read()) { if (user == "") { user = Reader.GetString("User"); } stamp = Reader.GetDateTime("Stamp"); String relativeID = Reader.GetString("RelativeID"); SampledSpline spline = null; complete = Reader.GetBoolean("CompleteArchitecture"); string label = null; if (!Reader.IsDBNull(4)) { label = Reader.GetString("Label"); } if (!Reader.IsDBNull(3)) { try { spline = RootNav.Data.SplineSerializer.BinaryToObject((byte[])Reader["Spline"]) as SampledSpline; } catch { spline = null; } } SplinePositionReference position = null; if (!Reader.IsDBNull(2)) { position = RootNav.Data.SplineSerializer.BinaryToObject((byte[])Reader["StartReference"]) as SplinePositionReference; } String key = relativeID.IndexOf('.') < 0 ? relativeID : relativeID.Substring(0, relativeID.IndexOf('.')); Tuple <string, DateTime> datedKey = new Tuple <string, DateTime>(key, stamp); if (!roots.ContainsKey(datedKey)) { roots.Add(datedKey, new List <RootInfo>()); } roots[datedKey].Add(new RootInfo() { RelativeID = relativeID, StartReference = position, Spline = spline, Label = label, Stamp = stamp }); } var timeSeparatedRoots = DuplicateTagCheck(roots); List <PlantInfo> plants = new List <PlantInfo>(); foreach (var timeStampedKVP in timeSeparatedRoots) { DateTime currentStamp = timeStampedKVP.Key; var stampedRoots = timeStampedKVP.Value; foreach (var kvp in stampedRoots) { plants.Add(PlantInfo.CreateTree(tag, currentStamp, complete, kvp.Value)); } } metadata = new SceneMetadata() { Key = tag, Complete = complete, Sequence = null, User = user, Software = "RootNav", Resolution = 1.0, Unit = "pixel", }; scene = new SceneInfo() { Plants = plants }; } // Optional image search byte[] imageData = null; if (image) { connection = dbm.Connection as MySqlConnection; MySqlCommand imageCommand = new MySqlCommand("SELECT Image FROM images WHERE Tag = (?tag) AND Stamp = (?stamp)", connection); imageCommand.Parameters.AddWithValue("?tag", tag); imageCommand.Parameters.AddWithValue("?stamp", stamp); using (MySqlDataReader imageReader = imageCommand.ExecuteReader()) { if (imageReader.HasRows) { imageReader.Read(); imageData = imageReader["Image"] as byte[]; } } } return(new Tuple <SceneMetadata, SceneInfo, byte[]> (metadata, scene, imageData)); }