浏览代码

Updates to support producing multi-document solo format

/solo_support
Steve Borkman 3 年前
当前提交
a13bf19d
共有 15 个文件被更改,包括 989 次插入26 次删除
  1. 13
      com.unity.perception/Runtime/GroundTruth/Exporters/Coco/CocoExporter.cs
  2. 6
      com.unity.perception/Runtime/GroundTruth/Exporters/IDatasetExporter.cs
  3. 14
      com.unity.perception/Runtime/GroundTruth/Exporters/PerceptionFormat/PerceptionExporter.cs
  4. 285
      com.unity.perception/Runtime/GroundTruth/Exporters/PerceptionNew/PerceptionNewExporter.cs
  5. 2
      com.unity.perception/Runtime/GroundTruth/Labelers/InstanceSegmentationLabeler.cs
  6. 15
      com.unity.perception/Runtime/GroundTruth/Labelers/SemanticSegmentationLabeler.cs
  7. 17
      com.unity.perception/Runtime/GroundTruth/SimulationState.cs
  8. 9
      com.unity.perception/Runtime/GroundTruth/SimulationState_Json.cs
  9. 8
      com.unity.perception/Runtime/GroundTruth/Exporters/SOLO.meta
  10. 103
      com.unity.perception/Runtime/GroundTruth/Exporters/SOLO/AnnotationHandler.cs
  11. 11
      com.unity.perception/Runtime/GroundTruth/Exporters/SOLO/AnnotationHandler.cs.meta
  12. 521
      com.unity.perception/Runtime/GroundTruth/Exporters/SOLO/SoloExporter.cs
  13. 11
      com.unity.perception/Runtime/GroundTruth/Exporters/SOLO/SoloExporter.cs.meta

13
com.unity.perception/Runtime/GroundTruth/Exporters/Coco/CocoExporter.cs


Guid m_SessionGuid;
public void OnMetricRegistered(Guid metricId, string name, string description)
{
Debug.Log("On MetricRegistered");
}
public string GetRgbCaptureFilename(params(string, object)[] additionalSensorValues)
{
return string.Empty;

}
}
public Task ProcessPendingMetrics(List<SimulationState.PendingMetric> pendingMetrics, SimulationState simState)
{
return null;
}
static Dictionary<int, CocoTypes.ObjectDetectionAnnotation> ProcessBoundingBoxAnnotations(IEnumerable<object> annotations)
{
var map = new Dictionary<int, CocoTypes.ObjectDetectionAnnotation>();

return map;
}
public async Task OnCaptureReported(int frame, int width, int height, string filename)
public async Task OnCaptureReported(Guid sequence, int step, int width, int height, string filename, Vector3 position, Quaternion rotation, Vector3 velocity, Vector3 acceleration)
var frame = 0;
var converted = AnnotationHandler.HandleCameraCapture(frame, width, height, filename);
if (m_FirstCapture)
{

6
com.unity.perception/Runtime/GroundTruth/Exporters/IDatasetExporter.cs


void OnAnnotationRegistered<TSpec>(Guid annotationId, TSpec[] values);
void OnMetricRegistered(Guid metricId, string name, string description);
Task OnCaptureReported(int frame, int width, int height, string filename);
Task ProcessPendingMetrics(List<SimulationState.PendingMetric> pendingMetrics, SimulationState simState);
Task OnCaptureReported(Guid sequence, int step, int width, int height, string filename, Vector3 position, Quaternion rotation, Vector3 velocity, Vector3 acceleration);
}
}

14
com.unity.perception/Runtime/GroundTruth/Exporters/PerceptionFormat/PerceptionExporter.cs


string outputDirectory = string.Empty;
int captureFileIndex = 0;
public void OnMetricRegistered(Guid metricId, string name, string description)
{
Debug.Log("On MetricRegistered");
}
public string GetRgbCaptureFilename(params(string, object)[] additionalSensorValues)
{
return string.Empty;

return null;
}
public Task OnCaptureReported(int frame, int width, int height, string filename)
public Task OnCaptureReported(Guid sequence, int step, int width, int height, string filename, Vector3 position, Quaternion rotation, Vector3 velocity, Vector3 acceleration)
{
// do nothing :-)
return null;

return ext.ToUpperInvariant();
}
public Task ProcessPendingMetrics(List<SimulationState.PendingMetric> pendingMetrics, SimulationState simState)
{
return null;
}
}
}

285
com.unity.perception/Runtime/GroundTruth/Exporters/PerceptionNew/PerceptionNewExporter.cs


