using System; using System.Collections.Generic; namespace MMDeploy { /// /// Box. /// public struct TextBox { /// /// P1. /// public Pointf P1; /// /// P2. /// public Pointf P2; /// /// P3. /// public Pointf P3; /// /// P4. /// public Pointf P4; /// /// Get reference Pi. /// /// ith point. /// Pi reference. public Pointf this[int i] { readonly get { return i switch { 0 => P1, 1 => P2, 2 => P3, 3 => P4, _ => throw new ArgumentOutOfRangeException(nameof(i)) }; } set { switch (i) { case 0: P1 = value; break; case 1: P2 = value; break; case 2: P3 = value; break; case 3: P4 = value; break; default: throw new ArgumentOutOfRangeException(nameof(i)); } } } } /// /// Single detection result of a picture. /// A picture may contains multiple reuslts. /// public struct TextDetect { /// /// Bounding box. /// public TextBox BBox; /// /// Score. /// public float Score; /// /// Initializes a new instance of the struct. /// /// score. /// bbox. public TextDetect(TextBox bbox, float score) { BBox = bbox; Score = score; } internal unsafe TextDetect(TextDetect* result) { Score = result->Score; BBox = default; for (int i = 0; i < 4; i++) { BBox[i] = result->BBox[i]; } } } /// /// Output of DetectorOutput. /// public struct TextDetectorOutput { /// /// Detection results for single image. /// public List Results; private void Init() { if (Results == null) { Results = new List(); } } /// /// Add result to single image. /// /// bbox. /// score. public void Add(TextBox bbox, float score) { Init(); Results.Add(new TextDetect(bbox, score)); } internal unsafe void Add(TextDetect* result) { Init(); Results.Add(new TextDetect(result)); } /// /// Gets number of output. /// public int Count { get { return (Results == null) ? 0 : Results.Count; } } } /// /// TextDetector. /// public class TextDetector : DisposableObject { /// /// Initializes a new instance of the class. /// /// model path. /// device name. /// device id. public TextDetector(string modelPath, string deviceName, int deviceId) { ThrowException(NativeMethods.mmdeploy_text_detector_create_by_path(modelPath, deviceName, deviceId, out _handle)); } /// /// Get information of each image in a batch. /// /// input mats. /// Results of each input mat. public List Apply(Mat[] mats) { List output = new List(); unsafe { TextDetect* results = null; int* resultCount = null; fixed (Mat* _mats = mats) { ThrowException(NativeMethods.mmdeploy_text_detector_apply(_handle, _mats, mats.Length, &results, &resultCount)); } FormatResult(mats.Length, resultCount, results, ref output, out var total); ReleaseResult(results, resultCount, total); } return output; } private unsafe void FormatResult(int matCount, int* resultCount, TextDetect* results, ref List output, out int total) { total = 0; for (int i = 0; i < matCount; i++) { TextDetectorOutput outi = default; for (int j = 0; j < resultCount[i]; j++) { outi.Add(results); results++; total++; } output.Add(outi); } } private unsafe void ReleaseResult(TextDetect* results, int* resultCount, int count) { NativeMethods.mmdeploy_text_detector_release_result(results, resultCount, count); } /// protected override void ReleaseHandle() { NativeMethods.mmdeploy_text_detector_destroy(_handle); } } }