public void CreateNewStarAnnotation() { // Create annotation group and add it to the chart annotations collection AnnotationGroup star = new AnnotationGroup(); star.X = 20; star.Y = 20; star.Width = 30; star.Height = 20; star.AllowSelecting = true; star.AllowMoving = true; star.AllowResizing = true; Chart1.Annotations.Add(star); // Add star shaped polygon annotation into the group PointF[] starPolygon = new PointF[] { new PointF(1, 6), new PointF(27, 23), new PointF(33, 5), new PointF(44, 22), new PointF(58, 0), new PointF(57, 19), new PointF(75, 11), new PointF(70, 28), new PointF(100, 37), new PointF(81, 53), new PointF(99, 65), new PointF(75, 67), new PointF(87, 98), new PointF(63, 69), new PointF(60, 94), new PointF(47, 69), new PointF(34, 100), new PointF(32, 69), new PointF(23, 74), new PointF(26, 61), new PointF(4, 72), new PointF(22, 49), new PointF(0, 39), new PointF(23, 32), new PointF(1, 6) }; GraphicsPath starPath = new GraphicsPath(); starPath.AddPolygon(starPolygon); PolygonAnnotation poly = new PolygonAnnotation(); poly.Name = "Star"; poly.GraphicsPath = starPath; star.Annotations.Add(poly); // Set star polygon annotation position and appearance star.Annotations["Star"].X = 0; star.Annotations["Star"].Y = 0; star.Annotations["Star"].Width = 100; star.Annotations["Star"].Height = 100; star.Annotations["Star"].LineColor = Color.FromArgb(64, 64, 64); star.Annotations["Star"].BackColor = Color.FromArgb(220, 255, 255, 192); star.Annotations["Star"].ShadowOffset = 2; // Add text in the middle of the star shape TextAnnotation textAnnotation = new TextAnnotation(); textAnnotation.Name = "StarText"; textAnnotation.Text = "New !!!"; textAnnotation.X = 20; textAnnotation.Y = 20; textAnnotation.Width = 60; textAnnotation.Height = 60; star.Annotations.Add(textAnnotation); star.Annotations["StarText"].Font = new Font("MS Sans Serif", 10, FontStyle.Bold | FontStyle.Italic); star.Annotations["StarText"].ForeColor = Color.FromArgb(26, 59, 105); }
public static void EndGroup() { if (_activeGroup != null) { _activeShaderGroup.Buffers.Add(_activeGroup); // Images do not use pack _activeGroup.BufferSize = _curOffset.RoundUpMultiple16(); _activeGroup = null; } }
/// <summary> /// Mouse was double clicked. /// </summary> internal void OnDoubleClick() { if (lastClickedAnnotation != null && lastClickedAnnotation.AllowTextEditing) { TextAnnotation textAnnotation = lastClickedAnnotation as TextAnnotation; if (textAnnotation == null) { AnnotationGroup group = lastClickedAnnotation as AnnotationGroup; if (group != null) { // Try to edit text annotation in the group foreach (Annotation annot in group.Annotations) { TextAnnotation groupAnnot = annot as TextAnnotation; if (groupAnnot != null && groupAnnot.AllowTextEditing) { // Get annotation position in relative coordinates PointF firstPoint = PointF.Empty; PointF anchorPoint = PointF.Empty; SizeF size = SizeF.Empty; groupAnnot.GetRelativePosition(out firstPoint, out size, out anchorPoint); RectangleF textPosition = new RectangleF(firstPoint, size); // Check if last clicked coordinate is inside this text annotation if (groupAnnot.GetGraphics() != null && textPosition.Contains(groupAnnot.GetGraphics().GetRelativePoint(this._movingResizingStartPoint))) { textAnnotation = groupAnnot; lastClickedAnnotation = textAnnotation; break; } } } } } if (textAnnotation != null) { // Start annotation text editing textAnnotation.BeginTextEditing(); } } }
/// <summary> /// Find all annotated NormalizedBBox. /// </summary> /// <param name="anno_datum">Specifies the annotated datum.</param> /// <returns>The grouped object BBoxes are returned.</returns> public List <NormalizedBBox> GroupObjectBBoxes(SimpleDatum anno_datum) { List <NormalizedBBox> rgObjectBboxes = new List <NormalizedBBox>(); if (anno_datum.annotation_group == null) { return(rgObjectBboxes); } for (int i = 0; i < anno_datum.annotation_group.Count; i++) { AnnotationGroup anno_group = anno_datum.annotation_group[i]; for (int j = 0; j < anno_group.annotations.Count; j++) { Annotation annotation = anno_group.annotations[j]; rgObjectBboxes.Add(annotation.bbox); } } return(rgObjectBboxes); }
internal void ChartAreaNameReferenceChanged(object sender, NameReferenceChangedEventArgs e) { // If all the chart areas are removed and then a new one is inserted - Annotations don't get bound to it by default if (e.OldElement == null) { return; } foreach (Annotation annotation in this) { if (annotation.ClipToChartArea == e.OldName) { annotation.ClipToChartArea = e.NewName; } AnnotationGroup group = annotation as AnnotationGroup; if (group != null) { group.Annotations.ChartAreaNameReferenceChanged(sender, e); } } }
/// <summary> /// Finds an annotation in the collection by name. /// </summary> /// <param name="name"> /// Name of the annotation to find. /// </param> /// <returns> /// <see cref="Annotation"/> object, or null (or nothing) if it does not exist. /// </returns> public override Annotation FindByName(string name) { foreach (Annotation annotation in this) { // Compare annotation name if (annotation.Name == name) { return(annotation); } // Check if annotation is a group AnnotationGroup annotationGroup = annotation as AnnotationGroup; if (annotationGroup != null) { Annotation result = annotationGroup.Annotations.FindByName(name); if (result != null) { return(result); } } } return(null); }
private bool loadXmlAnnotationFile(Log log, string strFile, SimpleDatum datum, Dictionary <string, int> rgNameToLabel) { XDocument doc = XDocument.Load(strFile); XElement size = doc.Descendants("size").First(); XElement val; val = size.Descendants("width").First(); int nWidth = int.Parse(val.Value); val = size.Descendants("height").First(); int nHeight = int.Parse(val.Value); val = size.Descendants("depth").First(); int nChannels = int.Parse(val.Value); if (datum.Height != nHeight || datum.Width != nWidth || datum.Channels != nChannels) { log.FAIL("Inconsistent image size, expected (" + datum.Channels.ToString() + "," + datum.Height.ToString() + "," + datum.Width.ToString() + ") but annotation has size (" + nChannels.ToString() + "," + nHeight.ToString() + "," + nWidth.ToString() + ")."); } int nInstanceId = 0; List <XElement> objects = doc.Descendants("object").ToList(); foreach (XElement obj in objects) { val = obj.Descendants("name").First(); string strName = val.Value; val = obj.Descendants("difficult").First(); bool bDifficult = (val.Value == "0") ? false : true; XElement bndbox = obj.Descendants("bndbox").First(); val = bndbox.Descendants("xmin").First(); float fxmin = float.Parse(val.Value); if (fxmin > nWidth || fxmin < 0) { log.WriteLine("WARNING: '" + strFile + "' bounding box exceeds image boundary."); } val = bndbox.Descendants("ymin").First(); float fymin = float.Parse(val.Value); if (fymin > nHeight || fymin < 0) { log.WriteLine("WARNING: '" + strFile + "' bounding box exceeds image boundary."); } val = bndbox.Descendants("xmax").First(); float fxmax = float.Parse(val.Value); if (fxmax > nWidth || fxmax < 0) { log.WriteLine("WARNING: '" + strFile + "' bounding box exceeds image boundary."); } val = bndbox.Descendants("ymax").First(); float fymax = float.Parse(val.Value); if (fymax > nHeight || fymax < 0) { log.WriteLine("WARNING: '" + strFile + "' bounding box exceeds image boundary."); } if (!rgNameToLabel.ContainsKey(strName)) { log.FAIL("Could not find the label '" + strName + "' in the label mapping!"); return(false); } int nLabel = rgNameToLabel[strName]; NormalizedBBox bbox = new NormalizedBBox(fxmin / nWidth, fymin / nHeight, fxmax / nWidth, fymax / nHeight, nLabel, bDifficult); datum.SetLabel(nLabel); foreach (AnnotationGroup g in datum.annotation_group) { if (nLabel == g.group_label) { if (g.annotations.Count == 0) { nInstanceId = 0; } else { nInstanceId = g.annotations[g.annotations.Count - 1].instance_id + 1; } g.annotations.Add(new Annotation(bbox, nInstanceId)); bbox = null; break; } } if (bbox != null) { nInstanceId = 0; AnnotationGroup grp = new AnnotationGroup(null, nLabel); grp.annotations.Add(new Annotation(bbox, nInstanceId)); datum.annotation_group.Add(grp); bbox = null; } } return(true); }
/// <summary> /// Load a batch of data in the background (this is run on an internal thread within the BasePrefetchingDataLayer class). /// </summary> /// <param name="batch">Specifies the Batch of data to load.</param> protected override void load_batch(Batch <T> batch) { m_log.CHECK(batch.Data.count() > 0, "There is no space allocated for data!"); if (m_param.data_param.display_timing) { m_swTimerBatch.Restart(); m_dfReadTime = 0; m_dfTransTime = 0; } if (m_bOutputLabels) { int nCount = batch.Label.count(); m_log.CHECK_GT(nCount, 0, "The label count cannot be zero!"); if (m_rgTopLabel == null || m_rgTopLabel.Length < nCount) { m_rgTopLabel = new T[nCount]; } } // Reshape according to the first anno_datum of each batch // ont single input batches allows for inputs of varying dimension. int nBatchSize = (int)m_param.data_param.batch_size; SimpleDatum datum; int nDim = 0; int nNumBboxes = 0; Dictionary <int, List <AnnotationGroup> > rgAllAnno = null; List <int> rgTopShape = null; bool bLabelDirty = false; for (int i = 0; i < nBatchSize; i++) { if (m_param.data_param.display_timing) { m_swTimerTransaction.Restart(); } while (Skip()) { if (m_evtCancel.WaitOne(0)) { return; } Next(); } datum = m_cursor.GetValue(null, true); if (m_param.data_param.display_timing) { m_dfReadTime += m_swTimerTransaction.Elapsed.TotalMilliseconds; m_swTimerTransaction.Restart(); } if (i == 0) { // Reshape according to the first datum of each batch // on single input batches allows for inputs of varying dimension. // Use data transformer to infer the expected blob shape for datum. rgTopShape = m_transformer.InferBlobShape(datum); rgTopShape[0] = nBatchSize; batch.Data.Reshape(rgTopShape); nDim = 1; for (int k = 1; k < rgTopShape.Count; k++) { nDim *= rgTopShape[k]; } int nTopLen = nDim * nBatchSize; if (m_rgTopData == null || m_rgTopData.Length != nTopLen) { m_rgTopData = new T[nTopLen]; } } SimpleDatum distort_datum = null; SimpleDatum expand_datum = null; if (m_param.transform_param.distortion_param != null && m_param.transform_param.distortion_param.Active) { distort_datum = m_transformer.DistortImage(datum); if (m_param.transform_param.expansion_param != null && m_param.transform_param.expansion_param.Active) { expand_datum = m_transformer.ExpandImage(distort_datum); } else { expand_datum = distort_datum; } } else if (m_param.transform_param.expansion_param != null && m_param.transform_param.expansion_param.Active) { expand_datum = m_transformer.ExpandImage(datum); } else { expand_datum = datum; } SimpleDatum sampled_datum = expand_datum; // Generate sampled bboxes from expand_datum. if (m_rgBatchSamplers.Count > 0) { List <NormalizedBBox> rgSampledBboxes = m_sampler.GenerateBatchSamples(expand_datum, m_rgBatchSamplers); // Randomly pick a sampled bbox and crop the expand_datum. if (rgSampledBboxes.Count > 0) { int nIdx = m_random.Next(rgSampledBboxes.Count); sampled_datum = m_transformer.CropImage(expand_datum, rgSampledBboxes[nIdx]); } } m_log.CHECK(sampled_datum != null, "The sampled datum cannot be null!"); List <int> rgShape = m_transformer.InferBlobShape(sampled_datum); if (m_param.transform_param.resize_param != null && m_param.transform_param.resize_param.Active) { if (m_param.transform_param.resize_param.resize_mode == ResizeParameter.ResizeMode.FIT_SMALL_SIZE) { batch.Data.Reshape(rgShape); } } // Apply data transformations (mirror, scale, crop...) int nOffset = batch.Data.offset(i); List <AnnotationGroup> rgTransformedAnnoVec; if (m_bOutputLabels) { if (m_AnnoType != SimpleDatum.ANNOTATION_TYPE.NONE) { // Make sure all data have same annoation type. if (m_param.annotated_data_param.anno_type != SimpleDatum.ANNOTATION_TYPE.NONE) { sampled_datum.annotation_type = m_AnnoType; } else { m_log.CHECK_EQ((int)m_AnnoType, (int)sampled_datum.annotation_type, "The sampled datum has a different AnnoationType!"); } // Transform datum and annotation_group at the same time. bool bMirror; T[] rgTrans = m_transformer.Transform(sampled_datum, out rgTransformedAnnoVec, out bMirror); Array.Copy(rgTrans, 0, m_rgTopData, nDim * i, nDim); // Count the number of bboxes. if (m_AnnoType == SimpleDatum.ANNOTATION_TYPE.BBOX) { for (int g = 0; g < rgTransformedAnnoVec.Count; g++) { nNumBboxes += rgTransformedAnnoVec[g].annotations.Count; } } else { m_log.FAIL("Unknown annotation type."); } if (rgAllAnno == null) { rgAllAnno = new Dictionary <int, List <AnnotationGroup> >(); } rgAllAnno.Add(i, rgTransformedAnnoVec); } else { T[] rgTrans = m_transformer.Transform(sampled_datum); Array.Copy(rgTrans, 0, m_rgTopData, nDim * i, nDim); // Otherwise, store the label from datum. if (m_param.data_param.label_type == DataParameter.LABEL_TYPE.MULTIPLE) { if (datum.DataCriteria == null || datum.DataCriteria.Length == 0) { m_log.FAIL("Could not find the multi-label data. The data source '" + m_param.data_param.source + "' does not appear to have any Image Criteria data."); } // Get the number of items and the item size from the end of the data. int nLen = BitConverter.ToInt32(datum.DataCriteria, datum.DataCriteria.Length - (sizeof(int) * 4)); int nItemSize = BitConverter.ToInt32(datum.DataCriteria, datum.DataCriteria.Length - (sizeof(int) * 3)); int nDstIdx = i * nLen; m_log.CHECK_EQ(nItemSize, 1, "Currently only byte sized labels are supported in multi-label scenarios."); Array.Copy(datum.DataCriteria, 0, m_rgTopLabel, nDstIdx, nLen); } else { m_rgTopLabel[i] = (T)Convert.ChangeType(datum.Label, typeof(T)); } bLabelDirty = true; } } if (m_param.data_param.display_timing) { m_dfTransTime += m_swTimerTransaction.Elapsed.TotalMilliseconds; } Next(); if (m_evtCancel.WaitOne(0)) { return; } } batch.Data.SetCPUData(m_rgTopData); if (m_bOutputLabels && bLabelDirty) { batch.Label.SetCPUData(m_rgTopLabel); } // Store 'rich' annotation if needed. if (m_bOutputLabels && m_AnnoType != SimpleDatum.ANNOTATION_TYPE.NONE) { List <int> rgLabelShape = Utility.Create <int>(4, 1); if (m_AnnoType == SimpleDatum.ANNOTATION_TYPE.BBOX) { rgLabelShape[0] = 1; rgLabelShape[1] = 1; rgLabelShape[3] = 8; if (nNumBboxes == 0) { // Store all -1 in the label. rgLabelShape[2] = 1; batch.Label.Reshape(rgLabelShape); for (int i = 0; i < m_rgTopLabel.Length; i++) { m_rgTopLabel[i] = m_tMinusOne; } batch.Label.SetCPUData(m_rgTopLabel); } else { // Reshape the label and store the annotation. rgLabelShape[2] = nNumBboxes; batch.Label.Reshape(rgLabelShape); int nCount = batch.Label.count(); m_log.CHECK_GT(nCount, 0, "The label count cannot be zero!"); float[] rgTopLabel1 = new float[nCount]; int nIdx = 0; for (int i = 0; i < nBatchSize; i++) { List <AnnotationGroup> rgAnnoGroups = rgAllAnno[i]; for (int g = 0; g < rgAnnoGroups.Count; g++) { AnnotationGroup anno_group = rgAnnoGroups[g]; for (int a = 0; a < anno_group.annotations.Count; a++) { Annotation anno = anno_group.annotations[a]; NormalizedBBox bbox = anno.bbox; rgTopLabel1[nIdx] = i; nIdx++; rgTopLabel1[nIdx] = anno_group.group_label; nIdx++; rgTopLabel1[nIdx] = anno.instance_id; nIdx++; rgTopLabel1[nIdx] = bbox.xmin; nIdx++; rgTopLabel1[nIdx] = bbox.ymin; nIdx++; rgTopLabel1[nIdx] = bbox.xmax; nIdx++; rgTopLabel1[nIdx] = bbox.ymax; nIdx++; rgTopLabel1[nIdx] = (bbox.difficult) ? 1 : 0; nIdx++; } } } batch.Label.SetCPUData(convert(rgTopLabel1)); } } else { m_log.FAIL("Unknown annotation type."); } } if (m_param.data_param.display_timing) { m_swTimerBatch.Stop(); m_swTimerTransaction.Stop(); m_log.WriteLine("Prefetch batch: " + m_swTimerBatch.ElapsedMilliseconds.ToString() + " ms.", true); m_log.WriteLine(" Read time: " + m_dfReadTime.ToString() + " ms.", true); m_log.WriteLine("Transform time: " + m_dfTransTime.ToString() + " ms.", true); } }
/// <summary> /// Transform the annotation data. /// </summary> /// <param name="d">Data to transform.</param> /// <param name="crop_bbox">Specifies the crop_bbox defined for the data.</param> /// <param name="bMirror">Specifies to mirror the data.</param> /// <param name="bResize">Specifies to resize the data.</param> /// <returns></returns> public List <AnnotationGroup> TransformAnnotation(SimpleDatum d, NormalizedBBox crop_bbox, bool bMirror, bool bResize) { int nImgHt = d.Height; int nImgWd = d.Width; List <AnnotationGroup> rgTransformedAnnotationGroup = new List <AnnotationGroup>(); if (d.annotation_type == SimpleDatum.ANNOTATION_TYPE.BBOX) { // Go through each AnnotationGroup. for (int g = 0; g < d.annotation_group.Count; g++) { // Go through each Annoation. bool bHasValidAnnotation = false; AnnotationGroup anno_group = d.annotation_group[g]; AnnotationGroup transformed_anno_group = new AnnotationGroup(); for (int a = 0; a < anno_group.annotations.Count; a++) { Annotation anno = anno_group.annotations[a]; NormalizedBBox bbox = anno.bbox; // Adjust bounding box annoation. NormalizedBBox resize_bbox = bbox; if (bResize && m_param.resize_param != null) { m_log.CHECK_GT(nImgHt, 0, "The image height must be > 0!"); m_log.CHECK_GT(nImgWd, 0, "The image width must be > 0!"); resize_bbox = m_imgTransforms.UpdateBBoxByResizePolicy(m_param.resize_param, nImgWd, nImgHt, resize_bbox); } if (m_param.emit_constraint != null && m_bbox.MeetEmitConstraint(crop_bbox, resize_bbox, m_param.emit_constraint)) { continue; } NormalizedBBox proj_bbox; if (m_bbox.Project(crop_bbox, resize_bbox, out proj_bbox)) { bHasValidAnnotation = true; Annotation transformed_anno = new Annotation(proj_bbox.Clone(), anno.instance_id); NormalizedBBox transformed_bbox = transformed_anno.bbox; if (bMirror) { float fTemp = transformed_bbox.xmin; transformed_bbox.xmin = 1 - transformed_bbox.xmax; transformed_bbox.xmax = 1 - fTemp; } else if (bResize && m_param.resize_param != null) { m_bbox.Extrapolate(m_param.resize_param, nImgHt, nImgWd, crop_bbox, transformed_bbox); } transformed_anno_group.annotations.Add(transformed_anno); } } // Save for output. if (bHasValidAnnotation) { transformed_anno_group.group_label = anno_group.group_label; rgTransformedAnnotationGroup.Add(transformed_anno_group); } } } else { m_log.FAIL("Unknown annotation type."); } return(rgTransformedAnnotationGroup); }
public static void BeginGroup() { _activeGroup = new AnnotationGroup(); _curOffset = 0; }
public static void DestroyGroup() { _activeVar = null; _activeGroup = null; }