ivsDrawer.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. import Drawer from './drawer.js';
  2. class IvsDrawer extends Drawer {
  3. constructor(canvas) {
  4. super(canvas);
  5. this.confidence = 200; //关键点最低置信度
  6. this.displayNum = 7; //大于等于该值时才绘制姿态
  7. }
  8. _init() {
  9. this.context.textAlign = 'left';
  10. this.context.textBaseline = 'bottom';
  11. }
  12. draw(data, time) {
  13. this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
  14. let rect = null,
  15. length = 0,
  16. undrawPoints = [],
  17. bodyLineWidth = 0,
  18. confidencePoint = [];
  19. let bodyCount = 0,
  20. speedBodyCount = 0;
  21. data.map((content, k) => {
  22. let {
  23. points,
  24. boundingBox,
  25. handsUp,
  26. boxConfidence,
  27. Loiter,
  28. Standing,
  29. Alone,
  30. guides,
  31. speed,
  32. overSpeed,
  33. id
  34. } = content;
  35. switch (content.type) {
  36. case 'rect':
  37. this.context.beginPath();
  38. this.context.strokeStyle = '#00ff00';
  39. this.context.fillStyle = '#00ff00';
  40. this.context.lineWidth = 1;//线条的宽度
  41. this.context.font = 'bold 20px Arial';
  42. if (!content.quality) {
  43. this.context.strokeStyle = '#ff0000';
  44. }
  45. rect = this._toRealCoordinate(content.rect[0], content.rect[1]);
  46. rect.push.apply(rect, this._toRealCoordinate(content.rect[2], content.rect[3]));
  47. this._drawRect(rect);
  48. //this.context.font = 'bold 20px Arial';
  49. //this.context.fillStyle = '#00ff00';
  50. // this._drawText(content.id, rect[0], rect[1]);
  51. // this._drawText(content.id, rect[0], rect[1]);
  52. // if (content.text) {
  53. // this._drawText(content.text, rect[0], rect[1] - 20);
  54. // }
  55. if (content.text !== undefined) {
  56. this._drawText(content.text, rect[0], rect[1] - 5);
  57. }
  58. //console.log('绘制 ', time)
  59. this.context.stroke();
  60. this.context.closePath();
  61. break;
  62. case 'text':
  63. break;
  64. case 'coco-pose':
  65. length = points.length;
  66. undrawPoints = [];
  67. bodyLineWidth = boundingBox[2] > 2048 ? 6 : ( boundingBox[2] > 512 ? 4 : 2);
  68. //过滤掉置信点不够的情况
  69. confidencePoint = points.filter((point) => {
  70. return point.confidence > this.confidence;
  71. });
  72. if (confidencePoint.length >= this.displayNum) {
  73. this.context.lineWidth = bodyLineWidth;
  74. //绘制实线
  75. for (let i = 0; i < length; i++) {
  76. if (undrawPoints.includes(i) || points[i].parent === -1) {
  77. continue;
  78. }
  79. let point = this._toRealCoordinate(points[i].x, points[i].y);
  80. let parentNode = points[points[i].parent];
  81. let parentPoint = this._toRealCoordinate(parentNode.x, parentNode.y);
  82. this.context.strokeStyle = handsUp ? '#ff0000' : points[i].pointColor;
  83. //confidence高于阈值时画实线,否则透明度降低
  84. if ((points[i].confidence <= this.confidence) || (parentNode.confidence <= this.confidence)) {
  85. this.context.globalAlpha = 0.3;
  86. }
  87. this.context.beginPath();
  88. this.context.moveTo(point[0], point[1]);
  89. this.context.lineTo(parentPoint[0], parentPoint[1]);
  90. this.context.stroke();
  91. this.context.globalAlpha = 1;
  92. this.context.closePath();
  93. }
  94. //绘制圆
  95. for (let i = 0; i < length; i++) {
  96. if (undrawPoints.includes(i)) {
  97. continue;
  98. }
  99. this.context.fillStyle = handsUp ? '#ffff00' : points[i].pointColor;
  100. //if ((points[i].parent !== -1 && points[i].confidence > this.confidence && points[points[i].parent].confidence > this.confidence)
  101. // || (points[i].parent === -1 && points[i].confidence > this.confidence)) {
  102. let point = this._toRealCoordinate(points[i].x, points[i].y);
  103. this.context.beginPath();
  104. this._drawArc(point[0], point[1], bodyLineWidth);
  105. this.context.fill();
  106. this.context.closePath();
  107. //}
  108. }
  109. } else {
  110. //console.log('only', confidencePoint.length, ' points');
  111. }
  112. //绘制人体框
  113. if (boxConfidence >= 0) {
  114. this.context.beginPath();
  115. this.context.lineWidth = 1;//线条的宽度
  116. this.context.strokeStyle = handsUp ? '#ff0000': '#0000ff';
  117. this.context.fillStyle = '#ffff00';
  118. this.context.font = 'bold 20px Arial';
  119. rect = this._toRealCoordinate(boundingBox[0], boundingBox[1]);
  120. rect.push.apply(rect, this._toRealCoordinate(boundingBox[2], boundingBox[3]));
  121. this._drawRect(rect);
  122. this._drawText(content.id, rect[0], rect[1] - 10);
  123. this.context.stroke();
  124. this.context.closePath();
  125. }
  126. break;
  127. case 'region-detect':
  128. let {state, area} = content;
  129. this.context.lineWidth = 2;
  130. this.context.strokeStyle = (state === 1) ? '#ffff00' : '#ff0000';
  131. this.context.beginPath();
  132. let beginPoint = this._toRealCoordinate(area[0].x, area[0].y);
  133. this.context.moveTo(beginPoint[0], beginPoint[1]);
  134. for (let i = 1; i < area.length; i++) {
  135. let point = this._toRealCoordinate(area[i].x, area[i].y);
  136. this.context.lineTo(point[0], point[1]);
  137. }
  138. this.context.lineTo(beginPoint[0], beginPoint[1]);
  139. this.context.stroke();
  140. this.context.closePath();
  141. break;
  142. case 'coco-poseex':
  143. length = points.length;
  144. undrawPoints = [];
  145. bodyLineWidth = boundingBox[2] > 2048 ? 6 : ( boundingBox[2] > 512 ? 4 : 2);
  146. //过滤掉置信点不够的情况
  147. confidencePoint = points.filter((point) => {
  148. return point.confidence > this.confidence;
  149. });
  150. if (confidencePoint.length >= this.displayNum) {
  151. this.context.lineWidth = bodyLineWidth;
  152. //绘制实线
  153. for (let i = 0; i < length; i++) {
  154. if (undrawPoints.includes(i) || points[i].parent === -1) {
  155. continue;
  156. }
  157. let point = this._toRealCoordinate(points[i].x, points[i].y);
  158. let parentNode = points[points[i].parent];
  159. let parentPoint = this._toRealCoordinate(parentNode.x, parentNode.y);
  160. this.context.strokeStyle = handsUp ? '#ff0000' : points[i].pointColor;
  161. //confidence高于阈值时画实线,否则透明度降低
  162. if ((points[i].confidence <= this.confidence) || (parentNode.confidence <= this.confidence)) {
  163. this.context.globalAlpha = 0.3;
  164. }
  165. this.context.beginPath();
  166. this.context.moveTo(point[0], point[1]);
  167. this.context.lineTo(parentPoint[0], parentPoint[1]);
  168. this.context.stroke();
  169. this.context.globalAlpha = 1;
  170. this.context.closePath();
  171. }
  172. //绘制圆
  173. for (let i = 0; i < length; i++) {
  174. if (undrawPoints.includes(i)) {
  175. continue;
  176. }
  177. this.context.fillStyle = handsUp ? '#ffff00' : points[i].pointColor;
  178. //if ((points[i].parent !== -1 && points[i].confidence > this.confidence && points[points[i].parent].confidence > this.confidence)
  179. // || (points[i].parent === -1 && points[i].confidence > this.confidence)) {
  180. let point = this._toRealCoordinate(points[i].x, points[i].y);
  181. this.context.beginPath();
  182. this._drawArc(point[0], point[1], bodyLineWidth);
  183. this.context.fill();
  184. this.context.closePath();
  185. //}
  186. }
  187. } else {
  188. //console.log('only', confidencePoint.length, ' points');
  189. }
  190. //绘制人体框
  191. if (boxConfidence >= 0) {
  192. let strokeStyle = (Loiter === 2 || Standing || Alone) ? '#ff0000' : (Loiter ? '#EFB842' : '#0000ff');
  193. this.context.beginPath();
  194. this.context.lineWidth = 1;//线条的宽度
  195. this.context.strokeStyle = strokeStyle;
  196. this.context.fillStyle = '#ffff00';
  197. this.context.font = 'bold 20px Arial';
  198. rect = this._toRealCoordinate(boundingBox[0], boundingBox[1]);
  199. rect.push.apply(rect, this._toRealCoordinate(boundingBox[2], boundingBox[3]));
  200. this._drawRect(rect);
  201. this._drawText(content.id, rect[0], rect[1] - 10);
  202. this.context.stroke();
  203. this.context.closePath();
  204. }
  205. //绘制参考线
  206. if(guides) {
  207. this.context.strokeStyle = '#0000ff';
  208. let point0 = this._toRealCoordinate(guides[0].x, guides[0].y);
  209. let point1 = this._toRealCoordinate(guides[1].x, guides[1].y);
  210. this.context.beginPath();
  211. this.context.setLineDash([10]);
  212. this.context.moveTo(point0[0], point0[1]);
  213. this.context.lineTo(point1[0], point1[1]);
  214. this._drawText(content.id, point1[0], point1[1] - 10);
  215. this.context.stroke();
  216. this.context.setLineDash([]);
  217. this.context.closePath();
  218. }
  219. bodyCount++;
  220. break;
  221. case 'over-speed':
  222. this.context.beginPath();
  223. this.context.fillStyle = overSpeed ? '#ff0000' : '#ffff00';
  224. this.context.font = 'bold 16px Arial';
  225. if(overSpeed) {
  226. this._drawText(`ID: ${id} speed: ${(speed / 100).toFixed(2)} m/s PMD`, 10, speedBodyCount * 20 + 30);
  227. } else {
  228. this._drawText(`ID: ${id} speed: ${(speed / 100).toFixed(2)} m/s`, 10, speedBodyCount * 20 + 30);
  229. }
  230. this.context.stroke();
  231. this.context.closePath();
  232. speedBodyCount++;
  233. break;
  234. default:
  235. console.log('unknown ivs type: ', content.type);
  236. break;
  237. }
  238. });
  239. //人数统计
  240. if(bodyCount) {
  241. this.context.beginPath();
  242. this.context.fillStyle = '#ffff00';
  243. this._drawText('人数:' + bodyCount, this.canvas.width - 100, 100);
  244. this.context.closePath();
  245. }
  246. }
  247. _drawRect(rect) {
  248. //console.log(rect)
  249. this.context.rect(rect[0], rect[1], rect[2], rect[3]);
  250. }
  251. _drawText(text, x, y) {
  252. this.context.fillText(text, x, y);
  253. }
  254. _drawArc(x, y, r) {
  255. this.context.arc(x, y, r, 0, 360);
  256. }
  257. }
  258. function f() {
  259. }
  260. export default IvsDrawer;