mirror of
https://github.com/cosyneco/MediaPipe.NET.git
synced 2025-08-24 08:40:39 +08:00

* Begin refactor
Signed-off-by: Ayane Satomi <ayane@vignetteapp.org>
* Begin IntPtr sweeping changes
Signed-off-by: Ayane Satomi <ayane@vignetteapp.org>
* Implement StringPacket
Signed-off-by: Ayane Satomi <ayane@vignetteapp.org>
* Implement StringPacket
Signed-off-by: Ayane Satomi <ayane@vignetteapp.org>
* Remove factory class to prepare for strongly typed packets
Signed-off-by: Ayane Satomi <ayane@vignetteapp.org>
* Finish FloatVectorPacket
Signed-off-by: Ayane <ayane@vignetteapp.org>
* Finish Anchor3DVectorPacket and BoolPacket
Signed-off-by: Ayane <ayane@vignetteapp.org>
* Make SerializedProto actually IDisposable
Signed-off-by: Ayane <ayane@vignetteapp.org>
* Finish ClassificationListPacket
Signed-off-by: Ayane <ayane@vignetteapp.org>
* Finish ClassificationListVectorPacket
Signed-off-by: Ayane <ayane@vignetteapp.org>
* Finish DetectionPacket
Signed-off-by: Ayane <ayane@vignetteapp.org>
* Finish DetectionVectorPacket
Signed-off-by: Ayane <ayane@vignetteapp.org>
* Finish FaceGeometryPacket
Signed-off-by: Ayane <ayane@vignetteapp.org>
* Finish FaceGeometryVectorPacket
Signed-off-by: Ayane <ayane@vignetteapp.org>
* Finish FloatArrayPacket
Signed-off-by: Ayane <ayane@vignetteapp.org>
* Fix mismatched extern call for FloatVector
This is potentially lethal and can cause a really bad bug on use
Signed-off-by: Ayane <ayane@vignetteapp.org>
* Finish FloatPacket
Signed-off-by: Ayane <ayane@vignetteapp.org>
* Finish FrameAnnotationPacket
Signed-off-by: Ayane <ayane@vignetteapp.org>
* Finish GpuBufferPacket
Converting the entirety of the GPU PInvoke code was also performed, it was unavoidable
Signed-off-by: Ayane <ayane@vignetteapp.org>
* Update imageFrame
This is kind of butchered but we will have a span-based overload again when I feel like it
Signed-off-by: Ayane <ayane@vignetteapp.org>
* Reintroduce the memory safe iamge handling again
Signed-off-by: Ayane <ayane@vignetteapp.org>
* Porting ImageFrame is an act of god ong
Signed-off-by: Ayane <ayane@vignetteapp.org>
* Finish ImageFramePacket
Signed-off-by: Ayane <ayane@vignetteapp.org>
* Finish IntPacket
Signed-off-by: Ayane <ayane@vignetteapp.org>
* Fix pointer ambiguity in MpResourceHandle
Signed-off-by: Ayane Satomi <ayane@vignetteapp.org>
* Let MpResourceHandle use its private property handle
Signed-off-by: Ayane Satomi <ayane@vignetteapp.org>
* Finish LandmarkListPacket
Signed-off-by: Ayane <ayane@vignetteapp.org>
* Finish LandmarkListVectorPacket
Signed-off-by: Ayane <ayane@vignetteapp.org>
* Finish NoramlizedLandmarkListPacket
Signed-off-by: Ayane <ayane@vignetteapp.org>
* Finish MatrixPacket
Signed-off-by: Ayane <ayane@vignetteapp.org>
* Finish NormalizedRectPacket
Signed-off-by: Ayane <ayane@vignetteapp.org>
* Finish normalizedVectorRect
Signed-off-by: Ayane <ayane@vignetteapp.org>
* Finish RectPacket
Signed-off-by: Ayane <ayane@vignetteapp.org>
* Finsih RectVector
Signed-off-by: Ayane <ayane@vignetteapp.org>
* Finish all Packets
Signed-off-by: Ayane <ayane@vignetteapp.org>
* Fixup CalculatorGraph for generic Packet types
Signed-off-by: Ayane <ayane@vignetteapp.org>
* a
Signed-off-by: Ayane <ayane@vignetteapp.org>
* Deprecate Solutions class
As there is no maintainers for it, it doesn't seem worth keeping it for now. We will put it on it's own package instead
Signed-off-by: Ayane <ayane@vignetteapp.org>
* Forgot to commit this 💀
Signed-off-by: Ayane <ayane@vignetteapp.org>
* Fix more casting issues
Signed-off-by: Ayane <ayane@vignetteapp.org>
* Make sure native methods are marshaled properly
Signed-off-by: Ayane <ayane@vignetteapp.org>
* Update some tests
Signed-off-by: Ayane Satomi <ayane@vignetteapp.org>
* Add an even more memory safe ctor for ImageFrame
Signed-off-by: Ayane Satomi <ayane@vignetteapp.org>
* Fix tests lmao
Signed-off-by: Ayane Satomi <ayane@vignetteapp.org>
* Fix StringPacket not pointing to a ptr
Signed-off-by: Ayane Satomi <ayane@vignetteapp.org>
* Fix incorrect test facts provided on cases
Signed-off-by: Ayane Satomi <ayane@vignetteapp.org>
---------
Signed-off-by: Ayane Satomi <ayane@vignetteapp.org>
Signed-off-by: Ayane <ayane@vignetteapp.org>
234 lines
9.4 KiB
C#
234 lines
9.4 KiB
C#
// Copyright (c) homuler and The Vignette Authors
|
|
// This file is part of MediaPipe.NET.
|
|
// MediaPipe.NET is licensed under the MIT License. See LICENSE for details.
|
|
|
|
using System;
|
|
using System.Linq;
|
|
using System.Runtime.InteropServices;
|
|
using Mediapipe.Net.Core;
|
|
using Mediapipe.Net.Framework.Format;
|
|
using Mediapipe.Net.Framework.Protobuf;
|
|
using Mediapipe.Net.Tests;
|
|
using NUnit.Framework;
|
|
|
|
namespace Mediapipe.Tests
|
|
{
|
|
public class ImageFrameTest
|
|
{
|
|
#region Constructor
|
|
[Test]
|
|
public unsafe void Ctor_ShouldInstantiateImageFrame_When_CalledWithNoArguments()
|
|
{
|
|
using var imageFrame = new ImageFrame();
|
|
Assert.AreEqual(ImageFormat.Types.Format.Unknown, imageFrame.Format());
|
|
Assert.AreEqual(0, imageFrame.Width());
|
|
Assert.AreEqual(0, imageFrame.Height(), 0);
|
|
Assert.AreEqual(0, imageFrame.ChannelSize());
|
|
Assert.AreEqual(0, imageFrame.NumberOfChannels());
|
|
Assert.AreEqual(0, imageFrame.ByteDepth());
|
|
Assert.AreEqual(0, imageFrame.WidthStep());
|
|
Assert.AreEqual(0, imageFrame.PixelDataSize());
|
|
Assert.AreEqual(0, imageFrame.PixelDataSizeStoredContiguously());
|
|
Assert.True(imageFrame.IsEmpty());
|
|
Assert.False(imageFrame.IsContiguous());
|
|
Assert.False(imageFrame.IsAligned(16));
|
|
Assert.AreEqual(IntPtr.Zero, imageFrame.MutablePixelData());
|
|
}
|
|
|
|
[Test]
|
|
public unsafe void Ctor_ShouldInstantiateImageFrame_When_CalledWithFormat()
|
|
{
|
|
using var imageFrame = new ImageFrame(ImageFormat.Types.Format.Sbgra, 640, 480);
|
|
Assert.AreEqual(ImageFormat.Types.Format.Sbgra, imageFrame.Format());
|
|
Assert.AreEqual(640, imageFrame.Width());
|
|
Assert.AreEqual(480, imageFrame.Height());
|
|
Assert.AreEqual(1, imageFrame.ChannelSize());
|
|
Assert.AreEqual(4, imageFrame.NumberOfChannels());
|
|
Assert.AreEqual(1, imageFrame.ByteDepth());
|
|
Assert.AreEqual(640 * 4, imageFrame.WidthStep());
|
|
Assert.AreEqual(640 * 480 * 4, imageFrame.PixelDataSize());
|
|
Assert.AreEqual(640 * 480 * 4, imageFrame.PixelDataSizeStoredContiguously());
|
|
Assert.False(imageFrame.IsEmpty());
|
|
Assert.True(imageFrame.IsContiguous());
|
|
Assert.True(imageFrame.IsAligned(16));
|
|
Assert.AreNotEqual(IntPtr.Zero, imageFrame.MutablePixelData());
|
|
}
|
|
|
|
[Test]
|
|
public void Ctor_ShouldInstantiateImageFrame_When_CalledWithFormatAndAlignmentBoundary()
|
|
{
|
|
using var imageFrame = new ImageFrame(ImageFormat.Types.Format.Gray8, 100, 100, 8);
|
|
Assert.AreEqual(100, imageFrame.Width());
|
|
Assert.AreEqual(1, imageFrame.NumberOfChannels());
|
|
Assert.AreEqual(104, imageFrame.WidthStep());
|
|
}
|
|
|
|
[Test]
|
|
public void Ctor_ShouldInstantiateImageFrame_When_CalledWithPixelData()
|
|
{
|
|
// The original test for this used NativeArray which only exists in Unity
|
|
// To emulate this, we're using a byte array and pinning it to get a pointer
|
|
// Which is the least ideal way to do it since this is not memory-safe.
|
|
var pixelData = new byte[32];
|
|
var pixelDataPtr = GCHandle.Alloc(pixelData, GCHandleType.Pinned).AddrOfPinnedObject();
|
|
byte[] srcBytes = new byte[] {
|
|
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
|
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
|
};
|
|
|
|
using var imageFrame = new ImageFrame(ImageFormat.Types.Format.Sbgra, 4, 2, 16, pixelDataPtr);
|
|
Assert.AreEqual(4, imageFrame.Width());
|
|
Assert.AreEqual(2, imageFrame.Height());
|
|
Assert.False(imageFrame.IsEmpty());
|
|
|
|
byte[] bytes = new byte[32];
|
|
imageFrame.CopyToBuffer(bytes);
|
|
Assert.IsEmpty(bytes.Where((x, i) => x != srcBytes[i]));
|
|
|
|
// free handle since we don't need it anymore
|
|
GCHandle.FromIntPtr(pixelDataPtr).Free();
|
|
}
|
|
|
|
|
|
[Test, SignalAbort]
|
|
public void Ctor_ShouldThrowMediaPipeException_When_CalledWithInvalidArgument()
|
|
{
|
|
#pragma warning disable IDE0058
|
|
Assert.Throws<MediapipeException>(() => { new ImageFrame(ImageFormat.Types.Format.Sbgra, 640, 480, 0); });
|
|
#pragma warning restore IDE0058
|
|
}
|
|
#endregion
|
|
|
|
#region #isDisposed
|
|
[Test]
|
|
public void IsDisposed_ShouldReturnFalse_When_NotDisposedYet()
|
|
{
|
|
using ImageFrame imageFrame = new ImageFrame();
|
|
Assert.False(imageFrame.IsDisposed);
|
|
}
|
|
|
|
[Test]
|
|
public void IsDisposed_ShouldReturnTrue_When_AlreadyDisposed()
|
|
{
|
|
ImageFrame imageFrame = new ImageFrame();
|
|
imageFrame.Dispose();
|
|
|
|
Assert.True(imageFrame.IsDisposed);
|
|
}
|
|
#endregion
|
|
|
|
#region #SetToZero
|
|
[Test]
|
|
public void SetToZero_ShouldSetZeroToAllBytes()
|
|
{
|
|
using var imageFrame = new ImageFrame(ImageFormat.Types.Format.Gray8, 10, 10);
|
|
imageFrame.SetToZero();
|
|
var bytes = new byte[100];
|
|
imageFrame.CopyToBuffer(bytes);
|
|
Assert.True(bytes.All((x) => x == 0));
|
|
}
|
|
#endregion
|
|
|
|
#region #SetAlignmentPaddingAreas
|
|
[Test]
|
|
public void SetAlignmentPaddingAreas_ShouldNotThrow()
|
|
{
|
|
using var imageFrame = new ImageFrame(ImageFormat.Types.Format.Gray8, 10, 10, 16);
|
|
Assert.DoesNotThrow(() => { imageFrame.SetAlignmentPaddingAreas(); });
|
|
}
|
|
#endregion
|
|
|
|
#region CopyToBuffer
|
|
[Test, SignalAbort]
|
|
public void CopyToByteBuffer_ShouldThrowException_When_BufferDepthIsWrong()
|
|
{
|
|
using var imageFrame = new ImageFrame(ImageFormat.Types.Format.Gray16, 10, 10);
|
|
#pragma warning disable IDE0058
|
|
Assert.Throws<MediapipeException>(() => { imageFrame.CopyToBuffer(new byte[100]); });
|
|
#pragma warning restore IDE0058
|
|
}
|
|
|
|
[Test]
|
|
public void CopyToByteBuffer_ShouldReturnByteArray_When_BufferSizeIsLargeEnough()
|
|
{
|
|
using var imageFrame = new ImageFrame(ImageFormat.Types.Format.Gray8, 10, 10);
|
|
var normalBuffer = new byte[100];
|
|
var largeBuffer = new byte[120];
|
|
imageFrame.CopyToBuffer(normalBuffer);
|
|
imageFrame.CopyToBuffer(largeBuffer);
|
|
|
|
Assert.IsEmpty(normalBuffer.Where((x, i) => x != largeBuffer[i]));
|
|
}
|
|
|
|
[Test, SignalAbort]
|
|
public void CopyToByteBuffer_ShouldThrowException_When_BufferSizeIsTooSmall()
|
|
{
|
|
using var imageFrame = new ImageFrame(ImageFormat.Types.Format.Gray8, 10, 10);
|
|
#pragma warning disable IDE0058
|
|
Assert.Throws<MediapipeException>(() => { imageFrame.CopyToBuffer(new byte[99]); });
|
|
#pragma warning restore IDE0058
|
|
}
|
|
|
|
[Test, SignalAbort]
|
|
public void CopyToUshortBuffer_ShouldThrowException_When_BufferDepthIsWrong()
|
|
{
|
|
using var imageFrame = new ImageFrame(ImageFormat.Types.Format.Gray8, 10, 10);
|
|
#pragma warning disable IDE0058
|
|
Assert.Throws<MediapipeException>(() => { imageFrame.CopyToBuffer(new ushort[100]); });
|
|
#pragma warning restore IDE0058
|
|
}
|
|
|
|
[Test]
|
|
public void CopyToUshortBuffer_ShouldReturnUshortArray_When_BufferSizeIsLargeEnough()
|
|
{
|
|
using var imageFrame = new ImageFrame(ImageFormat.Types.Format.Gray16, 10, 10);
|
|
var normalBuffer = new ushort[100];
|
|
var largeBuffer = new ushort[120];
|
|
imageFrame.CopyToBuffer(normalBuffer);
|
|
imageFrame.CopyToBuffer(largeBuffer);
|
|
|
|
Assert.IsEmpty(normalBuffer.Where((x, i) => x != largeBuffer[i]));
|
|
}
|
|
|
|
[Test, SignalAbort]
|
|
public void CopyToUshortBuffer_ShouldThrowException_When_BufferSizeIsTooSmall()
|
|
{
|
|
using var imageFrame = new ImageFrame(ImageFormat.Types.Format.Gray16, 10, 10);
|
|
#pragma warning disable IDE0058
|
|
Assert.Throws<MediapipeException>(() => { imageFrame.CopyToBuffer(new ushort[99]); });
|
|
#pragma warning restore IDE0058
|
|
}
|
|
|
|
[Test, SignalAbort]
|
|
public void CopyToFloatBuffer_ShouldThrowException_When_BufferDepthIsWrong()
|
|
{
|
|
using var imageFrame = new ImageFrame(ImageFormat.Types.Format.Gray8, 10, 10);
|
|
#pragma warning disable IDE0058
|
|
Assert.Throws<MediapipeException>(() => { imageFrame.CopyToBuffer(new float[100]); });
|
|
#pragma warning restore IDE0058
|
|
}
|
|
|
|
[Test]
|
|
public void CopyToFloatBuffer_ShouldReturnFloatArray_When_BufferSizeIsLargeEnough()
|
|
{
|
|
using var imageFrame = new ImageFrame(ImageFormat.Types.Format.Vec32F1, 10, 10);
|
|
var normalBuffer = new float[100];
|
|
var largeBuffer = new float[120];
|
|
imageFrame.CopyToBuffer(normalBuffer);
|
|
imageFrame.CopyToBuffer(largeBuffer);
|
|
|
|
Assert.IsEmpty(normalBuffer.Where((x, i) => Math.Abs(x - largeBuffer[i]) > 1e-9));
|
|
}
|
|
|
|
[Test, SignalAbort]
|
|
public void CopyToFloatBuffer_ShouldThrowException_When_BufferSizeIsTooSmall()
|
|
{
|
|
using var imageFrame = new ImageFrame(ImageFormat.Types.Format.Vec32F1, 10, 10);
|
|
#pragma warning disable IDE0058
|
|
Assert.Throws<MediapipeException>(() => { imageFrame.CopyToBuffer(new float[99]); });
|
|
#pragma warning restore IDE0058
|
|
}
|
|
}
|
|
#endregion
|
|
}
|