int m_UnknownFrameCount = 0;
public void OnMetricRegistered(Guid metricId, string name, string description)
{
Debug.Log("On MetricRegistered");
}
public string GetRgbCaptureFilename(params(string, object)[] additionalSensorValues)
{
var frameArray = additionalSensorValues.Where(p => p.Item1 == "frame").Select(p => p.Item2);

Debug.Log($"SS - New Perception - OnSimBegin");
m_Metadata = new Metadata
{
version = "0.0.1",
image_width = 0,
image_height = 0,
dataset_size = 0
version = "0.1.1",
unity_version = "2019.4.26f1",
perception_version = "0.8.0-preview.4",
total_frames = 0,
total_sequences = 0,
sequences = null,
sensors = new []
{
new CameraData
{
id = "camera",
modality = "camera",
resolution = new []{0,0}
}
}
};
m_DirectoryName = directoryName + Path.DirectorySeparatorChar + Guid.NewGuid() + Path.DirectorySeparatorChar;

struct Metadata
{
public string version;
public int image_width;
public int image_height;
public int dataset_size;
public string unity_version;
public string perception_version;
public int total_frames;
public int total_sequences;
public SequenceData[] sequences;
public CameraData[] sensors;
}
[Serializable]
struct SequenceData
{
public string sequence_id;
public int steps;
}
[Serializable]
struct CameraData
{
public string id;
public string modality;
public int[] resolution;
void CopyDefFile(string contains, string newName)
{
var d = m_DirectoryName;
var up = Directory.GetParent(m_DirectoryName)?.ToString() ?? string.Empty;
up = Directory.GetParent(up)?.ToString() ?? string.Empty;
var files = Directory.EnumerateFiles(up);
foreach (var file in files)
{
if (Path.GetFileName(file).Contains(contains))
{
File.Copy(file, Path.Combine(m_DirectoryName, newName));
return;
}
}
}
public void OnSimulationEnd()
{
Debug.Log($"SS - New Perception - OnSimEnd");

Debug.Log("SS - New Perception - writing");
var sequences = new Dictionary<int, int>();
foreach (var (seq, step) in m_FrameToSequenceMap.Values)
{
sequences.TryGetValue(seq, out var max);
if (step > max) max = step;
sequences[seq] = max;
}
m_Metadata.total_sequences = sequences.Count;
m_Metadata.sequences = new SequenceData[sequences.Count];
for (var i = 0; i < sequences.Count; i++)
{
m_Metadata.sequences[i] = new SequenceData
{
sequence_id = $"sequence_{i}",
steps = sequences[i]
};
}
CopyDefFile("annotation", "annotations.json");
CopyDefFile("metric_def", "metrics.json");
CopyDefFile("sensors", "sensors.json");
// Copy image files to the proper path
var d = m_DirectoryName;
var upOne = Path.Combine(m_DirectoryName, "..");
var upOne2 = Directory.GetParent(m_DirectoryName)?.ToString() ?? string.Empty;
var upTwo = Directory.GetParent(upOne2)?.ToString() ?? string.Empty;
var upThree = Directory.GetParent(upTwo)?.ToString() ?? string.Empty;
var dirs = Directory.EnumerateDirectories(upThree);
foreach (var dir in dirs)
{
if (dir.Contains("RGB"))
{
foreach (var f in Directory.EnumerateFiles(dir))
{
// Get the frame number from the path
var filename = Path.GetFileName(f);
var underscore = filename.IndexOf("_") + 1;
var dot = filename.IndexOf(".");
var frame = filename.Substring(underscore, dot - underscore);
var (seq, step) = m_FrameToSequenceMap[int.Parse(frame)];
var newFilename = $"step.{step}.capture.camera.png";
File.Copy(f, Path.Combine(m_DirectoryName, $"sequence.{seq}", newFilename));
}
}
else if (dir.Contains("Instance"))
{
foreach (var f in Directory.EnumerateFiles(dir))
{
// Get the frame number from the path
var filename = Path.GetFileName(f);
var underscore = filename.IndexOf("_") + 1;
var dot = filename.IndexOf(".");
var frame = filename.Substring(underscore, dot - underscore);
var (seq, step) = m_FrameToSequenceMap[int.Parse(frame)];
var newFilename = $"step.{step}.annotation.semantic_segmentation.camera.png";
File.Copy(f, Path.Combine(m_DirectoryName, $"sequence.{seq}", newFilename));
}
}
else if (dir.Contains("Semantic"))
{
foreach (var f in Directory.EnumerateFiles(dir))
{
// Get the frame number from the path
var filename = Path.GetFileName(f);
var underscore = filename.IndexOf("_") + 1;
var dot = filename.IndexOf(".");
var frame = filename.Substring(underscore, dot - underscore);
var (seq, step) = m_FrameToSequenceMap[int.Parse(frame)];
var newFilename = $"step.{step}.annotation.instance_segmentation.camera.png";
File.Copy(f, Path.Combine(m_DirectoryName, $"sequence.{seq}", newFilename));
}
}
}
// Go into the RGB directory
Manager.Instance.ConsumerFileProduced(writePath);
Task.WhenAll(m_PendingTasks);

// Right now, do nothing :-)
}
static bool GetFilenameForAnnotation(object rawData, out string filename)
bool GetFilenameForAnnotation(int sequence, int step, object rawData, out string filename, out string id, out string def, out bool reportValues)
id = string.Empty;
def = string.Empty;
reportValues = true;
m_FrameToSequenceMap[bbox.frame] = (sequence, step);
filename = $"frame_{frame}_bounding_bocx_2d.json";
id = "bounding_box";
def = $"{id}_definition";
// var fmt = new String('0', 5);
// var format = "{0,20:" + fmt + "}";
// filename = $"step.{frame.ToString(format)}.annotation.bounding_box.camera.json";
filename = $"step.{step}.annotation.{id}.camera.json";
return true;
}
if (rawData is InstanceSegmentationLabeler.InstanceColorValue)
{
id = "instance_segmentation";
def = $"{id}_definition";
// var fmt = new String('0', 5);
// var format = "{0,20:" + fmt + "}";
// filename = $"step.{frame.ToString(format)}.annotation.bounding_box.camera.json";
filename = $"step.{step}.annotation.{id}.camera.json";
return true;
}
if (rawData is SemanticSegmentationLabeler.SegmentationValue)
{
id = "semantic_segmentation";
def = $"{id}_definition";
// var fmt = new String('0', 5);
// var format = "{0,20:" + fmt + "}";
// filename = $"step.{frame.ToString(format)}.annotation.bounding_box.camera.json";
filename = $"step.{step}.annotation.{id}.camera.json";
reportValues = false;
return true;
}

// that reads json records off of a queue and writes them out
List<Task> m_PendingTasks = new List<Task>();
int m_CurrentSequence = 0;
Dictionary<Guid, int> m_SequenceGuidMap = new Dictionary<Guid, int>();
Dictionary<int, (int, int)> m_FrameToSequenceMap = new Dictionary<int, (int, int)>();
if (!m_SequenceGuidMap.TryGetValue(cap.SequenceId, out var seq))
{
seq = m_CurrentSequence++;
m_SequenceGuidMap[cap.SequenceId] = seq;
var seqDir = Path.Combine(m_DirectoryName, $"sequence.{m_SequenceGuidMap[cap.SequenceId]}");
// Create a directory
if (!Directory.Exists(seqDir))
Directory.CreateDirectory(seqDir);
}
var path = Path.Combine(m_DirectoryName, $"sequence.{m_SequenceGuidMap[cap.SequenceId]}");
foreach (var (annotation, annotationData) in cap.Annotations)
{
// Create a file for the annotation

foreach (var rawValue in annotationData.RawValues)
{
if (GetFilenameForAnnotation(rawValue, out var filename))
if (GetFilenameForAnnotation(seq, cap.Step, rawValue, out var filename, out var id, out var def, out var reportValues))
var sensor = "camera";
json.Append(annotationData.ValuesJson);
m_PendingTasks.Add(AnnotationHandler.WriteOutJson(m_DirectoryName, filename, json.ToString()));
json.Append($"{{\"Id\": \"{id}\",");
json.Append($"\"definition\": \"{def}\",");
json.Append($"\"sequence\": {seq},");
json.Append($"\"step\": {cap.Step},");
json.Append($"\"sensor\": \"{sensor}\"");
if (reportValues)
{
json.Append(",\"values\":");
json.Append(annotationData.ValuesJson);
}
json.Append("}");
m_PendingTasks.Add(AnnotationHandler.WriteOutJson(path, filename, json.ToString()));
#else
// Need to revisit this and handle this in a performant way
var jObject = PerceptionExporter.JObjectFromAnnotation((annotation, annotationData));

return Task.CompletedTask;
}
public Task OnCaptureReported(int frame, int width, int height, string filename)
[Serializable]
struct SensorData
{
public string id;
public int sequence;
public int step;
public Vector3 translation;
public Vector3 rotation;
public Vector3 velocity;
public Vector3 acceleration;
}
public Task OnCaptureReported(Guid sequence, int step, int width, int height, string filename, Vector3 position, Quaternion rotation, Vector3 velocity, Vector3 acceleration)
{
var sensor = new SensorData
{
id = "camera",
sequence = 0,
step = 0,
translation = position,
rotation = rotation.eulerAngles,
velocity = velocity,
acceleration = acceleration
};
if (!m_SequenceGuidMap.TryGetValue(sequence, out var seq))
{
seq = m_CurrentSequence++;
m_SequenceGuidMap[sequence] = seq;
}
var path = Path.Combine(m_DirectoryName, $"sequence.{seq}");
if (!Directory.Exists(path))
Directory.CreateDirectory(path);
var f = $"step.{step}.camera.json";
var json = JsonUtility.ToJson(sensor, true);
m_PendingTasks.Add(AnnotationHandler.WriteOutJson(path, f, json));
m_Metadata.total_frames++;
m_Metadata.sensors[0].resolution = new[] { width, height };
return null;
}
public Task ProcessPendingMetrics(List<SimulationState.PendingMetric> pendingMetrics, SimulationState simState)
m_Metadata.dataset_size++;
m_Metadata.image_height = height;
m_Metadata.image_width = width;
return null;
}
}

