当前位置:   article > 正文

seetaface 人脸识别 android 优化源码开放_seetaface6 android图片转特征

seetaface6 android图片转特征

申明:由于本人水平有限,所提供的代码、dll、so等必然存在很多问题,仅用于学习,不适合工业级使用,请谨慎使用,如果造成损失,责任自负。

基于seetaface的android实现,包含检测、对齐、比对,带自动遍历比对人脸,

JNI传递复杂对象,包括数组,

采用NEON优化提高处理速度,提供人脸旋转角度roll,pitch,yaw,

加载人脸识别模型改为只需加载一次,

在手机上提取特征并比对一次约需1.5~2秒,下图是模拟器的,只需要500多毫秒。

需要自己编译jni,并把3个.bin的模型文件放到手机的/sdcard/目录,也就是连上电脑后的根目录。

3个模型文件seeta_fa_v1.1.bin, seeta_fd_frontal_v1.0.bin,seeta_fr_v1.0.bin:

链接:http://pan.baidu.com/s/1geMDddD 密码:km1q

 

apk:http://download.csdn.net/detail/wuzuyu365/9843787

源码: 下载

NDK建议用android-ndk-r9d,SDK建议用Android-19或Android-20

jni编译好的so库:http://download.csdn.net/detail/wuzuyu365/9810605

 

neon优化的文件:math_functions.cpp

 

  1. /*
  2. *
  3. * This file is part of the open-source SeetaFace engine, which includes three modules:
  4. * SeetaFace Detection, SeetaFace Alignment, and SeetaFace Identification.
  5. *
  6. * This file is part of the SeetaFace Identification module, containing codes implementing the
  7. * face identification method described in the following paper:
  8. *
  9. *
  10. * VIPLFaceNet: An Open Source Deep Face Recognition SDK,
  11. * Xin Liu, Meina Kan, Wanglong Wu, Shiguang Shan, Xilin Chen.
  12. * In Frontiers of Computer Science.
  13. *
  14. *
  15. * Copyright (C) 2016, Visual Information Processing and Learning (VIPL) group,
  16. * Institute of Computing Technology, Chinese Academy of Sciences, Beijing, China.
  17. *
  18. * The codes are mainly developed by Zining Xu(a M.S. supervised by Prof. Shiguang Shan)
  19. *
  20. * As an open-source face recognition engine: you can redistribute SeetaFace source codes
  21. * and/or modify it under the terms of the BSD 2-Clause License.
  22. *
  23. * You should have received a copy of the BSD 2-Clause License along with the software.
  24. * If not, see < https://opensource.org/licenses/BSD-2-Clause>.
  25. *
  26. * Contact Info: you can send an email to SeetaFace@vipl.ict.ac.cn for any problems.
  27. *
  28. * Note: the above information must be kept whenever or wherever the codes are used.
  29. *
  30. */
  31. #include "math_functions.h"
  32. //#include <xmmintrin.h>
  33. #include "arm_neon.h"
  34. #include <cstdint>
  35. //neon process
  36. //采用neon单指令流多数据流SIMD优化内积运算,可以减少1秒时间
  37. float simd_dot(const float* src1, const float* src2, const long& count) {
  38. long i = 0;
  39. float32x4_t sum_vec = vdupq_n_f32(0);
  40. for (; i <count - 3 ; i+=4){
  41. float32x4_t data_a = vld1q_f32(&src1[i]);
  42. float32x4_t data_b = vld1q_f32(&src2[i]);
  43. sum_vec = vaddq_f32(sum_vec, vmulq_f32(data_a, data_b));
  44. }
  45. float sum = sum_vec[0] + sum_vec[1] + sum_vec[2] + sum_vec[3];
  46. //累加剩下的
  47. for (; i < count; i++){
  48. sum += src1[i] * src2[i];
  49. }
  50. return sum;
  51. }
  52. //为了更进一步提高速度,可尝试采用unsigned char类型的点积,未完成
  53. float simd_dot_uc(const unsigned char* src1, const unsigned char* src2, const long& count) {
  54. long i = 0;
  55. //neon process
  56. uint8x16_t sum_vec = vdupq_n_u8(0);
  57. for (; i <count - 15 ; i+=16){
  58. uint8x16_t data_a = vld1q_u8(&src1[i]);
  59. uint8x16_t data_b = vld1q_u8(&src2[i]);
  60. sum_vec = vaddq_u8(sum_vec, vmulq_u8(data_a, data_b));
  61. }
  62. float sum = 0;
  63. for(int i=0; i<16; i++){
  64. sum += sum_vec[i];
  65. }
  66. //累加剩下的
  67. for (; i < count; i++){
  68. sum += src1[i] * src2[i];
  69. }
  70. return sum;
  71. }
  72. //耗时很长的没有并行化的点积计算代码
  73. float simd_dot_c(const float* x, const float* y, const long& len) {
  74. float inner_prod = 0.0f;
  75. long i;
  76. //LOGD("simd_dot,len=%ld", len);
  77. for (i = 0; i < len; i++) {
  78. inner_prod += x[i] * y[i];
  79. }
  80. return inner_prod;
  81. }
  82. //PC上的SSE优化代码,android上无法使用
  83. float simd_dot_sse(const float* x, const float* y, const long& len) {
  84. float inner_prod = 0.0f;
  85. __m128 X, Y; // 128-bit values
  86. __m128 acc = _mm_setzero_ps(); // set to (0, 0, 0, 0)
  87. float temp[4];
  88. long i;
  89. for (i = 0; i + 4 < len; i += 4) {
  90. X = _mm_loadu_ps(x + i); // load chunk of 4 floats
  91. Y = _mm_loadu_ps(y + i);
  92. acc = _mm_add_ps(acc, _mm_mul_ps(X, Y));
  93. }
  94. _mm_storeu_ps(&temp[0], acc); // store acc into an array
  95. inner_prod = temp[0] + temp[1] + temp[2] + temp[3];
  96. return inner_prod;
  97. }
  98. void matrix_procuct(const float* A, const float* B, float* C, const int n,
  99. const int m, const int k, bool ta, bool tb) {
  100. #ifdef _BLAS
  101. arma::fmat mA = ta ? arma::fmat(A, k, n).t() : arma::fmat(A, n, k);
  102. arma::fmat mB = tb ? arma::fmat(B, m, k).t() : arma::fmat(B, k, m);
  103. arma::fmat mC(C, n, m, false);
  104. mC = mA * mB;
  105. #else
  106. CHECK_TRUE(ta && !tb);
  107. const float* x = B;
  108. for (int i = 0, idx = 0; i < m; ++i) {
  109. const float* y = A;
  110. for (int j = 0; j < n; ++j, ++idx) {
  111. C[idx] = simd_dot(x, y, k);
  112. y += k;
  113. }
  114. x += k;
  115. }
  116. #endif
  117. }
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/361490
推荐阅读
相关标签
  

闽ICP备14008679号