Skip to content

Commit 12a2955

Browse files
authored
Merge branch 'master' into fix_wrong_label
2 parents 3ca8e97 + 0532e91 commit 12a2955

File tree

4 files changed

+82
-28
lines changed

4 files changed

+82
-28
lines changed

com.unity.perception/CHANGELOG.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ The randomizer methods OnCreate(), OnStartRunning(), and OnStopRunning() are now
5353

5454
CameraLabeler methods OnBeginRendering() and OnEndRendering() have an added ScriptableRenderContext parameter.
5555

56+
Upgraded com.unity.simulation.capture package dependency to integrate new changes that prevent the API updater from looping infinitely when opening the project settings window on new URP projects.
57+
5658
### Deprecated
5759

5860
### Removed
@@ -71,7 +73,9 @@ Fixed an issue preventing a user from adding more options to a Categorical Param
7173

7274
Fixed a bug where uniform probabilities were not properly reset upon adding or removing options from a Categorical Parameter's list of options.
7375

74-
Fixed keypoints being reported in wrong locations on the first frame an object is visible.
76+
Fixed keypoints being reported in wrong locations on the first frame an object is visible.
77+
78+
Fixed an out of range error if a keypoint template skeleton relies on a joint that is not available.
7579

7680
Fixed wrong labels on 2d bounding boxes when all labeled objects are deleted in a frame.
7781

com.unity.perception/Runtime/GroundTruth/Labelers/KeypointLabeler.cs

Lines changed: 66 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -104,14 +104,63 @@ bool AreEqual(Color32 lhs, Color32 rhs)
104104
return lhs.r == rhs.r && lhs.g == rhs.g && lhs.b == rhs.b && lhs.a == rhs.a;
105105
}
106106

