浏览代码

No boxes on unmatching objects (#67)

* Do not report bounding boxes for objects that do not match the label config.

* Add test.

* Updating changelog

* Attempting to fix test

* Removing editor platforms for a test that gives unstable output in editors
/main
GitHub 4 年前
当前提交
acad175e
共有 7 个文件被更改,包括 62 次插入20 次删除
  1. 2
      com.unity.perception/CHANGELOG.md
  2. 18
      com.unity.perception/Runtime/GroundTruth/DatasetCapture.cs
  3. 11
      com.unity.perception/Runtime/GroundTruth/Labelers/BoundingBoxLabeler.cs
  4. 21
      com.unity.perception/Runtime/GroundTruth/SimulationState.cs
  5. 9
      com.unity.perception/Tests/Runtime/GroundTruthTests/DatasetCaptureTests.cs
  6. 15
      com.unity.perception/Tests/Runtime/GroundTruthTests/PerceptionCameraIntegrationTests.cs
  7. 6
      com.unity.perception/Tests/Runtime/GroundTruthTests/TestHelper.cs

2
com.unity.perception/CHANGELOG.md


### Removed
### Fixed
Fixed 2d bounding boxes being reported for objects that do not match the label config.
Fixed a categorical parameter UI error in which deleting an individual option would successfully remove the option from the UI but only serialize the option to null during serialization instead of removing it
Fixed the "Application Frequency" parameter UI field not initializing to a default value

18
com.unity.perception/Runtime/GroundTruth/DatasetCapture.cs


using System;
using System.Collections.Generic;
using Unity.Collections;
using Unity.Simulation;
using UnityEngine;

/// <param name="values">The annotation data.</param>
/// <typeparam name="T">The type of the data.</typeparam>
/// <exception cref="ArgumentNullException">Thrown if values is null</exception>
public void ReportValues<T>(T[] values)
public void ReportValues<T>(IEnumerable<T> values)
{
if (values == null)
throw new ArgumentNullException(nameof(values));
m_SimulationState.ReportAsyncAnnotationResult(this, values: values);
}
/// <summary>
/// Report a value-based data for this annotation.
/// </summary>
/// <param name="values">The annotation data.</param>
/// <typeparam name="T">The type of the data.</typeparam>
/// <exception cref="ArgumentNullException">Thrown if values is null</exception>
public void ReportValues<T>(NativeSlice<T> values) where T : struct
{
if (values == null)
throw new ArgumentNullException(nameof(values));

11
com.unity.perception/Runtime/GroundTruth/Labelers/BoundingBoxLabeler.cs


Dictionary<int, AsyncAnnotation> m_AsyncAnnotations;
AnnotationDefinition m_BoundingBoxAnnotationDefinition;
BoundingBoxValue[] m_BoundingBoxValues;
List<BoundingBoxValue> m_BoundingBoxValues;
Vector2 m_OriginalScreenSize = Vector2.zero;

throw new InvalidOperationException("BoundingBox2DLabeler's idLabelConfig field must be assigned");
m_AsyncAnnotations = new Dictionary<int, AsyncAnnotation>();
m_BoundingBoxValues = new List<BoundingBoxValue>();
m_BoundingBoxAnnotationDefinition = DatasetCapture.RegisterAnnotationDefinition("bounding box", idLabelConfig.GetAnnotationSpecification(),
"Bounding box for each labeled object visible to the sensor", id: new Guid(annotationId));

using (s_BoundingBoxCallback.Auto())
{
if (m_BoundingBoxValues == null || m_BoundingBoxValues.Length != renderedObjectInfos.Length)
m_BoundingBoxValues = new BoundingBoxValue[renderedObjectInfos.Length];
m_BoundingBoxValues.Clear();
for (var i = 0; i < renderedObjectInfos.Length; i++)
{
var objectInfo = renderedObjectInfos[i];

m_BoundingBoxValues[i] = new BoundingBoxValue
m_BoundingBoxValues.Add(new BoundingBoxValue
{
label_id = labelEntry.id,
label_name = labelEntry.label,

width = objectInfo.boundingBox.width,
height = objectInfo.boundingBox.height,
};
});
}
if (!CaptureOptions.useAsyncReadbackIfSupported && frameCount != Time.frameCount)

21
com.unity.perception/Runtime/GroundTruth/SimulationState.cs


using System.IO;
using System.Linq;
using Newtonsoft.Json.Linq;
using Unity.Collections;
using Unity.Simulation;
using UnityEngine;
using UnityEngine.Profiling;

return new AsyncAnnotation(ReportAnnotationFile(annotationDefinition, sensorHandle, null), this);
}
public void ReportAsyncAnnotationResult<T>(AsyncAnnotation asyncAnnotation, string filename = null, T[] values = null)
public void ReportAsyncAnnotationResult<T>(AsyncAnnotation asyncAnnotation, string filename = null, NativeSlice<T> values = default) where T : struct
{
var jArray = new JArray();
foreach (var value in values)
jArray.Add(new JRaw(DatasetJsonUtility.ToJToken(value)));
ReportAsyncAnnotationResult<T>(asyncAnnotation, filename, jArray);
}
public void ReportAsyncAnnotationResult<T>(AsyncAnnotation asyncAnnotation, string filename = null, IEnumerable<T> values = null)
{
var jArray = values == null ? null : JArray.FromObject(values);
ReportAsyncAnnotationResult<T>(asyncAnnotation, filename, jArray);
}
void ReportAsyncAnnotationResult<T>(AsyncAnnotation asyncAnnotation, string filename, JArray jArray)
{
if (!asyncAnnotation.IsPending)
throw new InvalidOperationException("AsyncAnnotation has already been reported and cannot be reported again.");

var annotationData = annotationTuple.Item2;
annotationData.Path = filename;
annotationData.ValuesJson = values == null ? null : JArray.FromObject(values);
annotationData.ValuesJson = jArray;
annotationTuple.Item2 = annotationData;
pendingCapture.Annotations[annotationIndex] = annotationTuple;

9
com.unity.perception/Tests/Runtime/GroundTruthTests/DatasetCaptureTests.cs


if (escapeGuids)
jsonActual = EscapeGuids(jsonActual);
if (ignoreFormatting)
{
jsonActual = Regex.Replace(jsonActual, "^\\s*", "", RegexOptions.Multiline);
jsonExpected = Regex.Replace(jsonExpected, "^\\s*", "", RegexOptions.Multiline);
}
jsonActual = TestHelper.NormalizeJson(jsonActual);
jsonExpected = TestHelper.NormalizeJson(jsonExpected);
jsonActual = TestHelper.NormalizeJson(jsonActual, ignoreFormatting);
jsonExpected = TestHelper.NormalizeJson(jsonExpected, ignoreFormatting);
Assert.AreEqual(jsonExpected, jsonActual, $"Expected:\n{jsonExpected}\nActual:\n{jsonActual}");
}

15
com.unity.perception/Tests/Runtime/GroundTruthTests/PerceptionCameraIntegrationTests.cs


//give the screen a chance to resize
yield return null;
var jsonExpected = $@" {{
var jsonExpected = $@"[
{{
""label_id"": 100,
""label_name"": ""label"",
""instance_id"": 1,

""height"": {Screen.height / 2:F1}
}}";
}}
]";
var labelingConfiguration = CreateLabelingConfiguration();
SetupCamera(pc =>
{

AddTestObjectForCleanup(plane);
//a plane is 10x10 by default, so scale it down to be 10x1 to cover the center half of the image
plane.transform.localScale = new Vector3(10f, -1f, .1f);
plane.transform.localPosition = new Vector3(0, 0, 10);
var plane2 = TestHelper.CreateLabeledPlane(label: "nonmatching");
AddTestObjectForCleanup(plane2);
//place a smaller plane in front to test non-matching objects
plane2.transform.localScale = new Vector3(.1f, -1f, .1f);
plane2.transform.localPosition = new Vector3(0, 0, 5);
StringAssert.Contains(jsonExpected, capturesJson);
StringAssert.Contains(TestHelper.NormalizeJson(jsonExpected, true), TestHelper.NormalizeJson(capturesJson, true));
}
[UnityTest]

6
com.unity.perception/Tests/Runtime/GroundTruthTests/TestHelper.cs


using System;
using System.Text.RegularExpressions;
using UnityEngine;
using UnityEngine.Perception.GroundTruth;

}
#endif
public static string NormalizeJson(string json)
public static string NormalizeJson(string json, bool normalizeFormatting = false)
if (normalizeFormatting)
json = Regex.Replace(json, "^\\s*", "", RegexOptions.Multiline);
return json.Replace("\r\n", "\n");
}
}
正在加载...
取消
保存