2
com.unity.perception/Runtime/GroundTruth/Labelers/InstanceSegmentationLabeler.cs


[SuppressMessage("ReSharper", "InconsistentNaming")]
[SuppressMessage("ReSharper", "NotAccessedField.Local")]
struct InstanceColorValue
public struct InstanceColorValue
{
public uint instance_id;
public Color32 color;

15
com.unity.perception/Runtime/GroundTruth/Labelers/SemanticSegmentationLabeler.cs


public RenderTexture sourceTexture;
}
public struct SegmentationValue
{
public int frame;
}
/// <summary>
/// Event which is called each frame a semantic segmentation image is read back from the GPU.
/// </summary>

if (!m_AsyncAnnotations.TryGetValue(frameCount, out var annotation))
return;
var info = new SegmentationValue[]
{
new SegmentationValue
{
frame = frameCount
}
};
annotation.ReportFile(datasetRelativePath);
annotation.ReportFileAndValues(datasetRelativePath, info);
var asyncRequest = Manager.Instance.CreateRequest<AsyncRequest<AsyncSemanticSegmentationWrite>>();

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


using UnityEngine.Perception.GroundTruth.Exporters.Coco;
using UnityEngine.Perception.GroundTruth.Exporters.PerceptionFormat;
using UnityEngine.Perception.GroundTruth.Exporters.PerceptionNew;
using UnityEngine.Perception.GroundTruth.Exporters.Solo;
using UnityEngine.Profiling;
namespace UnityEngine.Perception.GroundTruth

