您最多选择25个主题 主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

411 行
13 KiB

using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;
using UnityEngine;
using UnityEngine.Perception.GroundTruth.DataModel;
using Formatting = Newtonsoft.Json.Formatting;
namespace UnityEngine.Perception.GroundTruth.Consumers
{
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 : ConsumerEndpoint
{
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>();
protected override bool IsComplete()
{
return true;
}
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.First();
if (sensor is RgbSensor rgb)
{
rgbSensor = rgb;
path = WriteOutImageFile(frame.frame, rgb);
}
}
#if false // TODO bring back annotations....
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);
}
#endif
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
};
}
}
}
}