[Vision] Update Xcode 15 support (#19412)

This commit adds some missing bindings and fixes up some of the previous
API that were incorrectly bound with Vector4 instead of Matrix4.

A sample app using some of these latest bindings can be found here:
https://github.com/haritha-mohan/vision-analyzer

Contributes to https://github.com/xamarin/maccore/issues/2719, though
the manual testing ended up not being necessary still helped catch a few
bugs and showcases some of the latest work done for this Xcode release.

---------

Co-authored-by: GitHub Actions Autoformatter <github-actions-autoformatter@xamarin.com>
Co-authored-by: Rolf Bjarne Kvinge <rolf@xamarin.com>
This commit is contained in:
Haritha Mohan 2024-01-02 15:17:57 -05:00 коммит произвёл GitHub
Родитель d9e52067e2
Коммит f39489fe60
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
9 изменённых файлов: 220 добавлений и 18 удалений

Просмотреть файл

@ -16,6 +16,8 @@ using System;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using ObjCRuntime;
#if NET
using VectorFloat4 = global::System.Numerics.Vector4;
#else
@ -35,6 +37,7 @@ namespace OpenTK
[SupportedOSPlatform ("tvos")]
#endif
[StructLayout (LayoutKind.Sequential)]
[NativeName ("simd_float4x4")]
public struct NMatrix4 : IEquatable<NMatrix4> {
public float M11;
public float M21;

Просмотреть файл

@ -23,13 +23,13 @@ using AVFoundation;
#if NET
using Vector2 = global::System.Numerics.Vector2;
using Vector3 = global::System.Numerics.Vector3;
using Vector4 = global::System.Numerics.Vector4;
using Matrix3 = global::CoreGraphics.NMatrix3;
using Matrix4 = global::CoreGraphics.NMatrix4;
#else
using Vector2 = global::OpenTK.Vector2;
using Vector3 = global::OpenTK.Vector3;
using Vector4 = global::OpenTK.Vector4;
using Matrix3 = global::OpenTK.NMatrix3;
using Matrix4 = global::OpenTK.NMatrix4;
#endif
#if !NET
@ -202,6 +202,10 @@ namespace Vision {
[TV (15, 0), Mac (12, 0), iOS (15, 0)]
[MacCatalyst (15, 0)]
Two = 2,
[TV (16, 0), Mac (13, 0), iOS (16, 0), MacCatalyst (16, 0)]
Three = 3,
[TV (17, 0), Mac (14, 0), iOS (17, 0), MacCatalyst (17, 0)]
Four = 4,
}
[TV (12, 0), iOS (12, 0)]
@ -346,6 +350,8 @@ namespace Vision {
enum VNClassifyImageRequestRevision : ulong {
Unspecified = 0,
One = 1,
[TV (17, 0), Mac (14, 0), iOS (17, 0), MacCatalyst (17, 0)]
Two = 2,
}
[TV (15, 0), Mac (12, 0), iOS (15, 0), MacCatalyst (15, 0)]
@ -363,6 +369,8 @@ namespace Vision {
[TV (14, 0), Mac (11, 0), iOS (14, 0)]
[MacCatalyst (14, 0)]
Two = 2,
[TV (17, 0), Mac (14, 0), iOS (17, 0), MacCatalyst (17, 0)]
Three = 3,
}
[TV (13, 0), iOS (13, 0)]
@ -390,6 +398,8 @@ namespace Vision {
enum VNGenerateAttentionBasedSaliencyImageRequestRevision : ulong {
Unspecified = 0,
One = 1,
[TV (17, 0), Mac (14, 0), iOS (17, 0), MacCatalyst (17, 0)]
Two = 2,
}
[TV (13, 0), iOS (13, 0)]
@ -398,6 +408,8 @@ namespace Vision {
enum VNGenerateImageFeaturePrintRequestRevision : ulong {
Unspecified = 0,
One = 1,
[TV (17, 0), Mac (14, 0), iOS (17, 0), MacCatalyst (17, 0)]
Two = 2,
}
[TV (13, 0), iOS (13, 0)]
@ -406,6 +418,8 @@ namespace Vision {
enum VNGenerateObjectnessBasedSaliencyImageRequestRevision : ulong {
Unspecified = 0,
One = 1,
[TV (17, 0), Mac (14, 0), iOS (17, 0), MacCatalyst (17, 0)]
Two = 2,
}
[TV (13, 0), iOS (13, 0)]
@ -510,6 +524,30 @@ namespace Vision {
One = 1,
}
[TV (17, 0), Mac (14, 0), iOS (17, 0), MacCatalyst (17, 0)]
[Native]
enum VNDetectHumanBodyPose3DRequestRevision : ulong {
One = 1,
}
[TV (17, 0), Mac (14, 0), iOS (17, 0), MacCatalyst (17, 0)]
[Native]
enum VNTrackHomographicImageRegistrationRequestRevision : ulong {
One = 1,
}
[TV (17, 0), Mac (14, 0), iOS (17, 0), MacCatalyst (17, 0)]
[Native]
enum VNTrackTranslationalImageRegistrationRequestRevision : ulong {
One = 1,
}
[TV (17, 0), Mac (14, 0), iOS (17, 0), MacCatalyst (17, 0)]
[Native]
enum VNTrackOpticalFlowRequestRevision : ulong {
One = 1,
}
[TV (14, 0), Mac (11, 0), iOS (14, 0)]
[MacCatalyst (14, 0)]
enum VNHumanBodyPoseObservationJointName {
@ -4251,6 +4289,25 @@ namespace Vision {
[NullAllowed, Export ("results", ArgumentSemantic.Copy)]
VNImageTranslationAlignmentObservation [] Results { get; }
[Export ("revision")]
VNTrackTranslationalImageRegistrationRequestRevision Revision { get; set; }
[Static]
[Export ("supportedRevisions", ArgumentSemantic.Copy)]
NSIndexSet WeakSupportedRevisions { get; }
[Static]
[Wrap ("GetSupportedVersions<VNTrackTranslationalImageRegistrationRequestRevision> (WeakSupportedRevisions)")]
VNTrackTranslationalImageRegistrationRequestRevision [] SupportedRevisions { get; }
[Static]
[Export ("defaultRevision")]
VNTrackTranslationalImageRegistrationRequestRevision DefaultRevision { get; }
[Static]
[Export ("currentRevision")]
VNTrackTranslationalImageRegistrationRequestRevision CurrentRevision { get; }
}
[TV (17, 0), Mac (14, 0), iOS (17, 0), MacCatalyst (17, 0)]
@ -4261,6 +4318,25 @@ namespace Vision {
[NullAllowed, Export ("results", ArgumentSemantic.Copy)]
VNImageHomographicAlignmentObservation [] Results { get; }
[Export ("revision")]
VNTrackHomographicImageRegistrationRequestRevision Revision { get; set; }
[Static]
[Export ("supportedRevisions", ArgumentSemantic.Copy)]
NSIndexSet WeakSupportedRevisions { get; }
[Static]
[Wrap ("GetSupportedVersions<VNTrackHomographicImageRegistrationRequestRevision> (WeakSupportedRevisions)")]
VNTrackHomographicImageRegistrationRequestRevision [] SupportedRevisions { get; }
[Static]
[Export ("defaultRevision")]
VNTrackHomographicImageRegistrationRequestRevision DefaultRevision { get; }
[Static]
[Export ("currentRevision")]
VNTrackHomographicImageRegistrationRequestRevision CurrentRevision { get; }
}
[TV (17, 0), Mac (14, 0), iOS (17, 0), MacCatalyst (17, 0)]
@ -4322,6 +4398,25 @@ namespace Vision {
[NullAllowed, Export ("results", ArgumentSemantic.Copy)]
VNHumanBodyPose3DObservation [] Results { get; }
[Export ("revision")]
VNDetectHumanBodyPose3DRequestRevision Revision { get; set; }
[Static]
[Export ("supportedRevisions", ArgumentSemantic.Copy)]
NSIndexSet WeakSupportedRevisions { get; }
[Static]
[Wrap ("GetSupportedVersions<VNDetectHumanBodyPose3DRequestRevision> (WeakSupportedRevisions)")]
VNDetectHumanBodyPose3DRequestRevision [] SupportedRevisions { get; }
[Static]
[Export ("defaultRevision")]
VNDetectHumanBodyPose3DRequestRevision DefaultRevision { get; }
[Static]
[Export ("currentRevision")]
VNDetectHumanBodyPose3DRequestRevision CurrentRevision { get; }
}
[TV (17, 0), Mac (14, 0), iOS (17, 0), MacCatalyst (17, 0)]
@ -4331,10 +4426,10 @@ namespace Vision {
[Export ("initWithPosition:")]
[MarshalDirective (NativePrefix = "xamarin_simd__", Library = "__Internal")]
[DesignatedInitializer]
NativeHandle Constructor (Vector4 position);
NativeHandle Constructor (Matrix4 position);
[Export ("position")]
Vector4 Position {
Matrix4 Position {
[MarshalDirective (NativePrefix = "xamarin_simd__", Library = "__Internal")]
get;
}
@ -4347,7 +4442,7 @@ namespace Vision {
[Export ("initWithPosition:")]
[MarshalDirective (NativePrefix = "xamarin_simd__", Library = "__Internal")]
[DesignatedInitializer]
NativeHandle Constructor (Vector4 position);
NativeHandle Constructor (Matrix4 position);
[Export ("identifier")]
string Identifier { get; }
@ -4382,10 +4477,10 @@ namespace Vision {
[Export ("initWithPosition:")]
[MarshalDirective (NativePrefix = "xamarin_simd__", Library = "__Internal")]
[DesignatedInitializer]
NativeHandle Constructor (Vector4 position);
NativeHandle Constructor (Matrix4 position);
[Export ("localPosition")]
Vector4 LocalPosition {
Matrix4 LocalPosition {
[MarshalDirective (NativePrefix = "xamarin_simd__", Library = "__Internal")]
get;
}
@ -4425,7 +4520,7 @@ namespace Vision {
VNHumanBodyPose3DObservationHeightEstimation HeightEstimation { get; }
[Export ("cameraOriginMatrix")]
Vector4 CameraOriginMatrix {
Matrix4 CameraOriginMatrix {
[MarshalDirective (NativePrefix = "xamarin_simd__", Library = "__Internal")]
get;
}
@ -4457,6 +4552,10 @@ namespace Vision {
[return: NullAllowed]
[return: BindAs (typeof (VNHumanBodyPose3DObservationJointName))]
NSString GetParentJointName ([BindAs (typeof (VNHumanBodyPose3DObservationJointName))] NSString jointName);
[Export ("getCameraRelativePosition:forJointName:error:")]
// MarshalDirective not needed bc Matrix4 param is passed by reference as opposed to by value as typically done
bool GetCameraRelativePosition (out Matrix4 modelPositionOut, [BindAs (typeof (VNHumanBodyPose3DObservationJointName))] NSString jointName, [NullAllowed] out NSError error);
}
[TV (17, 0), Mac (14, 0), iOS (17, 0), MacCatalyst (17, 0)]

Двоичные данные
tests/monotouch-test/Resources/full_body.jpg Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 135 KiB

Просмотреть файл

@ -0,0 +1,87 @@
// Unit test for Vision.GetCameraRelativePosition
#if !__WATCHOS__
#if MONOMAC
using AppKit;
#else
using UIKit;
#endif
using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using NUnit.Framework;
using CoreGraphics;
using ImageIO;
using Foundation;
using Vision;
using SceneKit;
#if NET
using System.Numerics;
using Vector2 = global::System.Numerics.Vector2;
using Vector3 = global::System.Numerics.Vector3;
using Matrix3 = global::CoreGraphics.NMatrix3;
using Matrix4 = global::CoreGraphics.NMatrix4;
#else
using OpenTK;
using Vector2 = global::OpenTK.Vector2;
using Vector3 = global::OpenTK.Vector3;
using Matrix3 = global::OpenTK.NMatrix3;
using Matrix4 = global::OpenTK.NMatrix4;
#endif
namespace MonoTouchFixtures.Vision {
[TestFixture]
[Preserve (AllMembers = true)]
public class VNGetCameraRelativePositionTest {
[SetUp]
public void SetUp ()
{
TestRuntime.AssertNotSimulator ();
TestRuntime.AssertXcodeVersion (15, 0);
}
[Test]
public void GetCameraRelativePositionTest ()
{
var requestHandler = new VNImageRequestHandler (NSBundle.MainBundle.GetUrlForResource ("full_body", "jpg"), new NSDictionary ());
var request = new VNDetectHumanBodyPose3DRequest ();
var didPerform = requestHandler.Perform (new VNRequest [] { request }, out NSError error);
Assert.Null (error, $"VNImageRequestHandler.Perform should not return an error {error}");
var observation = request.Results?.Length > 0 ? request.Results [0] : null;
Assert.NotNull (observation, "VNImageRequestHandler.Perform should return a result.");
Matrix4 expectedMatrix = new Matrix4 (
(float) -0.98357517, (float) 0.014054606, (float) -0.17995091, (float) 0.012865879,
(float) -0.1346774, (float) -0.7209123, (float) 0.67981434, (float) 0.9698789,
(float) -0.12017429, (float) 0.69288385, (float) 0.71096426, (float) 1.2595181,
(float) 0, (float) 0, (float) 0, (float) 1);
var position = observation.GetCameraRelativePosition (out var modelPositionOut, VNHumanBodyPose3DObservationJointName.CenterHead, out NSError observationError);
Assert.Null (observationError, $"GetCameraRelativePosition should not return an error {observationError}");
Assert.That (modelPositionOut, Is.EqualTo (expectedMatrix), "VNVector3DGetCameraRelativePosition result is not equal to expected matrix");
}
[Test]
public void KeepValueMethodsAliveTest ()
{
// When running the app with the --optimize:all property, the Value extension methods of
// the VNHumanBodyPose3DObservationJointName smart enum are linked away and results in a
// build failure.
// This is https://github.com/xamarin/xamarin-macios/issues/19712
// As a temp workaround, this test will ensure that the GetValue method is getting used
// to prevent the linker from removing this method.
var getValue = VNHumanBodyPose3DObservationJointNameExtensions.GetValue ((NSString) "CenterHead");
Assert.NotNull (getValue, "VNHumanBodyPose3DObservationJointNameExtensions.GetValue should not return null");
}
}
}
#endif

Просмотреть файл

@ -181,6 +181,9 @@
<BundleResource Include="$(MonoTouchTestDirectory)\Resources\square.gif">
<Link>Resources\square.gif</Link>
</BundleResource>
<BundleResource Include="$(MonoTouchTestDirectory)\Resources\full_body.jpg">
<Link>Resources\full_body.jpg</Link>
</BundleResource>
</ItemGroup>
<ItemGroup>
<Metal Include="$(MonoTouchTestDirectory)\Resources\metal-sample.metal" Condition="'$(_SdkIsSimulator)' != 'true'">

Просмотреть файл

@ -296,6 +296,7 @@
<BundleResource Include="compressed_zip" />
<BundleResource Include="example.pac" />
<BundleResource Include="Resources\square.gif" />
<BundleResource Include="Resources\full_body.jpg" />
</ItemGroup>
<ItemGroup>
<Metal Include="Resources\metal-sample.metal" Condition="'$(Platform)' != 'iPhoneSimulator' " />

Просмотреть файл

@ -213,6 +213,9 @@
<Content Include="..\monotouch-test\Resources\square.gif">
<Link>Resources\square.gif</Link>
</Content>
<Content Include="..\monotouch-test\Resources\full_body.jpg">
<Link>Resources\full_body.jpg</Link>
</Content>
</ItemGroup>
<ItemGroup>
<Metal Include="..\monotouch-test\Resources\metal-sample.metal">

Просмотреть файл

@ -43,6 +43,10 @@
!unknown-native-enum! VNStatefulRequestRevision bound
!unknown-native-enum! VNDetectDocumentSegmentationRequestRevision bound
!unknown-native-enum! VNGeneratePersonSegmentationRequestRevision bound
!unknown-native-enum! VNDetectHumanBodyPose3DRequestRevision bound
!unknown-native-enum! VNTrackHomographicImageRegistrationRequestRevision bound
!unknown-native-enum! VNTrackOpticalFlowRequestRevision bound
!unknown-native-enum! VNTrackTranslationalImageRegistrationRequestRevision bound
## VNRequest is an abstract class so this will be bound in subclasses
## matching the return type to the above defined custom enums
@ -54,6 +58,8 @@
## init is available but it's abstract (type) and not a designated initializer (so we don't bind it)
!missing-selector! VNRequest::init not bound
# API requires new marshal directive which needs to be manually tested (ideally via sample)
!missing-selector! VNHumanBodyPose3DObservation::getCameraRelativePosition:forJointName:error: not bound
# Xcode 15
# Since the parameter is passed by reference rather than value, the marshal directive is not necessary
# validated by VisionAnalyzer sample: https://github.com/haritha-mohan/vision-analyzer
!wrong-simd-missing-marshaldirective! System.Boolean Vision.VNHumanBodyPose3DObservation::GetCameraRelativePosition(CoreGraphics.NMatrix4&,Vision.VNHumanBodyPose3DObservationJointName,Foundation.NSError&): simd type: simd_float4x4

Просмотреть файл

@ -43,6 +43,10 @@
!unknown-native-enum! VNStatefulRequestRevision bound
!unknown-native-enum! VNDetectDocumentSegmentationRequestRevision bound
!unknown-native-enum! VNGeneratePersonSegmentationRequestRevision bound
!unknown-native-enum! VNDetectHumanBodyPose3DRequestRevision bound
!unknown-native-enum! VNTrackHomographicImageRegistrationRequestRevision bound
!unknown-native-enum! VNTrackOpticalFlowRequestRevision bound
!unknown-native-enum! VNTrackTranslationalImageRegistrationRequestRevision bound
## VNRequest is an abstract class so this will be bound in subclasses
## matching the return type to the above defined custom enums
@ -54,12 +58,8 @@
## init is available but it's abstract (type) and not a designated initializer (so we don't bind it)
!missing-selector! VNRequest::init not bound
# Not really needed anymore, this old(?) unbound APIs got replaced
# API introduced and deprecated at the same time in Xcode 12
# Existing enums with name changes relevant only to Swift
# API requires new marshal directive which needs to be manually tested (ideally via sample)
!missing-selector! VNHumanBodyPose3DObservation::getCameraRelativePosition:forJointName:error: not bound
# Xcode 15
# Since the parameter is passed by reference rather than value, the marshal directive is not necessary
# validated by VisionAnalyzer sample: https://github.com/haritha-mohan/vision-analyzer
!wrong-simd-missing-marshaldirective! System.Boolean Vision.VNHumanBodyPose3DObservation::GetCameraRelativePosition(OpenTK.NMatrix4&,Vision.VNHumanBodyPose3DObservationJointName,Foundation.NSError&): simd type: simd_float4x4