case nameof(PerceptionNewExporter):
_ActiveReporter = new PerceptionNewExporter();
break;
case nameof(SoloExporter):
_ActiveReporter = new SoloExporter();
break;
default:
_ActiveReporter = new PerceptionExporter();
break;

}
}
struct PendingMetric
public struct PendingMetric
{
public PendingMetric(MetricDefinition metricDefinition, int metricId, SensorHandle sensorHandle, Guid captureId, Annotation annotation, Guid sequenceId, int step, JToken values = null)
{

}
}
GetActiveReporter()?.OnCaptureReported(frameCount, width, height, filename);
var trans = pendingCapture.SensorSpatialData.EgoPose.position;
var rot = pendingCapture.SensorSpatialData.EgoPose.rotation;
var velocity = pendingCapture.SensorSpatialData.EgoVelocity ?? Vector3.zero;
var accel = pendingCapture.SensorSpatialData.EgoAcceleration ?? Vector3.zero;
GetActiveReporter()?.OnCaptureReported(m_SequenceId, AcquireStep(), width, height, filename, trans, rot, velocity, accel);
}
static string GetFormatFromFilename(string filename)

id = Guid.NewGuid();
RegisterAdditionalInfoType(name, specValues, description, null, id, AdditionalInfoKind.Metric);
GetActiveReporter()?.OnMetricRegistered(id, name, description); // <- Not sure about this one either
return new MetricDefinition(id);
}

9
com.unity.perception/Runtime/GroundTruth/SimulationState_Json.cs


return;
}
void Write(List<PendingMetric> pendingMetrics, int metricsFileIndex)
void Write(List<PendingMetric> pendingMetrics, SimulationState simState, int metricsFileIndex)
GetActiveReporter()?.ProcessPendingMetrics(pendingMetrics, simState);
#if false
m_SerializeMetricsAsyncSampler.Begin();
var jArray = new JArray();
foreach (var pendingMetric in pendingMetrics)

WriteJObjectToFile(metricsJObject, $"metrics_{metricsFileIndex:000}.json");
m_SerializeMetricsAsyncSampler.End();
#endif
Write(pendingMetricsToWrite, m_MetricsFileIndex);
Write(pendingMetricsToWrite, this, m_MetricsFileIndex);
}
else
{

};
req.Enqueue(r =>
{
Write(r.data.PendingMetrics, r.data.MetricFileIndex);
Write(r.data.PendingMetrics, this, r.data.MetricFileIndex);
return AsyncRequest.Result.Completed;
});
req.Execute();

8
com.unity.perception/Runtime/GroundTruth/Exporters/SOLO.meta


