【一步步开发AI运动小程序】六、人体骨骼图绘制

随着人工智能技术的不断发展,阿里体育等IT大厂,推出的“乐动力”、“天天跳绳”AI运动APP,让云上运动会、线上运动会、健身打卡、AI体育指导等概念空前火热。那么,能否将这些在APP成功应用的场景搬上小程序,分享这些概念的红利呢?本系列文章就带您一步一步从零开始开发一个AI运动小程序,本系列文章将使用“云智AI运动识别小程序插件”,请先行在微信服务市场官网了解详情。

一、骨骼图绘制原理

人体骨骼图的绘制,是通过在camera组件上附一个同等大小的透明canvas组件,在上面绘制关键点达到与人体图像重合的目的。

二、绘制代码

<template>
	<view class="human-detection">
	<camera id="preview" class="preview" :style="videoStyles" flash="off" :device-position="deviceKey"
	resolution="high" frame-size="low" @initdone="onCameraReady">
	</camera>
	<canvas v-if="poseDrawEnabled" class="preview graphs" type="2d" id="graphics" :style="videoStyles"></canvas>
	</view>
</template>
<script>
	const AiSports = requirePlugin("aiSport");
	const PoseGraphs = AiSports.PoseGraphs;
	const humanDetection = AiSports.humanDetection;
	export default {
	data() {
	return {
	zoom: 1,
	deviceKey: "back",
	previewWidth: 480,
	previewHeight: 640,
	previewRate: 1,
	frameWidth: 480,
	frameHeight: 640,
	status: 'unknown',
	fps: 0,
	poseFps: 0,
	isHumanBody: false
	};
	},
	computed: {
	videoStyles() {
	const style = `width:${this.previewWidth}px;height:${this.previewHeight}px;`;
	return style;
	}
	},
	mounted() {
	this.autoFitPreview(480, 640);
	this.initCanvas();
	},
	methods: {
	autoFitPreview(width, height) {
	const sifno = uni.getSystemInfoSync();
	let rate = sifno.windowWidth / width;
	this.previewWidth = width * rate;
	this.previewHeight = height * rate;
	this.previewRate = rate;
	this.frameWidth = width;
	this.frameHeight = height;
	},
	initCanvas() {
	const that = this;
	const query = uni.createSelectorQuery().in(that);
	query.select('#graphics')
	.fields({
	node: true,
	size: true
	})
	.exec((res) => {
	if (utils.isEmptyArray(res))
	return;
	const canvas = res[0].node;
	const ctx = canvas.getContext('2d');
	const dpr = uni.getSystemInfoSync().pixelRatio;
	canvas.width = res[0].width * dpr;
	canvas.height = res[0].height * dpr;
	ctx.scale(dpr, dpr);
	that.canvas = canvas;
	that.ctx = ctx;
	that.poseGraphs = new PoseGraphs(ctx, canvas.width, canvas.height, 1);
	that.poseGraphs.lineColor = "#FF8E148C";//线条颜色
	});
	},
	async detection(frame) {
	const human = await humanDetection.detectionAsync(frame);
	//无结果
	if (!human)
	this.poseGraphs.clear();
	else
	this.poseGraphs.drawing(human.keypoints);
	},
	initVideo() {
	if (this.camera)
	return;
	const that = this;
	this.camera = new CameraDevice();
	this.camera.onFrame = frame => {
	that.fps = that.camera.fps;
	//重新自适应
	if (frame.width != that.frameWidth || frame.height != that.frameHeight) {
	that.autoFitPreview(frame.width, frame.height);
	that.initCanvas();
	}
	that.detection(frame);
	};
	}
	}
	}
</script>
<style lang="scss">
	.human-detection {
	width: auto;
	height: auto;
	.preview {
	margin: auto;
	width: 480px;
	height: 640px;
	}
	.graphs {
	position: absolute;
	top: 0;
	left: 0;
	z-index: 9999;
	box-shadow: 0 0 14.4928rpx #CCC;
	background-color: rgba(0, 0, 0, 0.01);
	}
	}
</style>

三、注意事项

小程序的抽帧图像大小与camera实时图像可能不一致(https://developers.weixin.qq.com/miniprogram/dev/component/camera.html#Bug-Tip),所以cameracanvas组件必须保持与帧图像保持同比缩放,否则可能导致骨骼与实时图像不一致。

下篇我们将为您介绍如何进行运动分析,敬请期待...

作者:alphaair原文地址:https://www.cnblogs.com/alphaair/p/17426183.html

%s 个评论

要回复文章请先登录注册