Steve Borkman
3 年前
当前提交
e2998b0b
共有 28 个文件被更改,包括 1433 次插入 和 143 次删除
-
11TestProjects/PerceptionURP/Assets/ExampleScripts/CustomAnnotationAndMetricReporter.cs
-
146com.unity.perception/Runtime/GroundTruth/DatasetCapture.cs
-
7com.unity.perception/Runtime/GroundTruth/Ego.cs
-
3com.unity.perception/Runtime/GroundTruth/Labelers/CameraLabeler.cs
-
9com.unity.perception/Runtime/GroundTruth/PerceptionCamera.cs
-
4com.unity.perception/Runtime/GroundTruth/PerceptionUpdater.cs
-
48com.unity.perception/Runtime/GroundTruth/SimulationState.cs
-
15com.unity.perception/Runtime/GroundTruth/SimulationState_Json.cs
-
332com.unity.perception/Runtime/GroundTruth/SoloDesign/Frame.cs
-
10com.unity.perception/Runtime/GroundTruth/SoloDesign/SoloConsumer.cs
-
18com.unity.perception/Runtime/Randomization/Scenarios/PerceptionScenario.cs
-
4com.unity.perception/Tests/Editor/DatasetCaptureEditorTests.cs
-
5com.unity.perception/Tests/Editor/PerceptionCameraEditorTests.cs
-
5com.unity.perception/Tests/Performance/PerformanceTester.cs
-
49com.unity.perception/Tests/Runtime/GroundTruthTests/DatasetCaptureSensorSchedulingTests.cs
-
34com.unity.perception/Tests/Runtime/GroundTruthTests/DatasetCaptureTests.cs
-
3com.unity.perception/Tests/Runtime/GroundTruthTests/GroundTruthTestBase.cs
-
7com.unity.perception/Tests/Runtime/GroundTruthTests/PerceptionCameraIntegrationTests.cs
-
6com.unity.perception/Tests/Runtime/Randomization/ScenarioTests/ScenarioTests.cs
-
2com.unity.perception/Tests/Runtime/Randomization/ScenarioTests/TestFixedLengthScenario.cs
-
25com.unity.perception/Runtime/GroundTruth/SoloDesign/IMessageBuilder.cs
-
11com.unity.perception/Runtime/GroundTruth/SoloDesign/IMessageBuilder.cs.meta
-
405com.unity.perception/Runtime/GroundTruth/SoloDesign/OldPerceptionConsumer.cs
-
11com.unity.perception/Runtime/GroundTruth/SoloDesign/OldPerceptionConsumer.cs.meta
-
178com.unity.perception/Runtime/GroundTruth/SoloDesign/OldPerceptionJsonFactory.cs
-
11com.unity.perception/Runtime/GroundTruth/SoloDesign/OldPerceptionJsonFactory.cs.meta
-
206com.unity.perception/Runtime/GroundTruth/SoloDesign/SoloMessageBuilder.cs
-
11com.unity.perception/Runtime/GroundTruth/SoloDesign/SoloMessageBuilder.cs.meta
|
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
|
|||
namespace UnityEngine.Perception.GroundTruth.Exporters.Solo |
|||
{ |
|||
public interface IMessageBuilder |
|||
{ |
|||
void AddInt(string label, int value); |
|||
void AddIntVector(string label, int[] values); |
|||
|
|||
void AddFloat(string label, float value); |
|||
void AddFloatVector(string label, float[] value); |
|||
|
|||
void AddString(string label, string value); |
|||
void AddStringVector(string label, object[] values); |
|||
|
|||
void AddBoolean(string label, bool value); |
|||
void AddBooleanVector(string label, bool[] values); |
|||
|
|||
void AddPngImage(string label, byte[] value); |
|||
|
|||
IMessageBuilder AddNestedMessage(string label); |
|||
IMessageBuilder AddNestedMessageToVector(string arrayLabel); |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 9b7babd7be7b7934db08409d6f7a9524 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Diagnostics.CodeAnalysis; |
|||
using System.Globalization; |
|||
using System.IO; |
|||
using System.Text; |
|||
using Newtonsoft.Json; |
|||
using Newtonsoft.Json.Linq; |
|||
using Newtonsoft.Json.Serialization; |
|||
using UnityEngine; |
|||
using UnityEngine.Perception.GroundTruth.SoloDesign; |
|||
using Formatting = Newtonsoft.Json.Formatting; |
|||
|
|||
namespace GroundTruth.SoloDesign |
|||
{ |
|||
public class PerceptionResolver : DefaultContractResolver |
|||
{ |
|||
protected override JsonObjectContract CreateObjectContract(Type objectType) |
|||
{ |
|||
var contract = base.CreateObjectContract(objectType); |
|||
if (objectType == typeof(Vector3) || |
|||
objectType == typeof(Vector2) || |
|||
objectType == typeof(Color32)) |
|||
{ |
|||
contract.Converter = PerceptionConverter.Instance; |
|||
} |
|||
|
|||
return contract; |
|||
} |
|||
} |
|||
|
|||
public class PerceptionConverter : JsonConverter |
|||
{ |
|||
public static PerceptionConverter Instance = new PerceptionConverter(); |
|||
|
|||
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) |
|||
{ |
|||
switch (value) |
|||
{ |
|||
case Vector3 v3: |
|||
{ |
|||
writer.WriteStartArray(); |
|||
writer.WriteValue(v3.x); |
|||
writer.WriteValue(v3.y); |
|||
writer.WriteValue(v3.z); |
|||
writer.WriteEndArray(); |
|||
break; |
|||
} |
|||
case Vector2 v2: |
|||
{ |
|||
writer.WriteStartArray(); |
|||
writer.WriteValue(v2.x); |
|||
writer.WriteValue(v2.y); |
|||
writer.WriteEndArray(); |
|||
break; |
|||
} |
|||
case Color32 rgba: |
|||
{ |
|||
writer.WriteStartObject(); |
|||
writer.WritePropertyName("r"); |
|||
writer.WriteValue(rgba.r); |
|||
writer.WritePropertyName("g"); |
|||
writer.WriteValue(rgba.g); |
|||
writer.WritePropertyName("b"); |
|||
writer.WriteValue(rgba.b); |
|||
writer.WritePropertyName("a"); |
|||
writer.WriteValue(rgba.a); |
|||
writer.WriteEndObject(); |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
|
|||
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) |
|||
{ |
|||
return null; |
|||
} |
|||
|
|||
public override bool CanConvert(Type objectType) |
|||
{ |
|||
if (objectType == typeof(Vector3)) return true; |
|||
if (objectType == typeof(Vector2)) return true; |
|||
return objectType == typeof(Color32); |
|||
} |
|||
} |
|||
|
|||
public class OldPerceptionConsumer : PerceptionConsumer |
|||
{ |
|||
static readonly string version = "0.1.1"; |
|||
|
|||
public string baseDirectory = "D:/PerceptionOutput/KickinItOldSchool"; |
|||
public int capturesPerFile = 20; |
|||
|
|||
internal JsonSerializer Serializer { get; }= new JsonSerializer { ContractResolver = new PerceptionResolver()}; |
|||
|
|||
//JsonSerializer m_JsonSerializer = new JsonSerializer();
|
|||
string m_CurrentPath; |
|||
string m_DatasetPath; |
|||
string m_RgbPath; |
|||
string m_LogsPath; |
|||
|
|||
[Serializable] |
|||
struct SensorInfo |
|||
{ |
|||
public Guid id; |
|||
public string modality; |
|||
public string description; |
|||
} |
|||
|
|||
Dictionary<string, SensorInfo> m_SensorMap = new Dictionary<string, SensorInfo>(); |
|||
Dictionary<string, (Guid, AnnotationDefinition)> m_RegisteredAnnotations = new Dictionary<string, (Guid, AnnotationDefinition)>(); |
|||
|
|||
Dictionary<int, Guid> m_SequenceToGuidMap = new Dictionary<int, Guid>(); |
|||
List<PerceptionCapture> m_CurrentCaptures = new List<PerceptionCapture>(); |
|||
|
|||
internal string VerifyDirectoryWithGuidExists(string directoryPrefix, bool appendGuid = true) |
|||
{ |
|||
var dirs = Directory.GetDirectories(m_CurrentPath); |
|||
var found = string.Empty; |
|||
|
|||
foreach (var dir in dirs) |
|||
{ |
|||
var dirName = new DirectoryInfo(dir).Name; |
|||
if (dirName.StartsWith(directoryPrefix)) |
|||
{ |
|||
found = dir; |
|||
break; |
|||
} |
|||
} |
|||
|
|||
if (found == string.Empty) |
|||
{ |
|||
var dirName = appendGuid ? $"{directoryPrefix}{Guid.NewGuid().ToString()}" : directoryPrefix; |
|||
found = Path.Combine(m_CurrentPath, dirName); |
|||
Directory.CreateDirectory(found); |
|||
} |
|||
|
|||
return found; |
|||
} |
|||
|
|||
public override void OnAnnotationRegistered(AnnotationDefinition annotationDefinition) |
|||
{ |
|||
if (m_RegisteredAnnotations.ContainsKey(annotationDefinition.id)) |
|||
{ |
|||
Debug.LogError("Tried to register an annotation twice"); |
|||
return; |
|||
} |
|||
|
|||
m_RegisteredAnnotations[annotationDefinition.id] = (Guid.NewGuid(), annotationDefinition); |
|||
} |
|||
|
|||
public override void OnSensorRegistered(SensorDefinition sensor) |
|||
{ |
|||
if (m_SensorMap.ContainsKey(sensor.id)) |
|||
{ |
|||
Debug.LogError("Tried to register a sensor twice"); |
|||
return; |
|||
} |
|||
|
|||
m_SensorMap[sensor.id] = new SensorInfo |
|||
{ |
|||
id = Guid.NewGuid(), |
|||
modality = sensor.modality, |
|||
description = sensor.definition |
|||
}; |
|||
} |
|||
|
|||
public override void OnSimulationStarted(SimulationMetadata metadata) |
|||
{ |
|||
// Create a directory guid...
|
|||
var path = Guid.NewGuid().ToString(); |
|||
|
|||
m_CurrentPath = Path.Combine(baseDirectory, path); |
|||
Directory.CreateDirectory(m_CurrentPath); |
|||
|
|||
m_DatasetPath = VerifyDirectoryWithGuidExists("Dataset"); |
|||
m_RgbPath = VerifyDirectoryWithGuidExists("RGB"); |
|||
m_LogsPath = VerifyDirectoryWithGuidExists("Logs", false); |
|||
} |
|||
|
|||
public override void OnFrameGenerated(Frame frame) |
|||
{ |
|||
if (!m_SequenceToGuidMap.TryGetValue(frame.sequence, out var seqId)) |
|||
{ |
|||
seqId = Guid.NewGuid(); |
|||
m_SequenceToGuidMap[frame.sequence] = seqId; |
|||
} |
|||
|
|||
// Only support one image file right now
|
|||
var path = ""; |
|||
|
|||
RgbSensor rgbSensor = null; |
|||
if (frame.sensors.Count == 1) |
|||
{ |
|||
var sensor = frame.sensors[0]; |
|||
if (sensor is RgbSensor rgb) |
|||
{ |
|||
rgbSensor = rgb; |
|||
path = WriteOutImageFile(frame.frame, rgb); |
|||
} |
|||
} |
|||
|
|||
var annotations = new JArray(); |
|||
foreach (var annotation in frame.annotations) |
|||
{ |
|||
var labelerId = Guid.NewGuid(); // TODO - we need to get this figured out
|
|||
|
|||
if (!m_RegisteredAnnotations.TryGetValue(annotation.Id, out var def)) |
|||
{ |
|||
def.Item1 = Guid.Empty; |
|||
} |
|||
|
|||
var defId = def.Item1; |
|||
var json = OldPerceptionJsonFactory.Convert(this, frame, labelerId, defId, annotation); |
|||
if (json != null) annotations.Add(json); |
|||
} |
|||
|
|||
var capture = new PerceptionCapture |
|||
{ |
|||
id = Guid.NewGuid(), |
|||
filename = path, |
|||
format = "PNG", |
|||
sequence_id = seqId, |
|||
step = frame.step, |
|||
timestamp = frame.timestamp, |
|||
sensor = PerceptionRgbSensor.Convert(this, rgbSensor, path), |
|||
annotations = annotations |
|||
}; |
|||
|
|||
m_CurrentCaptures.Add(capture); |
|||
|
|||
if (m_CurrentCaptures.Count >= capturesPerFile) |
|||
{ |
|||
var toRemove = m_CurrentCaptures; |
|||
m_CurrentCaptures = new List<PerceptionCapture>(); |
|||
// Write out a capture file
|
|||
WriteCaptureFile(m_CurrentCaptureIndex++, toRemove); |
|||
toRemove.Clear(); |
|||
} |
|||
} |
|||
|
|||
public override void OnSimulationCompleted(CompletionMetadata metadata) |
|||
{ |
|||
WriteSensorsFile(); |
|||
WriteEgosFile(); |
|||
WriteAnnotationsDefinitionsFile(); |
|||
WriteMetricsDefinitionsFile(); |
|||
} |
|||
|
|||
int m_CurrentCaptureIndex = 1; |
|||
|
|||
string WriteOutImageFile(int frame, RgbSensor rgb) |
|||
{ |
|||
var path = Path.Combine(m_RgbPath, $"{rgb.sensorType}_{frame}.png"); |
|||
var file = File.Create(path, 4096); |
|||
file.Write(rgb.buffer, 0, rgb.buffer.Length); |
|||
file.Close(); |
|||
return path; |
|||
} |
|||
|
|||
void WriteJTokenToFile(string filePath, PerceptionJson json) |
|||
{ |
|||
WriteJTokenToFile(filePath, JToken.FromObject(json, Serializer)); |
|||
} |
|||
|
|||
static void WriteJTokenToFile(string filePath, JToken json) |
|||
{ |
|||
var stringWriter = new StringWriter(new StringBuilder(256), CultureInfo.InvariantCulture); |
|||
using (var jsonTextWriter = new JsonTextWriter(stringWriter)) |
|||
{ |
|||
jsonTextWriter.Formatting = Formatting.Indented; |
|||
json.WriteTo(jsonTextWriter); |
|||
} |
|||
|
|||
var contents = stringWriter.ToString(); |
|||
|
|||
File.WriteAllText(filePath, contents); |
|||
} |
|||
|
|||
void WriteAnnotationsDefinitionsFile() |
|||
{ |
|||
var defs = new JArray(); |
|||
|
|||
foreach (var (id, def) in m_RegisteredAnnotations.Values) |
|||
{ |
|||
defs.Add(OldPerceptionJsonFactory.Convert(this, id, def)); |
|||
} |
|||
|
|||
var top = new JObject |
|||
{ |
|||
["version"] = version, |
|||
["annotation_definitions"] = defs |
|||
}; |
|||
var path = Path.Combine(m_DatasetPath, "annotation_definitions.json"); |
|||
WriteJTokenToFile(path, top); |
|||
} |
|||
|
|||
void WriteMetricsDefinitionsFile() |
|||
{ |
|||
var top = new JObject |
|||
{ |
|||
["version"] = version, |
|||
["metric_definitions"] = new JArray() |
|||
}; |
|||
var path = Path.Combine(m_DatasetPath, "metric_definitions.json"); |
|||
WriteJTokenToFile(path, top); |
|||
} |
|||
|
|||
void WriteEgosFile() |
|||
{ |
|||
var top = new JObject |
|||
{ |
|||
["version"] = version, |
|||
["egos"] = new JArray() |
|||
}; |
|||
var path = Path.Combine(m_DatasetPath, "egos.json"); |
|||
WriteJTokenToFile(path, top); |
|||
} |
|||
|
|||
void WriteSensorsFile() |
|||
{ |
|||
var sub = new JArray(); |
|||
foreach (var sensor in m_SensorMap) |
|||
{ |
|||
sub.Add(JToken.FromObject(sensor.Value, Serializer)); |
|||
} |
|||
var top = new JObject |
|||
{ |
|||
["version"] = version, |
|||
["sensors"] = sub |
|||
}; |
|||
var path = Path.Combine(m_DatasetPath, "sensors.json"); |
|||
WriteJTokenToFile(path, top); |
|||
} |
|||
|
|||
void WriteCaptureFile(int index, IEnumerable<PerceptionCapture> captures) |
|||
{ |
|||
var top = new PerceptionJson |
|||
{ |
|||
version = version, |
|||
captures = captures |
|||
}; |
|||
|
|||
var path = Path.Combine(m_DatasetPath, $"captures_{index}.json"); |
|||
WriteJTokenToFile(path, top); |
|||
} |
|||
|
|||
public Guid GetIdForSensor(Sensor inSensor) |
|||
{ |
|||
if (!m_SensorMap.TryGetValue(inSensor.Id, out var info)) |
|||
{ |
|||
Debug.LogError("Sensor Id was not available, it should have already been registered"); |
|||
return Guid.Empty; |
|||
} |
|||
|
|||
return info.id; |
|||
} |
|||
|
|||
[Serializable] |
|||
struct PerceptionJson |
|||
{ |
|||
public string version; |
|||
public IEnumerable<PerceptionCapture> captures; |
|||
} |
|||
|
|||
[SuppressMessage("ReSharper", "InconsistentNaming")] |
|||
[Serializable] |
|||
struct PerceptionCapture |
|||
{ |
|||
public Guid id; |
|||
public Guid sequence_id; |
|||
public int step; |
|||
public float timestamp; |
|||
public string filename; |
|||
public string format; |
|||
public PerceptionRgbSensor sensor; |
|||
public JArray annotations; |
|||
} |
|||
|
|||
[SuppressMessage("ReSharper", "InconsistentNaming")] |
|||
[Serializable] |
|||
struct PerceptionRgbSensor |
|||
{ |
|||
public Guid sensor_id; |
|||
public string modality; |
|||
public Vector3 translation; |
|||
public Vector3 rotation; |
|||
public Vector3 velocity; |
|||
public Vector3 acceleration; |
|||
|
|||
public static PerceptionRgbSensor Convert(OldPerceptionConsumer consumer, RgbSensor inRgb, string path) |
|||
{ |
|||
return new PerceptionRgbSensor |
|||
{ |
|||
sensor_id = consumer.GetIdForSensor(inRgb), |
|||
modality = inRgb.sensorType, |
|||
translation = inRgb.position, |
|||
rotation = inRgb.rotation, |
|||
velocity = inRgb.velocity, |
|||
acceleration = inRgb.acceleration |
|||
}; |
|||
} |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 263154e84a4500e4494724de402f1162 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Diagnostics.CodeAnalysis; |
|||
using System.IO; |
|||
using System.Linq; |
|||
using Newtonsoft.Json.Linq; |
|||
using UnityEngine; |
|||
using UnityEngine.Perception.GroundTruth.SoloDesign; |
|||
|
|||
namespace GroundTruth.SoloDesign |
|||
{ |
|||
public static class OldPerceptionJsonFactory |
|||
{ |
|||
public static JToken Convert(OldPerceptionConsumer consumer, Guid id, AnnotationDefinition def) |
|||
{ |
|||
switch (def) |
|||
{ |
|||
case BoundingBoxAnnotationDefinition b: |
|||
return JToken.FromObject(PerceptionBoundingBoxAnnotationDefinition.Convert(id, b)); |
|||
} |
|||
|
|||
return null; |
|||
} |
|||
|
|||
public static JToken Convert(OldPerceptionConsumer consumer, Frame frame, Guid labelerId, Guid defId, Annotation annotation) |
|||
{ |
|||
switch (annotation) |
|||
{ |
|||
case InstanceSegmentation i: |
|||
{ |
|||
return JToken.FromObject(PerceptionInstanceSegmentationValue.Convert(consumer, frame.frame, i), consumer.Serializer); |
|||
} |
|||
case BoundingBoxAnnotation b: |
|||
{ |
|||
return JToken.FromObject(PerceptionBoundingBoxAnnotationValue.Convert(consumer, labelerId, defId, b), consumer.Serializer); |
|||
} |
|||
} |
|||
|
|||
return null; |
|||
} |
|||
} |
|||
|
|||
[SuppressMessage("ReSharper", "InconsistentNaming")] |
|||
[Serializable] |
|||
struct PerceptionInstanceSegmentationValue |
|||
{ |
|||
[Serializable] |
|||
internal struct Entry |
|||
{ |
|||
public int instance_id; |
|||
public Color32 color; |
|||
|
|||
internal static Entry Convert(InstanceSegmentation.Entry entry) |
|||
{ |
|||
return new Entry |
|||
{ |
|||
instance_id = entry.instanceId, |
|||
color = entry.rgba |
|||
}; |
|||
} |
|||
} |
|||
|
|||
public Guid id; |
|||
public Guid annotation_definition; |
|||
public string filename; |
|||
public List<Entry> values; |
|||
|
|||
static string CreateFile(OldPerceptionConsumer consumer, int frame, InstanceSegmentation annotation) |
|||
{ |
|||
var path = consumer.VerifyDirectoryWithGuidExists("InstanceSegmentation"); |
|||
path = Path.Combine(path, $"Instance_{frame}.png"); |
|||
var file = File.Create(path, 4096); |
|||
file.Write(annotation.buffer, 0, annotation.buffer.Length); |
|||
file.Close(); |
|||
return path; |
|||
} |
|||
|
|||
public static PerceptionInstanceSegmentationValue Convert(OldPerceptionConsumer consumer, int frame, InstanceSegmentation annotation) |
|||
{ |
|||
return new PerceptionInstanceSegmentationValue |
|||
{ |
|||
id = Guid.NewGuid(), |
|||
annotation_definition = Guid.NewGuid(), |
|||
filename = CreateFile(consumer, frame, annotation), |
|||
values = annotation.instances.Select(Entry.Convert).ToList() |
|||
}; |
|||
} |
|||
} |
|||
|
|||
[Serializable] |
|||
struct LabelDefinitionEntry |
|||
{ |
|||
public int label_id; |
|||
public string label_name; |
|||
} |
|||
|
|||
[Serializable] |
|||
struct PerceptionBoundingBoxAnnotationDefinition |
|||
{ |
|||
public Guid id; |
|||
public string name; |
|||
public string description; |
|||
public string format; |
|||
public LabelDefinitionEntry[] spec; |
|||
|
|||
public static PerceptionBoundingBoxAnnotationDefinition Convert(Guid inId, BoundingBoxAnnotationDefinition box) |
|||
{ |
|||
var specs = new LabelDefinitionEntry[box.spec.Count()]; |
|||
var i = 0; |
|||
|
|||
foreach (var e in box.spec) |
|||
{ |
|||
specs[i++] = new LabelDefinitionEntry |
|||
{ |
|||
label_id = e.labelId, |
|||
label_name = e.labelName |
|||
}; |
|||
|
|||
} |
|||
|
|||
return new PerceptionBoundingBoxAnnotationDefinition |
|||
{ |
|||
id = inId, |
|||
name = box.id, |
|||
description = box.description, |
|||
format = "json", |
|||
spec = specs |
|||
}; |
|||
} |
|||
} |
|||
|
|||
[SuppressMessage("ReSharper", "InconsistentNaming")] |
|||
[Serializable] |
|||
struct PerceptionBoundingBoxAnnotationValue |
|||
{ |
|||
[Serializable] |
|||
internal struct Entry |
|||
{ |
|||
public int label_id; |
|||
public int frame; |
|||
public string label_name; |
|||
public uint instance_id; |
|||
public float x; |
|||
public float y; |
|||
public float width; |
|||
public float height; |
|||
|
|||
internal static Entry Convert(BoundingBoxAnnotation.Entry entry) |
|||
{ |
|||
return new Entry |
|||
{ |
|||
label_id = entry.labelId, // TODO
|
|||
frame = -1, // TODO
|
|||
label_name = entry.labelName, |
|||
instance_id = (uint)entry.instanceId, |
|||
x = entry.origin.x, |
|||
y = entry.origin.y, |
|||
width = entry.dimension.x, |
|||
height = entry.dimension.y |
|||
}; |
|||
} |
|||
} |
|||
|
|||
public Guid id; |
|||
public Guid annotation_definition; |
|||
public List<Entry> values; |
|||
|
|||
public static PerceptionBoundingBoxAnnotationValue Convert(OldPerceptionConsumer consumer, Guid labelerId, Guid defId, BoundingBoxAnnotation annotation) |
|||
{ |
|||
return new PerceptionBoundingBoxAnnotationValue |
|||
{ |
|||
id = labelerId, |
|||
annotation_definition = defId, |
|||
values = annotation.boxes.Select(Entry.Convert).ToList() |
|||
}; |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 41c6d077f1a3a704e91176dc0b675ac7 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
using System.Collections.Generic; |
|||
using System.Globalization; |
|||
using System.IO; |
|||
using System.Linq; |
|||
using System.Text; |
|||
using Newtonsoft.Json; |
|||
using Newtonsoft.Json.Linq; |
|||
using UnityEngine; |
|||
using UnityEngine.Perception.GroundTruth.Exporters.Solo; |
|||
using UnityEngine.Perception.GroundTruth.SoloDesign; |
|||
|
|||
namespace GroundTruth.SoloDesign |
|||
{ |
|||
public class SoloMessageBuilder : PerceptionConsumer |
|||
{ |
|||
public string _baseDirectory = "D:/PerceptionOutput/SoloMessageBuilder"; |
|||
public string soloDatasetName = "solo_mb"; |
|||
static string currentDirectory = ""; |
|||
|
|||
SimulationMetadata m_CurrentMetadata; |
|||
|
|||
public override void OnSimulationStarted(SimulationMetadata metadata) |
|||
{ |
|||
Debug.Log("SC - On Simulation Started"); |
|||
m_CurrentMetadata = metadata; |
|||
|
|||
if (!Directory.Exists((_baseDirectory))) |
|||
Directory.CreateDirectory(_baseDirectory); |
|||
|
|||
var i = 0; |
|||
while (true) |
|||
{ |
|||
var n = $"{soloDatasetName}_{i++}"; |
|||
n = Path.Combine(_baseDirectory, n); |
|||
if (!Directory.Exists(n)) |
|||
{ |
|||
Directory.CreateDirectory(n); |
|||
currentDirectory = n; |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
|
|||
static string GetSequenceDirectoryPath(Frame frame) |
|||
{ |
|||
var path = $"sequence.{frame.sequence}"; |
|||
|
|||
// verify that a directory already exists for a sequence,
|
|||
// if not, create it.
|
|||
path = Path.Combine(currentDirectory, path); |
|||
|
|||
if (!Directory.Exists(path)) |
|||
{ |
|||
Directory.CreateDirectory(path); |
|||
} |
|||
|
|||
return path; |
|||
} |
|||
|
|||
JToken m_FrameToken = null; |
|||
Stack<JToken> m_Tokens = new Stack<JToken>(); |
|||
|
|||
public override void OnFrameGenerated(Frame frame) |
|||
{ |
|||
if (m_FrameToken == null) |
|||
{ |
|||
m_FrameToken = new JObject(); |
|||
m_Tokens.Push(m_FrameToken); |
|||
} |
|||
else |
|||
{ |
|||
// do something here to write out previous frame
|
|||
} |
|||
|
|||
var msg = new FrameMessageBuilder(); |
|||
FrameMessageBuilder.currentFrame = frame; |
|||
|
|||
frame.ToMessage(msg); |
|||
|
|||
// write out current
|
|||
var path = GetSequenceDirectoryPath(frame); |
|||
path = Path.Combine(path, $"step{frame.step}.frame_data.json"); |
|||
WriteJTokenToFile(path, msg.ToJson()); |
|||
} |
|||
|
|||
static void WriteJTokenToFile(string filePath, JToken jToken) |
|||
{ |
|||
var stringWriter = new StringWriter(new StringBuilder(256), CultureInfo.InvariantCulture); |
|||
using (var jsonTextWriter = new JsonTextWriter(stringWriter)) |
|||
{ |
|||
jsonTextWriter.Formatting = Formatting.Indented; |
|||
jToken.WriteTo(jsonTextWriter); |
|||
} |
|||
|
|||
var contents = stringWriter.ToString(); |
|||
|
|||
File.WriteAllText(filePath, contents); |
|||
} |
|||
|
|||
public override void OnSimulationCompleted(CompletionMetadata metadata) |
|||
{ |
|||
Debug.Log("SC - On Simulation Completed"); |
|||
} |
|||
|
|||
class FrameMessageBuilder : IMessageBuilder |
|||
{ |
|||
JToken m_Current = new JObject(); |
|||
Dictionary<string, FrameMessageBuilder> m_NestedValue = new Dictionary<string, FrameMessageBuilder>(); |
|||
Dictionary<string, List<FrameMessageBuilder>> m_NestedArrays = new Dictionary<string, List<FrameMessageBuilder>>(); |
|||
public static Frame currentFrame = null; |
|||
|
|||
public JToken ToJson() |
|||
{ |
|||
foreach (var n in m_NestedValue) |
|||
{ |
|||
m_Current[n.Key] = n.Value.ToJson(); |
|||
} |
|||
|
|||
foreach (var n in m_NestedArrays) |
|||
{ |
|||
var jArray = new JArray(); |
|||
foreach (var o in n.Value) |
|||
{ |
|||
jArray.Add(o.ToJson()); |
|||
} |
|||
|
|||
m_Current[n.Key] = jArray; |
|||
} |
|||
return m_Current; |
|||
} |
|||
|
|||
public void AddInt(string label, int value) |
|||
{ |
|||
m_Current[label] = value; |
|||
} |
|||
|
|||
public void AddIntVector(string label, int[] values) |
|||
{ |
|||
m_Current[label] = new JArray(values); |
|||
} |
|||
|
|||
public void AddFloat(string label, float value) |
|||
{ |
|||
m_Current[label] = value; |
|||
} |
|||
|
|||
public void AddFloatVector(string label, float[] values) |
|||
{ |
|||
m_Current[label] = new JArray(values); |
|||
} |
|||
|
|||
public void AddString(string label, string value) |
|||
{ |
|||
m_Current[label] = value; |
|||
} |
|||
|
|||
public void AddStringVector(string label, object[] values) |
|||
{ |
|||
m_Current[label] = new JArray(values); |
|||
} |
|||
|
|||
public void AddBoolean(string label, bool value) |
|||
{ |
|||
m_Current[label] = value; |
|||
} |
|||
|
|||
public void AddBooleanVector(string label, bool[] values) |
|||
{ |
|||
m_Current[label] = new JArray(values); |
|||
} |
|||
|
|||
// Right now, just for png images
|
|||
public void AddPngImage(string label, byte[] value) |
|||
{ |
|||
// write out the file
|
|||
var path = GetSequenceDirectoryPath(currentFrame); |
|||
path = Path.Combine(path, $"step{currentFrame.step}.{label}.png"); |
|||
var file = File.Create(path, 4096); |
|||
file.Write(value, 0, value.Length); |
|||
file.Close(); |
|||
|
|||
// Add the filename to the json
|
|||
m_Current["filename"] = path; |
|||
} |
|||
|
|||
public IMessageBuilder AddNestedMessage(string label) |
|||
{ |
|||
var nested = new FrameMessageBuilder(); |
|||
m_NestedValue[label] = nested; |
|||
return nested; |
|||
} |
|||
|
|||
public IMessageBuilder AddNestedMessageToVector(string arrayLabel) |
|||
{ |
|||
if (!m_NestedArrays.TryGetValue(arrayLabel, out var nestedList)) |
|||
{ |
|||
nestedList = new List<FrameMessageBuilder>(); |
|||
m_NestedArrays[arrayLabel] = nestedList; |
|||
} |
|||
var nested = new FrameMessageBuilder(); |
|||
nestedList.Add(nested); |
|||
return nested; |
|||
} |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 8de61169fea9df74b99d779c0d38b8a5 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
撰写
预览
正在加载...
取消
保存
Reference in new issue