tensorflow.js官方特别支持了微信小程序,看tfjs-core,fjs-backend-webgl等等模块的dist下都一个单独的miniprogram目录。

还特别提供了一个微信小程序的插件:https://github.com/tensorflow/tfjs-wechat

tensorflow.js对微信小游戏还不支持,但是可以类似的实现,但是效率不高;

小游戏不支持插件,直接使用tfjs-webchat源码,我名称改为tfjs-plugin。

试试一个头部姿势,左右,点头控制:

基本的引用:

let sysInfo=wx.getSystemInfoSync();
const fetchWechat = require('fetch-wechat');
//window.fetch=fetchWechat.fetchFunc();const tf_core = require('@tensorflow/tfjs-core');
let tf_poseNet=require('@tensorflow-models/posenet');
const tf_webgl = require('@tensorflow/tfjs-backend-webgl');
const tf_plugin = require('./js/libs/@tensorflow/tfjs-plugin/index.js');//不能用主屏幕,组屏幕是2d的
let tf_canvas=wx.createCanvas();///必须指定webGL 1.0版本,微信小游戏只实现了这个版本,不支持2.0
tf_core.ENV.flagRegistry.WEBGL_VERSION.evaluationFn = function() {return 1;}
//tf_core.ENV.set('WEBGL_PACK', false);tf_plugin.configPlugin({//backendName:'wechat-webgl',fetchFunc: fetchWechat.fetchFunc(),tf:tf_core,webgl:tf_webgl,canvas: tf_canvas
},false);

载入官方预训练好的poseNet模型,先尝试从本地缓存加载,失败时从服务器加载,加载成功后保存到本地缓存:

