import Drawer from './drawer.js'; class IvsDrawer extends Drawer { constructor(canvas) { super(canvas); this.confidence = 200; //关键点最低置信度 this.displayNum = 7; //大于等于该值时才绘制姿态 } _init() { this.context.textAlign = 'left'; this.context.textBaseline = 'bottom'; } draw(data, time) { this.context.clearRect(0, 0, this.canvas.width, this.canvas.height); let rect = null, length = 0, undrawPoints = [], bodyLineWidth = 0, confidencePoint = []; let bodyCount = 0, speedBodyCount = 0; data.map((content, k) => { let { points, boundingBox, handsUp, boxConfidence, Loiter, Standing, Alone, guides, speed, overSpeed, id } = content; switch (content.type) { case 'rect': this.context.beginPath(); this.context.strokeStyle = '#00ff00'; this.context.fillStyle = '#00ff00'; this.context.lineWidth = 1;//线条的宽度 this.context.font = 'bold 20px Arial'; if (!content.quality) { this.context.strokeStyle = '#ff0000'; } rect = this._toRealCoordinate(content.rect[0], content.rect[1]); rect.push.apply(rect, this._toRealCoordinate(content.rect[2], content.rect[3])); this._drawRect(rect); //this.context.font = 'bold 20px Arial'; //this.context.fillStyle = '#00ff00'; // this._drawText(content.id, rect[0], rect[1]); // this._drawText(content.id, rect[0], rect[1]); // if (content.text) { // this._drawText(content.text, rect[0], rect[1] - 20); // } if (content.text !== undefined) { this._drawText(content.text, rect[0], rect[1] - 5); } //console.log('绘制 ', time) this.context.stroke(); this.context.closePath(); break; case 'text': break; case 'coco-pose': length = points.length; undrawPoints = []; bodyLineWidth = boundingBox[2] > 2048 ? 6 : ( boundingBox[2] > 512 ? 4 : 2); //过滤掉置信点不够的情况 confidencePoint = points.filter((point) => { return point.confidence > this.confidence; }); if (confidencePoint.length >= this.displayNum) { this.context.lineWidth = bodyLineWidth; //绘制实线 for (let i = 0; i < length; i++) { if (undrawPoints.includes(i) || points[i].parent === -1) { continue; } let point = this._toRealCoordinate(points[i].x, points[i].y); let parentNode = points[points[i].parent]; let parentPoint = this._toRealCoordinate(parentNode.x, parentNode.y); this.context.strokeStyle = handsUp ? '#ff0000' : points[i].pointColor; //confidence高于阈值时画实线,否则透明度降低 if ((points[i].confidence <= this.confidence) || (parentNode.confidence <= this.confidence)) { this.context.globalAlpha = 0.3; } this.context.beginPath(); this.context.moveTo(point[0], point[1]); this.context.lineTo(parentPoint[0], parentPoint[1]); this.context.stroke(); this.context.globalAlpha = 1; this.context.closePath(); } //绘制圆 for (let i = 0; i < length; i++) { if (undrawPoints.includes(i)) { continue; } this.context.fillStyle = handsUp ? '#ffff00' : points[i].pointColor; //if ((points[i].parent !== -1 && points[i].confidence > this.confidence && points[points[i].parent].confidence > this.confidence) // || (points[i].parent === -1 && points[i].confidence > this.confidence)) { let point = this._toRealCoordinate(points[i].x, points[i].y); this.context.beginPath(); this._drawArc(point[0], point[1], bodyLineWidth); this.context.fill(); this.context.closePath(); //} } } else { //console.log('only', confidencePoint.length, ' points'); } //绘制人体框 if (boxConfidence >= 0) { this.context.beginPath(); this.context.lineWidth = 1;//线条的宽度 this.context.strokeStyle = handsUp ? '#ff0000': '#0000ff'; this.context.fillStyle = '#ffff00'; this.context.font = 'bold 20px Arial'; rect = this._toRealCoordinate(boundingBox[0], boundingBox[1]); rect.push.apply(rect, this._toRealCoordinate(boundingBox[2], boundingBox[3])); this._drawRect(rect); this._drawText(content.id, rect[0], rect[1] - 10); this.context.stroke(); this.context.closePath(); } break; case 'region-detect': let {state, area} = content; this.context.lineWidth = 2; this.context.strokeStyle = (state === 1) ? '#ffff00' : '#ff0000'; this.context.beginPath(); let beginPoint = this._toRealCoordinate(area[0].x, area[0].y); this.context.moveTo(beginPoint[0], beginPoint[1]); for (let i = 1; i < area.length; i++) { let point = this._toRealCoordinate(area[i].x, area[i].y); this.context.lineTo(point[0], point[1]); } this.context.lineTo(beginPoint[0], beginPoint[1]); this.context.stroke(); this.context.closePath(); break; case 'coco-poseex': length = points.length; undrawPoints = []; bodyLineWidth = boundingBox[2] > 2048 ? 6 : ( boundingBox[2] > 512 ? 4 : 2); //过滤掉置信点不够的情况 confidencePoint = points.filter((point) => { return point.confidence > this.confidence; }); if (confidencePoint.length >= this.displayNum) { this.context.lineWidth = bodyLineWidth; //绘制实线 for (let i = 0; i < length; i++) { if (undrawPoints.includes(i) || points[i].parent === -1) { continue; } let point = this._toRealCoordinate(points[i].x, points[i].y); let parentNode = points[points[i].parent]; let parentPoint = this._toRealCoordinate(parentNode.x, parentNode.y); this.context.strokeStyle = handsUp ? '#ff0000' : points[i].pointColor; //confidence高于阈值时画实线,否则透明度降低 if ((points[i].confidence <= this.confidence) || (parentNode.confidence <= this.confidence)) { this.context.globalAlpha = 0.3; } this.context.beginPath(); this.context.moveTo(point[0], point[1]); this.context.lineTo(parentPoint[0], parentPoint[1]); this.context.stroke(); this.context.globalAlpha = 1; this.context.closePath(); } //绘制圆 for (let i = 0; i < length; i++) { if (undrawPoints.includes(i)) { continue; } this.context.fillStyle = handsUp ? '#ffff00' : points[i].pointColor; //if ((points[i].parent !== -1 && points[i].confidence > this.confidence && points[points[i].parent].confidence > this.confidence) // || (points[i].parent === -1 && points[i].confidence > this.confidence)) { let point = this._toRealCoordinate(points[i].x, points[i].y); this.context.beginPath(); this._drawArc(point[0], point[1], bodyLineWidth); this.context.fill(); this.context.closePath(); //} } } else { //console.log('only', confidencePoint.length, ' points'); } //绘制人体框 if (boxConfidence >= 0) { let strokeStyle = (Loiter === 2 || Standing || Alone) ? '#ff0000' : (Loiter ? '#EFB842' : '#0000ff'); this.context.beginPath(); this.context.lineWidth = 1;//线条的宽度 this.context.strokeStyle = strokeStyle; this.context.fillStyle = '#ffff00'; this.context.font = 'bold 20px Arial'; rect = this._toRealCoordinate(boundingBox[0], boundingBox[1]); rect.push.apply(rect, this._toRealCoordinate(boundingBox[2], boundingBox[3])); this._drawRect(rect); this._drawText(content.id, rect[0], rect[1] - 10); this.context.stroke(); this.context.closePath(); } //绘制参考线 if(guides) { this.context.strokeStyle = '#0000ff'; let point0 = this._toRealCoordinate(guides[0].x, guides[0].y); let point1 = this._toRealCoordinate(guides[1].x, guides[1].y); this.context.beginPath(); this.context.setLineDash([10]); this.context.moveTo(point0[0], point0[1]); this.context.lineTo(point1[0], point1[1]); this._drawText(content.id, point1[0], point1[1] - 10); this.context.stroke(); this.context.setLineDash([]); this.context.closePath(); } bodyCount++; break; case 'over-speed': this.context.beginPath(); this.context.fillStyle = overSpeed ? '#ff0000' : '#ffff00'; this.context.font = 'bold 16px Arial'; if(overSpeed) { this._drawText(`ID: ${id} speed: ${(speed / 100).toFixed(2)} m/s PMD`, 10, speedBodyCount * 20 + 30); } else { this._drawText(`ID: ${id} speed: ${(speed / 100).toFixed(2)} m/s`, 10, speedBodyCount * 20 + 30); } this.context.stroke(); this.context.closePath(); speedBodyCount++; break; default: console.log('unknown ivs type: ', content.type); break; } }); //人数统计 if(bodyCount) { this.context.beginPath(); this.context.fillStyle = '#ffff00'; this._drawText('人数:' + bodyCount, this.canvas.width - 100, 100); this.context.closePath(); } } _drawRect(rect) { //console.log(rect) this.context.rect(rect[0], rect[1], rect[2], rect[3]); } _drawText(text, x, y) { this.context.fillText(text, x, y); } _drawArc(x, y, r) { this.context.arc(x, y, r, 0, 360); } } function f() { } export default IvsDrawer;