107+
bool PixelOnScreen(int x, int y, (int x, int y) dimensions)
108+
{
109+
return x >= 0 && x < dimensions.x && y >= 0 && y < dimensions.y;
110+
}
111+
112+
bool PixelsMatch(int x, int y, Color32 idColor, (int x, int y) dimensions, NativeArray<Color32> data)
113+
{
114+
var h = dimensions.y - y;
115+
var pixelColor = data[h * dimensions.x + x];
116+
return AreEqual(pixelColor, idColor);
117+
}
118+
119+
static int s_PixelTolerance = 1;
120+
121+
// Determine the state of a keypoint. A keypoint is considered visible (state = 2) if it is on screen and not occluded
122+
// by another object. The way that we determine if a point is occluded is by checking the pixel location of the keypoint
123+
// against the instance segmentation mask for the frame. The instance segmentation mask provides the instance id of the
124+
// visible object at a pixel location. Which means, if the keypoint does not match the visible pixel, then another
125+
// object is in front of the keypoint occluding it from view. An important note here is that the keypoint is an infintely small
126+
// point in space, which can lead to false negatives due to rounding issues if the keypoint is on the edge of an object or very
127+
// close to the edge of the screen. Because of this we will test not only the keypoint pixel, but also the immediate surrounding
128+
// pixels to determine if the pixel is really visible. This method returns 1 if the pixel is not visible but on screen, and 0
129+
// if the pixel is off of the screen (taken the tolerance into account).
130+
int DetermineKeypointState(Keypoint keypoint, Color32 instanceIdColor, (int x, int y) dimensions, NativeArray<Color32> data)
131+
{
132+
if (keypoint.state == 0) return 0;
133+
134+
var centerX = Mathf.RoundToInt(keypoint.x);
135+
var centerY = Mathf.RoundToInt(keypoint.y);
136+
137+
var pixelOnScreen = false;
138+
139+
for (var y = centerY - s_PixelTolerance; y <= centerY + s_PixelTolerance; y++)
140+
{
141+
for (var x = centerX - s_PixelTolerance; x <= centerX + s_PixelTolerance; x++)
142+
{
143+
if (!PixelOnScreen(x, y, dimensions)) continue;
144+
145+
pixelOnScreen = true;
146+
if (PixelsMatch(x, y, instanceIdColor, dimensions, data))
147+
{
148+
return 2;
149+
}
150+
}
151+
}
152+
153+
return pixelOnScreen ? 1 : 0;
154+
}
155+
107156
void OnInstanceSegmentationImageReadback(int frameCount, NativeArray<Color32> data, RenderTexture renderTexture)
108157
{
109158
if (!m_AsyncAnnotations.TryGetValue(frameCount, out var asyncAnnotation))
110159
return;
111160

112161
m_AsyncAnnotations.Remove(frameCount);
113162

114-
var width = renderTexture.width;
163+
var dimensions = (renderTexture.width, renderTexture.height);
115164

116165
m_ToReport.Clear();
117166

@@ -123,22 +172,15 @@ void OnInstanceSegmentationImageReadback(int frameCount, NativeArray<Color32> da
123172

124173
foreach (var keypoint in keypointSet.Value.keypoints)
125174
{
126-
// If the keypoint isn't mapped to a body part keep it at 0
127-
if (keypoint.state == 0) continue;
175+
keypoint.state = DetermineKeypointState(keypoint, idColor, dimensions, data);
128176

129-
if (keypoint.x < 0 || keypoint.x > width || keypoint.y < 0 || keypoint.y > renderTexture.height)
177+
if (keypoint.state == 0)
130178
{
131-
keypoint.state = 0;
132179
keypoint.x = 0;
133180
keypoint.y = 0;
134181
}
135182
else
136183
{
137-
// Get the pixel color at the keypoints location
138-
var height = renderTexture.height - (int)keypoint.y;
139-
var pixel = data[height * width + (int)keypoint.x];
140-
141-
keypoint.state = AreEqual(pixel, idColor) ? 2 : 1;
142184
shouldReport = true;
143185
}
144186
}
@@ -230,8 +272,9 @@ public class Keypoint
230272

231273
float GetCaptureHeight()
232274
{
233-
return perceptionCamera.attachedCamera.targetTexture != null ?
234-
perceptionCamera.attachedCamera.targetTexture.height : Screen.height;
275+
var targetTexture = perceptionCamera.attachedCamera.targetTexture;
276+
return targetTexture != null ?
277+
targetTexture.height : Screen.height;
235278
}
236279

237280
// Converts a coordinate from world space into pixel space
@@ -307,7 +350,7 @@ void ProcessLabel(Labeling labeledEntity)
307350

308351
cached.keypoints.instance_id = labeledEntity.instanceId;
309352
cached.keypoints.label_id = labelEntry.id;
310-
cached.keypoints.template_guid = activeTemplate.templateID.ToString();
353+
cached.keypoints.template_guid = activeTemplate.templateID;
311354

312355
cached.keypoints.keypoints = new Keypoint[activeTemplate.keypoints.Length];
313356
for (var i = 0; i < cached.keypoints.keypoints.Length; i++)
@@ -408,6 +451,12 @@ string GetPose(Animator animator)
408451
return "unset";
409452
}
410453

454+
Keypoint GetKeypointForJoint(KeypointEntry entry, int joint)
455+
{
456+
if (joint < 0 || joint >= entry.keypoints.Length) return null;
457+
return entry.keypoints[joint];
458+
}
459+
411460
/// <inheritdoc/>
412461
protected override void OnVisualize()
413462
{
@@ -423,10 +472,10 @@ protected override void OnVisualize()
423472
{
424473
foreach (var bone in activeTemplate.skeleton)
425474
{
426-
var joint1 = entry.keypoints[bone.joint1];
427-
var joint2 = entry.keypoints[bone.joint2];
475+
var joint1 = GetKeypointForJoint(entry, bone.joint1);
476+
var joint2 = GetKeypointForJoint(entry, bone.joint2);
428477

429-
if (joint1.state == 2 && joint2.state == 2)
478+
if (joint1 != null && joint1.state == 2 && joint2 != null && joint2.state == 2)
430479
{
431480
VisualizationHelper.DrawLine(joint1.x, joint1.y, joint2.x, joint2.y, bone.color, 8, skeletonTexture);
432481
}
@@ -472,7 +521,7 @@ struct KeypointJson
472521
KeypointJson TemplateToJson(KeypointTemplate input)
473522
{
474523
var json = new KeypointJson();
475-
json.template_id = input.templateID.ToString();
524+
json.template_id = input.templateID;
476525
json.template_name = input.templateName;
477526
json.key_points = new JointJson[input.keypoints.Length];
478527
json.skeleton = new SkeletonJson[input.skeleton.Length];

com.unity.perception/Tests/Runtime/GroundTruthTests/KeypointGroundTruthTests.cs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -271,14 +271,15 @@ static void SetupCubeJoint(GameObject cube, KeypointTemplate template, string la
271271

272272
static void SetupCubeJoints(GameObject cube, KeypointTemplate template)
273273
{
274-
SetupCubeJoint(cube, template, "FrontLowerLeft", -0.495f, -0.495f, -0.495f);
275-
SetupCubeJoint(cube, template, "FrontUpperLeft", -0.495f, 0.495f, -0.495f);
276-
SetupCubeJoint(cube, template, "FrontUpperRight", 0.495f, 0.495f, -0.495f);
277-
SetupCubeJoint(cube, template, "FrontLowerRight", 0.495f, -0.495f, -0.495f);
278-
SetupCubeJoint(cube, template, "BackLowerLeft", -0.495f, -0.495f, 0.495f);
279-
SetupCubeJoint(cube, template, "BackUpperLeft", -0.495f, 0.495f, 0.495f);
280-
SetupCubeJoint(cube, template, "BackUpperRight", 0.495f, 0.495f, 0.495f);
281-
SetupCubeJoint(cube, template, "BackLowerRight", 0.495f, -0.495f, 0.495f);
274+
const float dim = 0.5f;
275+
SetupCubeJoint(cube, template, "FrontLowerLeft", -dim, -dim, -dim);
276+
SetupCubeJoint(cube, template, "FrontUpperLeft", -dim, dim, -dim);
277+
SetupCubeJoint(cube, template, "FrontUpperRight", dim, dim, -dim);
278+
SetupCubeJoint(cube, template, "FrontLowerRight", dim, -dim, -dim);
279+
SetupCubeJoint(cube, template, "BackLowerLeft", -dim, -dim, dim);
280+
SetupCubeJoint(cube, template, "BackUpperLeft", -dim, dim, dim);
281+
SetupCubeJoint(cube, template, "BackUpperRight", dim, dim, dim);
282+
SetupCubeJoint(cube, template, "BackLowerRight", dim, -dim, dim);
282283
}
283284

284285
[UnityTest]

com.unity.perception/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"com.unity.collections": "0.9.0-preview.6",
55
"com.unity.nuget.newtonsoft-json": "1.1.2",
66
"com.unity.render-pipelines.core": "7.1.6",
7-
"com.unity.simulation.capture": "0.0.10-preview.19",
7+
"com.unity.simulation.capture": "0.0.10-preview.20",
88
"com.unity.simulation.client": "0.0.10-preview.10",
99
"com.unity.simulation.core": "0.0.10-preview.22"
1010
},
@@ -25,4 +25,4 @@
2525
"path": "Samples~/Human Pose Labeling and Randomization"
2626
}
2727
]
28-
}
28+
}

0 commit comments

Comments
 (0)