Steven Borkman
4 年前
当前提交
50825a13
共有 11 个文件被更改,包括 609 次插入 和 65 次删除
-
142com.unity.perception/Runtime/GroundTruth/Labelers/KeyPointLabeler.cs
-
109com.unity.perception/Runtime/GroundTruth/Labelers/Visualization/VisualizationHelper.cs
-
3com.unity.perception/Runtime/GroundTruth/Labelers/Visualization/VisualizationHelper.cs.meta
-
10com.unity.perception/Runtime/Randomization/Parameters/ParameterTypes/CategorialParameters/AnimationClipParameter.cs
-
3com.unity.perception/Runtime/Randomization/Parameters/ParameterTypes/CategorialParameters/AnimationClipParameter.cs.meta
-
67com.unity.perception/Runtime/Randomization/Randomizers/RandomizerExamples/Randomizers/AnimationRandomizer.cs
-
3com.unity.perception/Runtime/Randomization/Randomizers/RandomizerExamples/Randomizers/AnimationRandomizer.cs.meta
-
16com.unity.perception/Runtime/Randomization/Randomizers/RandomizerExamples/Tags/AnimationRandomizerTag.cs
-
3com.unity.perception/Runtime/Randomization/Randomizers/RandomizerExamples/Tags/AnimationRandomizerTag.cs.meta
-
307com.unity.perception/Tests/Runtime/GroundTruthTests/KeyPointGroundTruthTests.cs
-
11com.unity.perception/Tests/Runtime/GroundTruthTests/KeyPointGroundTruthTests.cs.meta
|
|||
namespace UnityEngine.Perception.GroundTruth |
|||
{ |
|||
/// <summary>
|
|||
/// Helper class that contains common visualization methods useful to ground truth labelers.
|
|||
/// </summary>
|
|||
public static class VisualizationHelper |
|||
{ |
|||
static Texture2D s_OnePixel = new Texture2D(1, 1); |
|||
|
|||
/// <summary>
|
|||
/// Converts a 3D world space coordinate to image pixel space.
|
|||
/// </summary>
|
|||
/// <param name="camera">The rendering camera</param>
|
|||
/// <param name="worldLocation">The 3D world location to convert</param>
|
|||
/// <returns>The coordinate in pixel space</returns>
|
|||
public static Vector3 ConvertToScreenSpace(Camera camera, Vector3 worldLocation) |
|||
{ |
|||
var pt = camera.WorldToScreenPoint(worldLocation); |
|||
pt.y = Screen.height - pt.y; |
|||
return pt; |
|||
} |
|||
|
|||
static Rect ToBoxRect(float x, float y, float halfSize = 3.0f) |
|||
{ |
|||
return new Rect(x - halfSize, y - halfSize, halfSize * 2, halfSize * 2); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draw a point (in pixel space) on the screen
|
|||
/// </summary>
|
|||
/// <param name="pt">The point location, in pixel space</param>
|
|||
/// <param name="color">The color of the point</param>
|
|||
/// <param name="width">The width of the point</param>
|
|||
/// <param name="texture">The texture to use for the point, defaults to a solid pixel</param>
|
|||
public static void DrawPoint(Vector3 pt, Color color, float width = 4.0f, Texture texture = null) |
|||
{ |
|||
DrawPoint(pt.x, pt.y, color, width, texture); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draw a point (in pixel space) on the screen
|
|||
/// </summary>
|
|||
/// <param name="x">The point's x value, in pixel space</param>
|
|||
/// <param name="y">The point's y value, in pixel space</param>
|
|||
/// <param name="color">The color of the point</param>
|
|||
/// <param name="width">The width of the point</param>
|
|||
/// <param name="texture">The texture to use for the point, defaults to a solid pixel</param>
|
|||
public static void DrawPoint(float x, float y, Color color, float width = 4, Texture texture = null) |
|||
{ |
|||
if (texture == null) texture = s_OnePixel; |
|||
var oldColor = GUI.color; |
|||
GUI.color = color; |
|||
GUI.DrawTexture(ToBoxRect(x, y, width * 0.5f), texture); |
|||
GUI.color = oldColor; |
|||
} |
|||
|
|||
static float Magnitude(float p1X, float p1Y, float p2X, float p2Y) |
|||
{ |
|||
var x = p2X - p1X; |
|||
var y = p2Y - p1Y; |
|||
return Mathf.Sqrt(x * x + y * y); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draw's a texture between two locations of a passed in width.
|
|||
/// </summary>
|
|||
/// <param name="p1">The start point in pixel space</param>
|
|||
/// <param name="p2">The end point in pixel space</param>
|
|||
/// <param name="color">The color of the line</param>
|
|||
/// <param name="width">The width of the line</param>
|
|||
/// <param name="texture">The texture to use, if null, will draw a solid line of passed in color</param>
|
|||
public static void DrawLine(Vector2 p1, Vector2 p2, Color color, float width = 3.0f, Texture texture = null) |
|||
{ |
|||
DrawLine(p1.x, p1.y, p2.x, p2.y, color, width, texture); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Draw's a texture between two locations of a passed in width.
|
|||
/// </summary>
|
|||
/// <param name="p1X">The start point's x coordinate in pixel space</param>
|
|||
/// <param name="p1Y">The start point's y coordinate in pixel space</param>
|
|||
/// <param name="p2X">The end point's x coordinate in pixel space</param>
|
|||
/// <param name="p2Y">The end point's y coordinate in pixel space</param>
|
|||
/// <param name="color">The color of the line</param>
|
|||
/// <param name="width">The width of the line</param>
|
|||
/// <param name="texture">The texture to use, if null, will draw a solid line of passed in color</param>
|
|||
public static void DrawLine (float p1X, float p1Y, float p2X, float p2Y, Color color, float width = 3.0f, Texture texture = null) |
|||
{ |
|||
if (texture == null) texture = s_OnePixel; |
|||
|
|||
var oldColor = GUI.color; |
|||
|
|||
GUI.color = color; |
|||
|
|||
var matrixBackup = GUI.matrix; |
|||
var angle = Mathf.Atan2 (p2Y - p1Y, p2X - p1X) * 180f / Mathf.PI; |
|||
|
|||
var length = Magnitude(p1X, p1Y, p2X, p2Y); |
|||
|
|||
GUIUtility.RotateAroundPivot (angle, new Vector2(p1X, p1Y)); |
|||
var halfWidth = width * 0.5f; |
|||
GUI.DrawTexture (new Rect (p1X - halfWidth, p1Y - halfWidth, length, width), texture); |
|||
|
|||
GUI.matrix = matrixBackup; |
|||
GUI.color = oldColor; |
|||
} |
|||
|
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: b4ef50bfa62549848a6d12c049397eba |
|||
timeCreated: 1611019489 |
|
|||
using System; |
|||
|
|||
namespace UnityEngine.Experimental.Perception.Randomization.Parameters |
|||
{ |
|||
/// <summary>
|
|||
/// A categorical parameter for animation clips
|
|||
/// </summary>
|
|||
[Serializable] |
|||
public class AnimationClipParameter : CategoricalParameter<AnimationClip> { } |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 6af6ee532f5e4e4b83353f2f32105665 |
|||
timeCreated: 1610935882 |
|
|||
using System; |
|||
using System.Collections.Generic; |
|||
using UnityEngine; |
|||
using UnityEngine.Animations; |
|||
using UnityEngine.Experimental.Perception.Randomization.Parameters; |
|||
using UnityEngine.Experimental.Perception.Randomization.Randomizers.SampleRandomizers.Tags; |
|||
using UnityEngine.Experimental.Perception.Randomization.Samplers; |
|||
using UnityEngine.Playables; |
|||
|
|||
namespace UnityEngine.Experimental.Perception.Randomization.Randomizers.SampleRandomizers |
|||
{ |
|||
/// <summary>
|
|||
/// Chooses a random of frame of a random clip for a gameobject
|
|||
/// </summary>
|
|||
[Serializable] |
|||
[AddRandomizerMenu("Perception/Animation Randomizer")] |
|||
public class AnimationRandomizer : Randomizer |
|||
{ |
|||
FloatParameter m_FloatParameter = new FloatParameter{ value = new UniformSampler(0, 1) }; |
|||
Dictionary<GameObject, (PlayableGraph, Animator)> m_GraphMap; |
|||
|
|||
/// <inheritdoc/>
|
|||
protected override void OnCreate() |
|||
{ |
|||
m_GraphMap = new Dictionary<GameObject, (PlayableGraph, Animator)>(); |
|||
} |
|||
|
|||
(PlayableGraph, Animator) GetGraph(GameObject gameObject) |
|||
{ |
|||
if (!m_GraphMap.ContainsKey(gameObject)) |
|||
{ |
|||
var graph = PlayableGraph.Create(); |
|||
graph.SetTimeUpdateMode(DirectorUpdateMode.GameTime); |
|||
var animator = gameObject.GetComponent<Animator>(); |
|||
m_GraphMap[gameObject] = (graph, animator); |
|||
} |
|||
|
|||
return m_GraphMap[gameObject]; |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
protected override void OnIterationStart() |
|||
{ |
|||
var taggedObjects = tagManager.Query<AnimationRandomizerTag>(); |
|||
foreach (var taggedObject in taggedObjects) |
|||
{ |
|||
var (graph, animator) = GetGraph(taggedObject.gameObject); |
|||
|
|||
var tag = taggedObject.GetComponent<AnimationRandomizerTag>(); |
|||
|
|||
var clips = tag.animationClips; |
|||
CategoricalParameter<AnimationClip> param = new AnimationClipParameter(); |
|||
param.SetOptions(clips); |
|||
var clip = param.Sample(); |
|||
|
|||
var output = AnimationPlayableOutput.Create(graph, "Animation", animator); |
|||
var playable = AnimationClipPlayable.Create(graph, clip); |
|||
output.SetSourcePlayable(playable); |
|||
var l = clip.length; |
|||
var t = m_FloatParameter.Sample(); |
|||
playable.SetTime(t * l); |
|||
playable.SetSpeed(0); |
|||
graph.Play(); |
|||
} |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 8b57910cfd4a4dec90d6aa4a8ef824da |
|||
timeCreated: 1610802187 |
|
|||
namespace UnityEngine.Experimental.Perception.Randomization.Randomizers.SampleRandomizers.Tags |
|||
{ |
|||
/// <summary>
|
|||
/// Used in conjunction with a <see cref="AnimationRandomizer"/> to select a random animation frame for
|
|||
/// the tagged game object
|
|||
/// </summary>
|
|||
[RequireComponent(typeof(Animator))] |
|||
[AddComponentMenu("Perception/RandomizerTags/Animation Randomizer Tag")] |
|||
public class AnimationRandomizerTag : RandomizerTag |
|||
{ |
|||
/// <summary>
|
|||
/// A list of animation clips from which to choose
|
|||
/// </summary>
|
|||
public AnimationClip[] animationClips; |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: f8943e41c7c34facb177a5decc1b2aef |
|||
timeCreated: 1610802367 |
|
|||
using System; |
|||
using System.Collections; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using NUnit.Framework; |
|||
using UnityEngine; |
|||
using UnityEngine.Perception.GroundTruth; |
|||
using UnityEngine.TestTools; |
|||
|
|||
namespace GroundTruthTests |
|||
{ |
|||
[TestFixture] |
|||
public class KeyPointGroundTruthTests : GroundTruthTestBase |
|||
{ |
|||
static GameObject SetupCamera(IdLabelConfig config, KeyPointTemplate template, Action<List<KeyPointLabeler.KeyPointEntry>> computeListener) |
|||
{ |
|||
var cameraObject = new GameObject(); |
|||
cameraObject.SetActive(false); |
|||
var camera = cameraObject.AddComponent<Camera>(); |
|||
camera.orthographic = false; |
|||
camera.fieldOfView = 60; |
|||
camera.nearClipPlane = 0.3f; |
|||
camera.farClipPlane = 1000; |
|||
|
|||
camera.transform.position = new Vector3(0, 0, -10); |
|||
|
|||
var perceptionCamera = cameraObject.AddComponent<PerceptionCamera>(); |
|||
perceptionCamera.captureRgbImages = false; |
|||
var keyPointLabeler = new KeyPointLabeler(config, template); |
|||
if (computeListener != null) |
|||
keyPointLabeler.KeyPointsComputed += computeListener; |
|||
|
|||
perceptionCamera.AddLabeler(keyPointLabeler); |
|||
|
|||
return cameraObject; |
|||
} |
|||
|
|||
static KeyPointTemplate CreateTestTemplate(Guid guid, string label) |
|||
{ |
|||
var keyPoints = new[] |
|||
{ |
|||
new KeyPointDefinition |
|||
{ |
|||
label = "FrontLowerLeft", |
|||
associateToRig = false, |
|||
color = Color.black |
|||
}, |
|||
new KeyPointDefinition |
|||
{ |
|||
label = "FrontUpperLeft", |
|||
associateToRig = false, |
|||
color = Color.black |
|||
}, |
|||
new KeyPointDefinition |
|||
{ |
|||
label = "FrontUpperRight", |
|||
associateToRig = false, |
|||
color = Color.black |
|||
}, |
|||
new KeyPointDefinition |
|||
{ |
|||
label = "FrontLowerRight", |
|||
associateToRig = false, |
|||
color = Color.black |
|||
}, |
|||
new KeyPointDefinition |
|||
{ |
|||
label = "BackLowerLeft", |
|||
associateToRig = false, |
|||
color = Color.black |
|||
}, |
|||
new KeyPointDefinition |
|||
{ |
|||
label = "BackUpperLeft", |
|||
associateToRig = false, |
|||
color = Color.black |
|||
}, |
|||
new KeyPointDefinition |
|||
{ |
|||
label = "BackUpperRight", |
|||
associateToRig = false, |
|||
color = Color.black |
|||
}, |
|||
new KeyPointDefinition |
|||
{ |
|||
label = "BackLowerRight", |
|||
associateToRig = false, |
|||
color = Color.black |
|||
}, |
|||
new KeyPointDefinition |
|||
{ |
|||
label = "Center", |
|||
associateToRig = false, |
|||
color = Color.black |
|||
} |
|||
}; |
|||
|
|||
var skeleton = new[] |
|||
{ |
|||
new SkeletonDefinition |
|||
{ |
|||
joint1 = 0, |
|||
joint2 = 1, |
|||
color = Color.magenta |
|||
}, |
|||
new SkeletonDefinition |
|||
{ |
|||
joint1 = 1, |
|||
joint2 = 2, |
|||
color = Color.magenta |
|||
}, |
|||
new SkeletonDefinition |
|||
{ |
|||
joint1 = 2, |
|||
joint2 = 3, |
|||
color = Color.magenta |
|||
}, |
|||
new SkeletonDefinition |
|||
{ |
|||
joint1 = 3, |
|||
joint2 = 0, |
|||
color = Color.magenta |
|||
}, |
|||
|
|||
new SkeletonDefinition |
|||
{ |
|||
joint1 = 4, |
|||
joint2 = 5, |
|||
color = Color.blue |
|||
}, |
|||
new SkeletonDefinition |
|||
{ |
|||
joint1 = 5, |
|||
joint2 = 6, |
|||
color = Color.blue |
|||
}, |
|||
new SkeletonDefinition |
|||
{ |
|||
joint1 = 6, |
|||
joint2 = 7, |
|||
color = Color.blue |
|||
}, |
|||
new SkeletonDefinition |
|||
{ |
|||
joint1 = 7, |
|||
joint2 = 4, |
|||
color = Color.blue |
|||
}, |
|||
|
|||
new SkeletonDefinition |
|||
{ |
|||
joint1 = 0, |
|||
joint2 = 4, |
|||
color = Color.green |
|||
}, |
|||
new SkeletonDefinition |
|||
{ |
|||
joint1 = 1, |
|||
joint2 = 5, |
|||
color = Color.green |
|||
}, |
|||
new SkeletonDefinition |
|||
{ |
|||
joint1 = 2, |
|||
joint2 = 6, |
|||
color = Color.green |
|||
}, |
|||
new SkeletonDefinition |
|||
{ |
|||
joint1 = 3, |
|||
joint2 = 7, |
|||
color = Color.green |
|||
}, |
|||
}; |
|||
|
|||
var template = ScriptableObject.CreateInstance<KeyPointTemplate>(); |
|||
template.templateID = guid; |
|||
template.templateName = label; |
|||
template.jointTexture = null; |
|||
template.skeletonTexture = null; |
|||
template.keyPoints = keyPoints; |
|||
template.skeleton = skeleton; |
|||
|
|||
return template; |
|||
} |
|||
|
|||
[Test] |
|||
public void KeypointTemplate_CreateTemplateTest() |
|||
{ |
|||
var guid = Guid.NewGuid(); |
|||
const string label = "TestTemplate"; |
|||
var template = CreateTestTemplate(guid, label); |
|||
|
|||
Assert.AreEqual(template.templateID, guid); |
|||
Assert.AreEqual(template.templateName, label); |
|||
Assert.IsNull(template.jointTexture); |
|||
Assert.IsNull(template.skeletonTexture); |
|||
Assert.IsNotNull(template.keyPoints); |
|||
Assert.IsNotNull(template.skeleton); |
|||
Assert.AreEqual(template.keyPoints.Length, 9); |
|||
Assert.AreEqual(template.skeleton.Length, 12); |
|||
|
|||
var k0 = template.keyPoints[0]; |
|||
Assert.NotNull(k0); |
|||
Assert.AreEqual(k0.label, "FrontLowerLeft"); |
|||
Assert.False(k0.associateToRig); |
|||
Assert.AreEqual(k0.color, Color.black); |
|||
|
|||
var s0 = template.skeleton[0]; |
|||
Assert.NotNull(s0); |
|||
Assert.AreEqual(s0.joint1, 0); |
|||
Assert.AreEqual(s0.joint2, 1); |
|||
Assert.AreEqual(s0.color, Color.magenta); |
|||
} |
|||
|
|||
static IdLabelConfig SetUpLabelConfig() |
|||
{ |
|||
var cfg = ScriptableObject.CreateInstance<IdLabelConfig>(); |
|||
cfg.Init(new List<IdLabelEntry>() |
|||
{ |
|||
new IdLabelEntry |
|||
{ |
|||
id = 1, |
|||
label = "label" |
|||
} |
|||
}); |
|||
|
|||
return cfg; |
|||
} |
|||
|
|||
static void SetupCubeJoint(GameObject cube, KeyPointTemplate template, string label, float x, float y, float z) |
|||
{ |
|||
var joint = new GameObject(); |
|||
joint.transform.parent = cube.transform; |
|||
joint.transform.localPosition = new Vector3(x, y, z); |
|||
var jointLabel = joint.AddComponent<JointLabel>(); |
|||
jointLabel.templateInformation = new List<JointLabel.TemplateData>(); |
|||
var templateData = new JointLabel.TemplateData |
|||
{ |
|||
template = template, |
|||
label = label |
|||
}; |
|||
jointLabel.templateInformation.Add(templateData); |
|||
} |
|||
|
|||
static void SetupCubeJoints(GameObject cube, KeyPointTemplate template) |
|||
{ |
|||
SetupCubeJoint(cube, template, "FrontLowerLeft", -0.5f, -0.5f, -0.5f); |
|||
SetupCubeJoint(cube, template, "FrontUpperLeft", -0.5f, 0.5f, -0.5f); |
|||
SetupCubeJoint(cube, template, "FrontUpperRight", 0.5f, 0.5f, -0.5f); |
|||
SetupCubeJoint(cube, template, "FrontLowerRight", 0.5f, -0.5f, -0.5f); |
|||
SetupCubeJoint(cube, template, "BackLowerLeft", -0.5f, -0.5f, 0.5f); |
|||
SetupCubeJoint(cube, template, "BackUpperLeft", -0.5f, 0.5f, 0.5f); |
|||
SetupCubeJoint(cube, template, "BackUpperRight", 0.5f, 0.5f, 0.5f); |
|||
SetupCubeJoint(cube, template, "BackLowerRight", 0.5f, -0.5f, 0.5f); |
|||
} |
|||
|
|||
[UnityTest] |
|||
public IEnumerator Keypoint_TestStaticLabeledCube() |
|||
{ |
|||
var incoming = new List<List<KeyPointLabeler.KeyPointEntry>>(); |
|||
var template = CreateTestTemplate(Guid.NewGuid(), "TestTemplate"); |
|||
|
|||
var cam = SetupCamera(SetUpLabelConfig(), template, (data) => |
|||
{ |
|||
incoming.Add(data); |
|||
}); |
|||
|
|||
var cube = TestHelper.CreateLabeledCube(scale: 6, z: 8); |
|||
SetupCubeJoints(cube, template); |
|||
|
|||
cube.SetActive(true); |
|||
cam.SetActive(true); |
|||
|
|||
AddTestObjectForCleanup(cam); |
|||
AddTestObjectForCleanup(cube); |
|||
|
|||
yield return null; |
|||
yield return null; |
|||
|
|||
var testCase = incoming.Last(); |
|||
Assert.AreEqual(1, testCase.Count); |
|||
var t = testCase.First(); |
|||
Assert.NotNull(t); |
|||
Assert.AreEqual(1, t.instance_id); |
|||
Assert.AreEqual(1, t.label_id); |
|||
Assert.AreEqual(template.templateID.ToString(), t.template_guid); |
|||
Assert.AreEqual(9, t.keypoints.Length); |
|||
|
|||
Assert.AreEqual(t.keypoints[0].x, t.keypoints[1].x); |
|||
Assert.AreEqual(t.keypoints[2].x, t.keypoints[3].x); |
|||
Assert.AreEqual(t.keypoints[4].x, t.keypoints[5].x); |
|||
Assert.AreEqual(t.keypoints[6].x, t.keypoints[7].x); |
|||
|
|||
Assert.AreEqual(t.keypoints[0].y, t.keypoints[3].y); |
|||
Assert.AreEqual(t.keypoints[1].y, t.keypoints[2].y); |
|||
Assert.AreEqual(t.keypoints[4].y, t.keypoints[7].y); |
|||
Assert.AreEqual(t.keypoints[5].y, t.keypoints[6].y); |
|||
|
|||
for (var i = 0; i < 9; i++) Assert.AreEqual(i, t.keypoints[i].index); |
|||
for (var i = 0; i < 8; i++) Assert.AreEqual(1, t.keypoints[i].state); |
|||
Assert.Zero(t.keypoints[8].state); |
|||
Assert.Zero(t.keypoints[8].x); |
|||
Assert.Zero(t.keypoints[8].y); |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: c62092ba10e4e4a80a0ec03e6e92593a |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
撰写
预览
正在加载...
取消
保存
Reference in new issue