Editor/Inference/DinoShape.cs
using System;
namespace HumanoidMocapX.Inference;
/// <summary>Dimensions for the two DINO image encoders used by camera and body inference.</summary>
internal readonly record struct DinoShape
{
internal const int PatchSize = 16, PrefixTokens = 5;
internal int Height { get; }
internal int Width { get; }
internal int Channels { get; }
internal int Heads { get; }
internal bool IsSam { get; }
internal int Depth => IsSam ? 32 : 24;
internal string Name => IsSam ? "backbone.encoder" : "aggregator.patch_embed";
internal int Patches => Height / PatchSize * (Width / PatchSize);
internal int Tokens => Patches + PrefixTokens;
internal int ImageElements => Height * Width * 3;
DinoShape(int height, int width, int channels, int heads, bool isSam)
{
if (height < PatchSize || width < PatchSize || height > 512 || width > 512
|| height % PatchSize != 0 || width % PatchSize != 0 || channels < 4 || channels > 1280
|| heads < 1 || channels % heads != 0 || channels / heads % 4 != 0)
throw new ArgumentException("DINO needs patch-aligned images up to 512 pixels and heads divisible by four.");
Height = height; Width = width; Channels = channels; Heads = heads; IsSam = isSam;
}
internal static DinoShape Omega(OmegaShape shape) => new(shape.Height, shape.Width, shape.Channels, shape.Heads, false);
internal static DinoShape Sam(int height = 512, int width = 512, int channels = 1280, int heads = 20)
=> new(height, width, channels, heads, true);
}