fileFormatVersion: 2
guid: e34b42ace3dcbaa45a44f0a85ac99ec2
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

103
com.unity.perception/Runtime/GroundTruth/Exporters/SOLO/AnnotationHandler.cs


using System;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Unity.Simulation;
namespace UnityEngine.Perception.GroundTruth.Exporters.Solo
{
public static class AnnotationHandler
{
[Serializable]
struct BoundingBox2dRecord
{
public uint instanceId;
public int frame;
public int labelId;
public string labelName;
public float x;
public float y;
public float width;
public float height;
public string annotationId;
public string annotationDefinition;
public static BoundingBox2dRecord FromBoundingBoxValue(Guid annotationId, Guid annotationDefinition, BoundingBox2DLabeler.BoundingBoxValue bbox)
{
return new BoundingBox2dRecord
{
instanceId = bbox.instance_id,
frame = bbox.frame,
labelId = bbox.label_id,
labelName = bbox.label_name,
x = bbox.x,
y = bbox.y,
width = bbox.width,
height = bbox.height,
annotationId = annotationId.ToString(),
annotationDefinition = annotationDefinition.ToString()
};
}
public string ToJson()
{
return JsonUtility.ToJson(this, true);
}
}
public static async Task WriteOutJson(string path, string filename, string json)
{
if (true)
{
try
{
json = JToken.Parse(json).ToString(Formatting.Indented);
}
catch (Exception e)
{
Debug.LogException(e);
throw;
}
}
var writePath = Path.Combine(path, filename);
var file = File.CreateText(writePath);
await file.WriteAsync(json);
file.Close();
Manager.Instance.ConsumerFileProduced(writePath);
}
static async Task HandleBoundingBoxAnnotation(string path, Annotation annotation, AnnotationDefinition def, BoundingBox2DLabeler.BoundingBoxValue bbox)
{
var id = annotation.Id;
var defId = def.Id;
var converted = BoundingBox2dRecord.FromBoundingBoxValue(id, defId, bbox);
var filename = $"frame_{converted.frame}_id_{converted.instanceId}_bounding_box_2d.json";
var writePath = Path.Combine(path, filename);
var file = File.CreateText(writePath);
await file.WriteAsync(converted.ToJson());
file.Close();
Manager.Instance.ConsumerFileProduced(writePath);
}
public static async Task HandleAnnotation(string path, Annotation annotation, AnnotationDefinition def, object annotatedData)
{
switch (annotatedData)
{
case BoundingBox2DLabeler.BoundingBoxValue bbox:
await HandleBoundingBoxAnnotation(path, annotation, def, bbox);
break;
}
}
}
}

11
com.unity.perception/Runtime/GroundTruth/Exporters/SOLO/AnnotationHandler.cs.meta


fileFormatVersion: 2
guid: 09097c4d404c4d046b71f950ba044642
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

521
com.unity.perception/Runtime/GroundTruth/Exporters/SOLO/SoloExporter.cs


