App.cs 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. using Edge.Core.Processor;
  2. using Edge.Core.Processor.Dispatcher.Attributes;
  3. using Edge.Core.UniversalApi;
  4. using Microsoft.Extensions.DependencyInjection;
  5. using System;
  6. using System.Collections.Generic;
  7. using System.Linq;
  8. using System.Threading;
  9. using System.Threading.Tasks;
  10. namespace AreaIntrudeDetecterServer
  11. {
  12. [MetaPartsDescriptor(
  13. "lang-zh-cn:区域闯入检测lang-zh-tw:區域闖入檢測lang-en-us:Area intrude detecter",
  14. "lang-zh-cn:接收某区域的闯入行为,此程序作为服务器(接收端)需要与检测客户端配合使用(如基于视频流分析的jetson inference framework)" +
  15. "lang-en-us:接收某区域的闯入行为,此程序作为服务器(接收端)需要与检测客户端配合使用(如基于视频流分析的jetson inference framework)",
  16. new[] { "lang-zh-cn:摄像头lang-en-us:Cameralang-zh-tw:攝像頭" })]
  17. public class App : IAppProcessor
  18. {
  19. private IServiceProvider services;
  20. public string MetaConfigName { get; set; }
  21. public class Area
  22. {
  23. public string Name { get; set; }
  24. public int BndBox_LeftTop_X { get; set; }
  25. public int BndBox_RightBottom_X { get; set; }
  26. public int BndBox_LeftTop_Y { get; set; }
  27. public int BndBox_RightBottom_Y { get; set; }
  28. }
  29. /// <summary>
  30. /// basically info can refer https://rawgit.com/dusty-nv/jetson-inference/python/docs/html/python/jetson.inference.html#detectNet
  31. /// </summary>
  32. public class Detection
  33. {
  34. public string AreaName { get; set; }
  35. public int? ClassID { get; set; }
  36. public string ClassName { get; set; }
  37. public double Confidence { get; set; }
  38. public int? Height { get; set; }
  39. public int? Width { get; set; }
  40. }
  41. private Timer timelyFireGenericAlarmTimer;
  42. private int busy = 0;
  43. private List<Detection> cache = new List<Detection>();
  44. public App(int appConfig, IServiceProvider services)
  45. {
  46. this.services = services;
  47. this.timelyFireGenericAlarmTimer = new Timer(async (o) =>
  48. {
  49. if (0 != Interlocked.CompareExchange(ref this.busy, 1, 0))
  50. return;
  51. try
  52. {
  53. var groupByAreaName = cache.GroupBy(d => new { d.AreaName, d.ClassName });
  54. var universalApiHub = this.services.GetRequiredService<UniversalApiHub>();
  55. foreach (var g in groupByAreaName)
  56. {
  57. foreach (var ig in g)
  58. {
  59. await universalApiHub.ClearAndFirePersistGenericAlarm(this,
  60. new GenericAlarm()
  61. {
  62. Category = $"区域闯入检测",
  63. Title = $"{this.GetFriendlyAreaName(g.Key.AreaName)} - {this.GetFriendlyClassName(ig.ClassName)}闯入",
  64. Detail = $"系统有{(Math.Round(ig.Confidence, 2) * 100).ToString().Substring(0, 2)}%的确信度认为有{ig.ClassName} (ClassId: {ig.ClassID})闯入至区域: {this.GetFriendlyAreaName(g.Key.AreaName)}",
  65. Severity = GenericAlarmSeverity.Warning
  66. }, g => g.Title, g => g.Title);
  67. }
  68. }
  69. this.cache.Clear();
  70. }
  71. finally
  72. {
  73. this.busy = 0;
  74. }
  75. }, null, 0, 1500);
  76. }
  77. int maxWaitTimes = 20;
  78. [UniversalApi]
  79. public async Task<bool> Report(IEnumerable<Detection> input)
  80. {
  81. Console.WriteLine(input.Select(d => $"Detect in area: {d.AreaName} has object: {d.ClassName} with conf: {d.Confidence}").Aggregate((acc, n) => acc + " | " + n));
  82. int waitTimes = 0;
  83. while (0 != Interlocked.CompareExchange(ref this.busy, 1, 0))
  84. {
  85. Thread.Sleep(50);
  86. waitTimes++;
  87. if (waitTimes > maxWaitTimes)
  88. return false;
  89. }
  90. try
  91. {
  92. this.cache.AddRange(input);
  93. }
  94. finally { this.busy = 0; }
  95. return true;
  96. }
  97. private string GetFriendlyAreaName(string rawName)
  98. {
  99. switch (rawName.ToLower())
  100. {
  101. case "indoor0": return "消防通道A";
  102. case "indoor1": return "消防通道B";
  103. case "indoor2": return "消防通道C";
  104. case "indoor3": return "消防通道D";
  105. case "indoor4": return "消防通道E";
  106. case "outdoor0": return "卸油区通道A";
  107. case "outdoor1": return "卸油区通道B";
  108. case "outdoor2": return "油罐区通道A";
  109. case "outdoor3": return "油罐区通道B";
  110. case "outdoor4": return "油罐区通道C";
  111. default: return rawName;
  112. }
  113. }
  114. private string GetFriendlyClassName(string rawName)
  115. {
  116. switch (rawName.ToLower())
  117. {
  118. case "person": return "人员";
  119. case "chair": return "座椅";
  120. case "bird": return "鸟类";
  121. case "truck": return "卡车";
  122. case "car": return "小汽车";
  123. default: return rawName;
  124. }
  125. }
  126. private List<Area> savedAreas = new List<Area>();
  127. [UniversalApi]
  128. public async Task<bool> SaveAreas(IEnumerable<Area> input)
  129. {
  130. this.savedAreas.AddRange(input);
  131. return true;
  132. }
  133. [UniversalApi]
  134. public async Task<IEnumerable<Area>> GetAreas()
  135. {
  136. return this.savedAreas;
  137. }
  138. [UniversalApi]
  139. public async Task<bool> ClearAreas()
  140. {
  141. this.savedAreas.Clear();
  142. return true;
  143. }
  144. public void Init(IEnumerable<IProcessor> processors)
  145. {
  146. //throw new NotImplementedException();
  147. }
  148. }
  149. }