const POSENET_URL = 'https://ai.flypot.cn/models/posenet/model.json';
const FILE_STORAGE_PATH='poseNet';
const fileStorageHandler = tf_plugin.fileStorageIO(FILE_STORAGE_PATH, wx.getFileSystemManager());
let g_model=null;function loadModel(options){if (g_model){if (options.success) options.success(g_model);return;}let cfg={architecture: 'MobileNetV1',outputStride: 16,//越大速度越快inputResolution: 193,//越小速度越快multiplier: 0.5//越小越快}function loadFromLocal(){console.log('load model from local................');wx.showLoading({title: '从本地加载模型...',mask:true});//https://github.com/tensorflow/tfjs-models/tree/master/posenetcfg.modelUrl=fileStorageHandler;tf_poseNet.load(cfg).then(function(model){console.log('model loaded');wx.hideLoading();//console.log(model);g_model = model;if (options.success){options.success(model);}},function(err){console.log(err);loadFromServer();});}function loadFromServer(){console.log('load model from server................');wx.showLoading({title: '从服务器加载模型...',mask:true});cfg.modelUrl=POSENET_URL;tf_poseNet.load(cfg).then(function(model){console.log('model loaded');wx.hideLoading();//console.log(model);model.baseModel.model.save(fileStorageHandler);g_model = model;if (options.success){options.success(model);}},function(err){console.log(err);wx.hideLoading();if (options.fail){options.fail(err);}});}loadFromLocal();
}

载入模型后,打开camera,开始侦测,没有办法直接画在摄像头的canvas上,所以摄像头的canvas设置为1x1大小,相当于隐藏起来。

因为每次人体姿势检测在手机上大概要花80-110ms,很慢,所以不能摄像头视频每帧都检测,10帧检测一次,否则很卡:

let g_camera=null;
let frameIndex=0;
let canvas_camera,ctx_camera;
let camera_imageData;function startPoseNetControl(options){function doIt(){//demoDetect();openCamera();if (options.success) options.success();options.complete();}if (g_model) {doIt();return;}loadModel({success:function(model){// wx.showModal({//   content: 'model loaded.'// });doIt();},fail:function(err){wx.showModal({content: JSON.stringify(err)});if (options.fail) options.fail(err);options.complete();}});
}function stopPoseNetControl(options){if (g_camera){g_camera.destroy();g_camera=null;}canvas_camera=null;if (options.success) options.success();options.complete();
}function openCamera(){g_camera=wx.createCamera({width:1,//不影响onFrame返回的width和heightheight:1,devicePosition:'front',size:'small',flash:'off',success:function(res){console.log('camera opened.');console.log(res);g_camera.listenFrameChange();},fail:function(e){console.log('camera open fail:',e);}});g_camera.onCameraFrame(function(frame){//console.log(frame.width);frameIndex++;if (frameIndex<10) return;if (!canvas_camera){canvas_camera=wx.createCanvas();canvas_camera.width=frame.width;canvas_camera.height=frame.height;ctx_camera=canvas_camera.getContext('2d');camera_imageData = ctx_camera.createImageData(frame.width,frame.height);}let pixels=new Uint8Array(frame.data);detectFrame({pixels:pixels,width:frame.width,height:frame.height,success:function(res){camera_imageData.data.set(pixels);ctx_camera.putImageData(camera_imageData,0,0);displayResult(res);frameIndex=0;},fail:function(err){frameIndex=0;}});});
}

调用人体姿势检测:

function detectFrame(options){//let t1=new Date();g_model.estimateSinglePose({data:options.pixels,width:options.width,height:options.height}, {flipHorizontal: false}).then(function(res){//每次检测,在pc模拟器中:第1次要800-900ms,第2次只要60-90ms//手机上:第2次后每次80-110msoptions.success(res);},function(err){options.fail(err);});
}let g_noseEys_distance=999999;function displayResult(pose){//console.log(pose);const minPoseConfidence = 0.3;const minPartConfidence = 0.3;if (pose.score >= minPoseConfidence) {drawKeypoints(pose.keypoints, minPartConfidence, ctx_camera);//drawBoundingBox(pose.keypoints,ctx_camera);//drawSkeleton(pose.keypoints, minPartConfidence, ctx_camera);if (!wx.tmGlobal.isAllowControl()) return;//鼻子高度-左眼高度let dy1=Math.round(pose.keypoints[0].position.y-pose.keypoints[1].position.y);  //左眼高度-右眼高度let dy2=pose.keypoints[1].position.y-pose.keypoints[2].position.y;//console.log(dy2);if (dy1-g_noseEys_distance>10 && dy2>-10 && dy2<10){//低头时,鼻子-左眼间距加大wx.tmGlobal.webGL.releaseCurrentBall();}else{wx.tmGlobal.webGL.moveCurrentBall(dy2);}g_noseEys_distance=dy1;}
}const color = 'aqua';
const boundingBoxColor = 'red';
const lineWidth = 2;function drawKeypoints(keypoints, minConfidence, ctx, scale = 1) {for (let i = 0; i < keypoints.length; i++) {const keypoint = keypoints[i];if (keypoint.score < minConfidence) {continue;}const { y, x } = keypoint.position;drawPoint(ctx, y * scale, x * scale, 5, color);}
}function drawPoint(ctx, y, x, r, color) {ctx.beginPath()ctx.arc(x, y, r, 0, 2 * Math.PI);ctx.fillStyle = color;ctx.fill();ctx.stroke();
}

微信小游戏用tensorflow.js人体姿势PoseNet控制相关推荐

  1. 微信小游戏_China_Fighting——game.js、game.json、project.config.json

    目录 微信小游戏_China_Fighting--前言 微信小游戏_China_Fighting--基础支撑类(sprite.animation.pool) 微信小游戏_China_Fighting- ...

  2. 微信小游戏、three.js、真机调试,出现锯齿的解决办法

    更正: 原文是基于微信小游戏,在微信开发者工具.手机端微信小游戏,该方案没问题. 我今天尝试移植到普通web,该方案出现新问题: 1)不使用该方案,则出现锯齿. 2)使用该方案,则正圆变成椭圆. 暂时 ...

  3. 新手入门:如何用Laya开发微信小游戏?

    1.环境准备 1.1 LayaAirIDE 1.7.14版本才开始集成微信小游戏开发. 1.2 微信小游戏开发工具 微信小游戏开发工具是小游戏开发与测试的环境,由于LayaAir引擎的开发者完全可以使 ...

  4. Laya之微信小游戏入门

    1.环境准备 1.1 LayaAirIDE 1.7.14版本才开始集成微信小游戏开发 1.2 微信小游戏开发工具 微信小游戏开发工具是小游戏开发与测试的环境,由于LayaAir引擎的开发者完全可以使用 ...

  5. 在微信小游戏中开发一个贪食蛇

    为什么80%的码农都做不了架构师?>>>    我自己也写过一个贪食蛇的小游戏,不过是对dom的操作,微信小游戏是采用js语法基于canvas的开发.为了省事在网上直接搜了一个基于c ...

  6. 微信小游戏_China_Fighting——npc类(enemy、mask、sars)

    目录 微信小游戏_China_Fighting--前言 微信小游戏_China_Fighting--基础支撑类(sprite.animation.pool) 微信小游戏_China_Fighting- ...

  7. 微信小游戏_China_Fighting——后记

    目录 微信小游戏_China_Fighting--前言 微信小游戏_China_Fighting--基础支撑类(sprite.animation.pool) 微信小游戏_China_Fighting- ...

  8. 微信小游戏_China_Fighting——前言

    目录 微信小游戏_China_Fighting--前言 微信小游戏_China_Fighting--基础支撑类(sprite.animation.pool) 微信小游戏_China_Fighting- ...

  9. 微信小游戏 demo 飞机大战 代码分析(四)(enemy.js, bullet.js, index.js)

    微信小游戏 demo 飞机大战 代码分析(四)(enemy.js, bullet.js, index.js) 微信小游戏 demo 飞机大战 代码分析(一)(main.js) 微信小游戏 demo 飞 ...

最新文章

  1. 记录ALiYun EMR常用服务的手动启动和停止命令(hdfs/yarn/mr-jobhistory/zk/spark-history)
  2. (转)个例子让你了解Java反射机制
  3. android Mp3播放器之音频文件扫描
  4. thinkphp几个表的数据合并,并用数组分页
  5. iar 看时序_IAR 硬件仿真查看运行时间
  6. C语言程序main入口函数
  7. c语言 在txt文件中搜索关键词_网络推广外包—网络推广外包如何在搜索引擎中体现关键词优化效果...
  8. C++中const char *p和char const *p
  9. asp.net捕获全局未处理异常的几种方法
  10. 二分答案——小车问题(洛谷 P1258)
  11. 默认地址路径修改_修改Docker默认路径
  12. nj04---事件回调函数
  13. 是谁断送了网络工程师的前途
  14. Vulkan入门(一)-环境配置.md
  15. ssm整合开发配置文件
  16. 论文笔记:Show, Edit and Tell : A Framework for Editing Image Captions
  17. 记-微服务CPU100%排查之windows版
  18. OpenCV笔记-对轮廓进行平滑处理
  19. 破解root密码详细流程
  20. Hexo博客Next主题配置加载优化性能提升

热门文章

  1. 基于STM32的智能循迹避障小车实验(小车运动部分)
  2. ros机器小车运动控制
  3. Ubuntu 17.04 x64 安装 Docker CE 初窥 Dockerfile 部署 Ngi
  4. 电大c语言形考作业网上作业,C语言程序设计电大形考作业
  5. 【论文】:NEZHA(哪吒)
  6. 口袋妖怪c语言代码大全,口袋妖怪漆黑的魅影金手指代码大全
  7. Linux下类迅雷的下载神器-uGet 2.0
  8. 我的世界无限天空服务器,我的世界1.8-1.12魔塔天空RPG服务器
  9. c++11工厂子类实现自注册的两种方法
  10. 四个主要的连接池介绍!(建议收藏!)