VKSession.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386
  1. //index.js
  2. const HTTP = require("../../../requestFn/Api");
  3. //获取应用实例
  4. const app = getApp()
  5. const {
  6. baseURL
  7. } = app.globalData;
  8. Page({
  9. data: {
  10. imgsrc: "/static/mine/view_face_background.png",
  11. src: "",
  12. windowWidth: 0,
  13. windowHeight: 0,
  14. canvasshow: true,
  15. access_token: '',
  16. userImage: "",
  17. cameraShow: true,
  18. tipsText: ""
  19. },
  20. onLoad(options) {
  21. var that = this
  22. const {
  23. garden_id
  24. } = options;
  25. that.setData({
  26. garden_id
  27. })
  28. wx.showLoading({
  29. title: '努力加载中',
  30. mask: true
  31. }) //屏幕宽度
  32. var sysInfo = wx.getSystemInfoSync();
  33. that.setData({
  34. windowWidth: sysInfo.windowWidth / 2,
  35. windowHeight: sysInfo.windowHeight / 2,
  36. })
  37. that.ctx = wx.createCameraContext();
  38. //每次更新access_token
  39. wx.request({
  40. url: "https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=" + app.globalData.client_id + "&client_secret=" + app.globalData.client_secret,
  41. method: 'POST',
  42. dataType: "json",
  43. header: {
  44. 'content-type': 'application/json'
  45. },
  46. success(res) {
  47. app.globalData.access_token = res.data.access_token;
  48. that.setData({
  49. access_token: res.data.access_token
  50. });
  51. //打印access_token
  52. wx.hideLoading();
  53. // that.initData();
  54. that.start()
  55. }
  56. })
  57. },
  58. start() {
  59. this.setOwner();
  60. this.interval = setInterval(this.takePhoto, 5000);
  61. },
  62. init() {
  63. this.setData({
  64. cameraShow: true,
  65. canvasshow: false
  66. })
  67. this.start();
  68. },
  69. // initData() {
  70. // wx.initFaceDetect();
  71. // this.cameraEngine = wx.createCameraContext();
  72. // // 3、获取 Camera 实时帧数据
  73. // const listener = this.cameraEngine.onCameraFrame((frame) => {
  74. // // 4、人脸识别,使用前需要通过 wx.initFaceDetect 进行一次初始化,推荐使用相机接口返回的帧数据
  75. // wx.faceDetect({
  76. // frameBuffer: frame.data,
  77. // width: frame.width,
  78. // height: frame.height,
  79. // enablePoint: true,
  80. // enableConf: true,
  81. // enableAngle: true,
  82. // enableMultiFace: true,
  83. // success: async (faceData) => {
  84. // console.log(faceData);
  85. // let face = faceData.faceInfo[0]
  86. // // if (face.x == -1 || face.y == -1) {
  87. // // this.tipsText = '检测不到人'
  88. // // }
  89. // // if (faceData.faceInfo.length > 1) {
  90. // // this.tipsText = '请保证只有一个人'
  91. // // } else {
  92. // // const {
  93. // // pitch,
  94. // // roll,
  95. // // yaw
  96. // // } = face.angleArray;
  97. // // const standard = 0.5
  98. // // if (Math.abs(pitch) >= standard || Math.abs(roll) >= standard ||
  99. // // Math.abs(yaw) >= standard) {
  100. // // this.tipsText = '请平视摄像头'
  101. // // } else if (face.confArray.global <= 0.8 || face.confArray.leftEye <=
  102. // // 0.8 || face.confArray.mouth <= 0.8 || face.confArray.nose <= 0.8 ||
  103. // // face.confArray.rightEye <= 0.8) {
  104. // // this.tipsText = '请勿遮挡五官'
  105. // // } else {
  106. // // if (this.isVerify) return
  107. // // //人脸位置校验
  108. // // var centerWidth = 250;
  109. // // var centerHeight = 250;
  110. // // if (face.x > (frame.width - centerWidth) / 2 && face.x < (frame
  111. // // .width - centerWidth) / 2 + centerWidth && face.y > (frame
  112. // // .height - centerHeight) / 2 && face.y < (frame.height -
  113. // // centerHeight) / 2 + centerHeight) {
  114. // // this.tipsText = '校验中...'
  115. // // this.isVerify = true;
  116. // // // 太快获取的人脸可能比较抽象,给用户一个准备时间
  117. // // // setTimeout(async () => {
  118. // // this.base64 = await this.changeDataToBase64(
  119. // // frame);
  120. // // this.searchUserFace();
  121. // // // }, 300)
  122. // // } else {
  123. // // this.tipsText = '请将人脸对准中心位置'
  124. // // }
  125. // // }
  126. // // }
  127. // },
  128. // fail: (err) => {
  129. // console.log(err);
  130. // // if (this.isVerify) return
  131. // // if (err.x == -1 || err.y == -1) {
  132. // // this.tipsText = '检测不到人'
  133. // // } else {
  134. // // this.tipsText = err.errMsg || '网络错误,请退出页面重试'
  135. // // }
  136. // },
  137. // })
  138. // })
  139. // // 5、开始监听帧数据
  140. // listener.start()
  141. // setTimeout(()=>{
  142. // listener.stop()
  143. // },2000)
  144. // },
  145. initData() {
  146. const session = wx.createVKSession({
  147. track: {
  148. plane: {
  149. mode: 3
  150. },
  151. face: {
  152. mode: 1
  153. }
  154. },
  155. version: 'v2',
  156. })
  157. this.setData({
  158. session
  159. })
  160. // 需要调用一次 start 以启动
  161. session.start(errno => {
  162. console.log("启动");
  163. if (!errno) {
  164. session.on('updateAnchors', anchors => {
  165. anchors.forEach(anchor => {
  166. console.log('anchor.points', anchor.points)
  167. console.log('anchor.origin', anchor.origin)
  168. console.log('anchor.size', anchor.size)
  169. console.log('anchor.angle', anchor.angle)
  170. })
  171. })
  172. // 当人脸从相机中离开时,会触发 removeAnchors 事件
  173. session.on('removeAnchors', () => {
  174. console.log('removeAnchors')
  175. })
  176. }
  177. })
  178. session.stop(res => {
  179. console.log("关闭");
  180. console.log(res);
  181. })
  182. },
  183. stop() {
  184. clearInterval(this.interval)
  185. },
  186. takePhoto() {
  187. var that = this;
  188. that.setText("")
  189. var takephonewidth
  190. var takephoneheight
  191. that.ctx.takePhoto({
  192. quality: 'medium',
  193. success(res) {
  194. let data = res;
  195. // 获取图片真实宽高
  196. wx.getImageInfo({
  197. src: res.tempImagePath,
  198. success(res) {
  199. takephonewidth = res.width;
  200. takephoneheight = res.height;
  201. }
  202. })
  203. wx.getFileSystemManager().readFile({
  204. filePath: res.tempImagePath, //选择图片返回的相对路径
  205. encoding: 'base64', //编码格式
  206. success(res) {
  207. //成功的回调
  208. wx.request({
  209. url: "https://aip.baidubce.com/rest/2.0/face/v3/detect?access_token=" + that.data.access_token,
  210. data: {
  211. image: res.data,
  212. image_type: "BASE64",
  213. max_face_num: 1,
  214. face_field: "eye_status,quality"
  215. },
  216. method: 'POST',
  217. dataType: "json",
  218. header: {
  219. 'content-type': 'application/json'
  220. },
  221. success(res) {
  222. console.log(res.data);
  223. if (res.data.error_msg === "SUCCESS") {
  224. let quality = res.data.result.face_list[0].quality;
  225. let eye_status = res.data.result.face_list[0].eye_status
  226. const {
  227. left_eye,
  228. right_eye,
  229. nose,
  230. mouth,
  231. left_cheek,
  232. right_cheek,
  233. chin_contour
  234. } = quality.occlusion;
  235. const {
  236. left_eye: left_eye1,
  237. right_eye: right_eye1
  238. } = eye_status;
  239. const {
  240. illumination
  241. } = quality;
  242. const location = res.data.result.face_list[0].location
  243. const {
  244. left,
  245. top,
  246. height,
  247. width
  248. } = location;
  249. var x1 = left / takephonewidth * that.data.windowWidth;
  250. var y1 = top / takephoneheight * that.data.windowHeight;
  251. var sw = (width / takephonewidth * that.data.windowWidth);
  252. var sh = (height / takephoneheight * that.data.windowHeight);
  253. var centerX = x1 + sw * 0.5;
  254. var centerY = y1 + sh * 0.5;
  255. var screenX = that.data.windowWidth * 0.5;
  256. var screenY = that.data.windowHeight * 0.5; //左右角度
  257. var x = res.data.result.face_list[0].angle.yaw; //俯仰角度
  258. var y = res.data.result.face_list[0].angle.pitch;
  259. if (((x >= -12.0 && x <= 12.0) && (y >= -8.0 && y <= 15.0) && (sw <= that.data.windowWidth * 0.5 && sh <= that.data.windowHeight * 0.5)) && (((centerX >= screenX - 20.0) && (centerX <= screenX + 20.0)) && (centerY >= screenY - 80.0) && (centerY <= screenY + 80.0))) {
  260. if (illumination < 20) {
  261. that.setText("当前光线较弱")
  262. return false
  263. } else if (left_eye1 < 0.5 || right_eye1 < 0.5) {
  264. that.setText("请保持双眼睁开")
  265. return false
  266. } else if (
  267. left_eye > 0.2 || right_eye > 0.2 || nose > 0.2 || mouth > 0.2 || left_cheek > 0.2 || right_cheek > 0.2 || chin_contour > 0.2) {
  268. that.setText("请勿遮挡五官")
  269. return false
  270. } else {
  271. that.setData({
  272. cameraShow: false,
  273. canvasshow: true
  274. })
  275. that.drawImag(data);
  276. }
  277. } else {
  278. that.setText("请将人脸对准中心位置")
  279. return false
  280. }
  281. } else if (res.data.error_msg === "pic not has face") {
  282. that.setData({
  283. tipsText: "未检测到人脸"
  284. })
  285. }
  286. }
  287. })
  288. }
  289. })
  290. }
  291. })
  292. },
  293. upload() {
  294. var that = this;
  295. clearInterval(that.interval);
  296. const userInfo = wx.getStorageSync('userInfo')
  297. wx.uploadFile({
  298. filePath: that.data.userImage,
  299. name: 'file',
  300. url: baseURL + '/upload',
  301. header: {
  302. "token": userInfo.token
  303. },
  304. success(res) {
  305. const pic_url = JSON.parse(res.data).data;
  306. that.InputFace(pic_url);
  307. },
  308. fail(res) {
  309. console.log(res);
  310. }
  311. })
  312. },
  313. onUnload() {
  314. clearInterval(this.interval)
  315. },
  316. previewImage() {
  317. wx.previewImage({
  318. urls: [this.data.userImage],
  319. })
  320. },
  321. setOwner() {
  322. var timeStamp = Date.parse(new Date)
  323. this.setData({
  324. owner: timeStamp / 1000
  325. })
  326. },
  327. drawImag(data) {
  328. const that = this;
  329. const query = this.createSelectorQuery()
  330. query.select(`#canvas${this.data.owner}`).fields({
  331. node: true,
  332. size: true
  333. });
  334. query.exec((res) => {
  335. const canvas = res[0].node
  336. const ctx = canvas.getContext('2d')
  337. const dpr = wx.getSystemInfoSync().pixelRatio
  338. canvas.width = res[0].width * dpr
  339. canvas.height = res[0].height * dpr
  340. ctx.scale(dpr, dpr)
  341. let userImage = data.tempImagePath
  342. that.setData({
  343. userImage
  344. })
  345. const img = canvas.createImage()
  346. img.src = userImage
  347. img.onload = function () {
  348. ctx.drawImage(img, 0, 0, 100, 100)
  349. }
  350. })
  351. },
  352. setText(val) {
  353. this.setData({
  354. tipsText: val
  355. })
  356. },
  357. async InputFace(pic_url) {
  358. const {
  359. garden_id
  360. } = this.data;
  361. const {code} = await HTTP.Face({
  362. method: "post",
  363. garden_id: garden_id - 0,
  364. pic_url
  365. })
  366. if(code==0){
  367. wx.showToast({
  368. title: '上传成功',
  369. icon: 'success',
  370. duration: 2000,
  371. })
  372. setTimeout(() => {
  373. wx.navigateBack()
  374. }, 2000);
  375. }else{
  376. setTimeout(() => {
  377. wx.navigateBack()
  378. }, 2000);
  379. }
  380. }
  381. })