using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Unity.Simulation;
using UnityEngine.Perception.GroundTruth.Exporters.PerceptionFormat;
namespace UnityEngine.Perception.GroundTruth.Exporters.Solo
{
public class SoloExporter : IDatasetExporter
{
public bool prettyPrint = true;
string m_DirectoryName = string.Empty;
int m_UnknownFrameCount = 0;
public string GetRgbCaptureFilename(params (string, object)[] additionalSensorValues)
{
var frameArray = additionalSensorValues.Where(p => p.Item1 == "frame").Select(p => p.Item2);
var frame = frameArray.Any() ? (int)frameArray.First() : m_UnknownFrameCount++;
return Path.Combine(m_DirectoryName, $"rgb_{frame}.png");
}
public void OnSimulationBegin(string directoryName)
{
Debug.Log($"SS - New Perception - OnSimBegin");
m_Metadata = new Metadata
{
version = "0.1.1",
unity_version = "2019.4.26f1",
perception_version = "0.8.0-preview.4",
total_frames = 0,
total_sequences = 0,
sequences = null,
sensors = new[]
{
new CameraData
{
id = "camera",
modality = "camera",
resolution = new[] { 0, 0 }
}
}
};
m_DirectoryName = directoryName + Path.DirectorySeparatorChar + Guid.NewGuid() + Path.DirectorySeparatorChar;
if (!Directory.Exists(m_DirectoryName))
Directory.CreateDirectory(m_DirectoryName);
}
[Serializable]
struct Metadata
{
public string version;
public string unity_version;
public string perception_version;
public int total_frames;
public int total_sequences;
public SequenceData[] sequences;
public CameraData[] sensors;
}
[Serializable]
struct SequenceData
{
public string sequence_id;
public int steps;
}
[Serializable]
struct CameraData
{
public string id;
public string modality;
public int[] resolution;
}
Metadata m_Metadata;
void CopyDefFile(string contains, string newName)
{
var d = m_DirectoryName;
var up = Directory.GetParent(m_DirectoryName)?.ToString() ?? string.Empty;
up = Directory.GetParent(up)?.ToString() ?? string.Empty;
var files = Directory.EnumerateFiles(up);
foreach (var file in files)
{
if (Path.GetFileName(file).Contains(contains))
{
File.Copy(file, Path.Combine(m_DirectoryName, newName));
return;
}
}
}
public void OnSimulationEnd()
{
Debug.Log($"SS - New Perception - OnSimEnd");
var writePath = Path.Combine(m_DirectoryName, "metadata.json");
var file = File.CreateText(writePath);
Debug.Log("SS - New Perception - writing");
var sequences = new Dictionary<int, int>();
foreach (var (seq, step) in m_FrameToSequenceMap.Values)
{
sequences.TryGetValue(seq, out var max);
if (step > max) max = step;
sequences[seq] = max;
}
m_Metadata.total_sequences = sequences.Count;
m_Metadata.sequences = new SequenceData[sequences.Count];
for (var i = 0; i < sequences.Count; i++)
{
m_Metadata.sequences[i] = new SequenceData
{
sequence_id = $"sequence_{i}",
steps = sequences[i]
};
}
file.Write(JsonUtility.ToJson(m_Metadata, true));
file.Close();
CopyDefFile("annotation", "annotations.json");
CopyDefFile("metric_def", "metrics.json");
CopyDefFile("sensors", "sensors.json");
// Copy image files to the proper path
var d = m_DirectoryName;
var upOne = Path.Combine(m_DirectoryName, "..");
var upOne2 = Directory.GetParent(m_DirectoryName)?.ToString() ?? string.Empty;
var upTwo = Directory.GetParent(upOne2)?.ToString() ?? string.Empty;
var upThree = Directory.GetParent(upTwo)?.ToString() ?? string.Empty;
var dirs = Directory.EnumerateDirectories(upThree);
foreach (var dir in dirs)
{
if (dir.Contains("RGB"))
{
foreach (var f in Directory.EnumerateFiles(dir))
{
// Get the frame number from the path
var filename = Path.GetFileName(f);
var underscore = filename.IndexOf("_") + 1;
var dot = filename.IndexOf(".");
var frame = filename.Substring(underscore, dot - underscore);
var (seq, step) = m_FrameToSequenceMap[int.Parse(frame)];
var newFilename = $"step.{step}.capture.camera.png";
File.Copy(f, Path.Combine(m_DirectoryName, $"sequence.{seq}", newFilename));
}
}
else if (dir.Contains("Instance"))
{
foreach (var f in Directory.EnumerateFiles(dir))
{
// Get the frame number from the path
var filename = Path.GetFileName(f);
var underscore = filename.IndexOf("_") + 1;
var dot = filename.IndexOf(".");
var frame = filename.Substring(underscore, dot - underscore);
var (seq, step) = m_FrameToSequenceMap[int.Parse(frame)];
var newFilename = $"step.{step}.annotation.semantic_segmentation.camera.png";
File.Copy(f, Path.Combine(m_DirectoryName, $"sequence.{seq}", newFilename));
}
}
else if (dir.Contains("Semantic"))
{
foreach (var f in Directory.EnumerateFiles(dir))
{
// Get the frame number from the path
var filename = Path.GetFileName(f);
var underscore = filename.IndexOf("_") + 1;
var dot = filename.IndexOf(".");
var frame = filename.Substring(underscore, dot - underscore);
var (seq, step) = m_FrameToSequenceMap[int.Parse(frame)];
var newFilename = $"step.{step}.annotation.instance_segmentation.camera.png";
File.Copy(f, Path.Combine(m_DirectoryName, $"sequence.{seq}", newFilename));
}
}
}
// Go into the RGB directory
Manager.Instance.ConsumerFileProduced(writePath);
Task.WhenAll(m_PendingTasks);
}
public void OnAnnotationRegistered<TSpec>(Guid annotationId, TSpec[] values)
{
// Right now, do nothing :-)
}
Dictionary<Guid, (string, string)> m_MetricIdMap = new Dictionary<Guid, (string, string)>();
public void OnMetricRegistered(Guid metricId, string name, string description)
{
Debug.Log("On MetricRegistered");
m_MetricIdMap[metricId] = (name, description);
}
bool GetFilenameForMetric(int sequence, int step, object value, out string filename, out string id, out string def, out bool reportValues)
{
filename = string.Empty;
id = string.Empty;
def = string.Empty;
reportValues = true;
#if false
if (value is BoundingBox2DLabeler.BoundingBoxValue bbox)
{
m_FrameToSequenceMap[bbox.frame] = (sequence, step);
var frame = bbox.frame;
id = "bounding_box";
def = $"{id}_definition";
// var fmt = new String('0', 5);
// var format = "{0,20:" + fmt + "}";
// filename = $"step.{frame.ToString(format)}.annotation.bounding_box.camera.json";
filename = $"step.{step}.annotation.{id}.camera.json";
return true;
}
if (rawData is InstanceSegmentationLabeler.InstanceColorValue)
{
id = "instance_segmentation";
def = $"{id}_definition";
// var fmt = new String('0', 5);
// var format = "{0,20:" + fmt + "}";
// filename = $"step.{frame.ToString(format)}.annotation.bounding_box.camera.json";
filename = $"step.{step}.annotation.{id}.camera.json";
return true;
}
if (rawData is SemanticSegmentationLabeler.SegmentationValue)
{
id = "semantic_segmentation";
def = $"{id}_definition";
// var fmt = new String('0', 5);
// var format = "{0,20:" + fmt + "}";
// filename = $"step.{frame.ToString(format)}.annotation.bounding_box.camera.json";
filename = $"step.{step}.annotation.{id}.camera.json";
reportValues = false;
return true;
}
#endif
return false;
}
bool GetFilenameForAnnotation(int sequence, int step, object rawData, out string filename, out string id, out string def, out bool reportValues)
{
filename = string.Empty;
id = string.Empty;
def = string.Empty;
reportValues = true;
if (rawData is BoundingBox2DLabeler.BoundingBoxValue bbox)
{
m_FrameToSequenceMap[bbox.frame] = (sequence, step);
var frame = bbox.frame;
id = "bounding_box";
def = $"{id}_definition";
// var fmt = new String('0', 5);
// var format = "{0,20:" + fmt + "}";
// filename = $"step.{frame.ToString(format)}.annotation.bounding_box.camera.json";
filename = $"step.{step}.annotation.{id}.camera.json";
return true;
}
if (rawData is InstanceSegmentationLabeler.InstanceColorValue)
{
id = "instance_segmentation";
def = $"{id}_definition";
// var fmt = new String('0', 5);
// var format = "{0,20:" + fmt + "}";
// filename = $"step.{frame.ToString(format)}.annotation.bounding_box.camera.json";
filename = $"step.{step}.annotation.{id}.camera.json";
return true;
}
if (rawData is SemanticSegmentationLabeler.SegmentationValue)
{
id = "semantic_segmentation";
def = $"{id}_definition";
// var fmt = new String('0', 5);
// var format = "{0,20:" + fmt + "}";
// filename = $"step.{frame.ToString(format)}.annotation.bounding_box.camera.json";
filename = $"step.{step}.annotation.{id}.camera.json";
reportValues = false;
return true;
}
return false;
}
// TODO - handle the 1000's of file writes we will be doing in a more intelligent fashion. Perhaps create a bg thread
// that reads json records off of a queue and writes them out
List<Task> m_PendingTasks = new List<Task>();
int m_CurrentSequence = 0;
Dictionary<Guid, int> m_SequenceGuidMap = new Dictionary<Guid, int>();
Dictionary<int, (int, int)> m_FrameToSequenceMap = new Dictionary<int, (int, int)>();
public Task ProcessPendingMetrics(List<SimulationState.PendingMetric> pendingMetrics, SimulationState simState)
{
foreach (var metric in pendingMetrics)
{
if (!m_SequenceGuidMap.TryGetValue(metric.SequenceId, out var seq))
{
seq = m_CurrentSequence++;
m_SequenceGuidMap[metric.SequenceId] = seq;
var seqDir = Path.Combine(m_DirectoryName, $"sequence.{m_SequenceGuidMap[metric.SequenceId]}");
// Create a directory
if (!Directory.Exists(seqDir))
Directory.CreateDirectory(seqDir);
}
var path = Path.Combine(m_DirectoryName, $"sequence.{m_SequenceGuidMap[metric.SequenceId]}");
if (!m_MetricIdMap.ContainsKey(metric.MetricDefinition.Id))
continue;
var label = m_MetricIdMap[metric.MetricDefinition.Id].Item1.Replace(" ", "_");
var filename = $"step.{metric.Step}.metric.{label}.camera.json";
var sensor = "camera";
var json = new StringBuilder();
json.Append($"{{\"capture_id\": \"{sensor}\",");
json.Append($"\"annotation_id\": \"\",");
json.Append($"\"metric_definition\": \"{label}\",");
json.Append("\"values\":");
json.Append(metric.Values);
json.Append("}");
m_PendingTasks.Add(AnnotationHandler.WriteOutJson(path, filename, json.ToString()));
#if false
if (GetFilenameForAnnotation(seq, metric.Step, value, out var filename, out var id, out var def, out var reportValues))
{
var sensor = "camera";
var json = new StringBuilder();
json.Append($"{{\"Id\": \"{id}\",");
json.Append($"\"definition\": \"{def}\",");
json.Append($"\"sequence\": {seq},");
json.Append($"\"step\": {metric.Step},");
json.Append($"\"sensor\": \"{sensor}\"");
if (reportValues)
{
json.Append(",\"values\":");
json.Append(annotationData.ValuesJson);
}
json.Append("}");
m_PendingTasks.Add(AnnotationHandler.WriteOutJson(path, filename, json.ToString()));
}
#endif
}
return Task.CompletedTask;
}
public Task ProcessPendingCaptures(List<SimulationState.PendingCapture> pendingCaptures, SimulationState simState)
{
foreach (var cap in pendingCaptures)
{
if (!m_SequenceGuidMap.TryGetValue(cap.SequenceId, out var seq))
{
seq = m_CurrentSequence++;
m_SequenceGuidMap[cap.SequenceId] = seq;
var seqDir = Path.Combine(m_DirectoryName, $"sequence.{m_SequenceGuidMap[cap.SequenceId]}");
// Create a directory
if (!Directory.Exists(seqDir))
Directory.CreateDirectory(seqDir);
}
var path = Path.Combine(m_DirectoryName, $"sequence.{m_SequenceGuidMap[cap.SequenceId]}");
foreach (var (annotation, annotationData) in cap.Annotations)
{
// Create a file for the annotation
#if false
if (annotationData.RawValues.Any())
{
var first = annotationData.RawValues.First();
if (GetFilenameForAnnotation(first, frame, out var filename))
{
var json = new StringBuilder("{");
json.Append(annotationData.ValuesJson);
json.Append("}");
m_PendingTasks.Add(AnnotationHandler.WriteOutJson(m_DirectoryName, filename, json.ToString()));
#if false
// Need to revisit this and handle this in a performant way
var jObject = PerceptionExporter.JObjectFromAnnotation((annotation, annotationData));
PerceptionExporter.WriteJObjectToFile(jObject, m_DirectoryName, filename);
#endif
}
}
#endif
foreach (var rawValue in annotationData.RawValues)
{
if (GetFilenameForAnnotation(seq, cap.Step, rawValue, out var filename, out var id, out var def, out var reportValues))
{
#if true
var sensor = "camera";
var json = new StringBuilder();
json.Append($"{{\"Id\": \"{id}\",");
json.Append($"\"definition\": \"{def}\",");
json.Append($"\"sequence\": {seq},");
json.Append($"\"step\": {cap.Step},");
json.Append($"\"sensor\": \"{sensor}\"");
if (reportValues)
{
json.Append(",\"values\":");
json.Append(annotationData.ValuesJson);
}
json.Append("}");
m_PendingTasks.Add(AnnotationHandler.WriteOutJson(path, filename, json.ToString()));
#else
// Need to revisit this and handle this in a performant way
var jObject = PerceptionExporter.JObjectFromAnnotation((annotation, annotationData));
PerceptionExporter.WriteJObjectToFile(jObject, m_DirectoryName, filename);
#endif
}
}
}
}
return Task.CompletedTask;
}
[Serializable]
struct SensorData
{
public string id;
public int sequence;
public int step;
public Vector3 translation;
public Vector3 rotation;
public Vector3 velocity;
public Vector3 acceleration;
}
public Task OnCaptureReported(Guid sequence, int step, int width, int height, string filename, Vector3 position, Quaternion rotation, Vector3 velocity, Vector3 acceleration)
{
var sensor = new SensorData
{
id = "camera",
sequence = 0,
step = 0,
translation = position,
rotation = rotation.eulerAngles,
velocity = velocity,
acceleration = acceleration
};
if (!m_SequenceGuidMap.TryGetValue(sequence, out var seq))
{
seq = m_CurrentSequence++;
m_SequenceGuidMap[sequence] = seq;
}
var path = Path.Combine(m_DirectoryName, $"sequence.{seq}");
if (!Directory.Exists(path))
Directory.CreateDirectory(path);
var f = $"step.{step}.camera.json";
var json = JsonUtility.ToJson(sensor, true);
m_PendingTasks.Add(AnnotationHandler.WriteOutJson(path, f, json));
m_Metadata.total_frames++;
m_Metadata.sensors[0].resolution = new[] { width, height };
return null;
}
}
}

11
com.unity.perception/Runtime/GroundTruth/Exporters/SOLO/SoloExporter.cs.meta


fileFormatVersion: 2
guid: f727b57d53e58c54b99a942650fe6e21
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
正在加载...
取消
保存