当前位置:   article > 正文

运动状态识别(python转c)_py里判断是步行还是跑步

py里判断是步行还是跑步

由于算法要运行在手表上,算力和内存空间有限,需要进行内存压缩和c代码实现。

状态识别(计算步数+分段滤波)_传统处理方法

Status_detection.c

  1. #include <stdio.h>
  2. #include <stdbool.h>
  3. #include <math.h>
  4. #include <stdlib.h>
  5. #define buf_p 7
  6. #define EPS 0.000001
  7. float g_Tx[250], g_Tx1[250];
  8. float g_Sp[20], g_Tvec[20], g_Zi[20];
  9. int g_Is[10], g_Js[10];
  10. float b_ppg[3] = { 0.0133592,0.0267184,0.0133592 };
  11. float a_ppg[3] = { 1, -1.64745998, 0.70089678 };//b_u和a_u为滤波器参数
  12. void Filter(const float* x, float* y, int xlen, float* a, float* b, int nfilt, float* g_Zi)//nfilt为系数数组长度,g_Zi为延时系数
  13. {
  14. float tmp;
  15. int i, j;
  16. //判断a[0]是否为1,若不是,归一化下
  17. if ((*a - 1.0 > EPS) || (*a - 1.0 < -EPS))
  18. {
  19. tmp = *a;
  20. for (i = 0; i < nfilt; i++)
  21. {
  22. b[i] /= tmp;
  23. a[i] /= tmp;
  24. }
  25. }
  26. memset(y, 0, xlen * sizeof(float));//将y清零,以双浮点为单位
  27. a[0] = 0.0;
  28. for (i = 0; i < xlen; i++)
  29. {
  30. for (j = 0; i >= j && j < nfilt; j++)
  31. {
  32. y[i] += (b[j] * x[i - j] - a[j] * y[i - j]);
  33. }
  34. //滤波器阶数大于2就加上延时系数
  35. if (g_Zi&&i < nfilt - 1) y[i] += g_Zi[i];
  36. }
  37. a[0] = 1.0;//还原滤波系数
  38. }
  39. //矩阵乘法 ,第一个矩阵列数必须要和第二个矩阵的行数相同,输出结果存放在c中
  40. void Trmul(float *a, float *b, float *c, int m, int n, int k)
  41. {
  42. int i, j, l, u;
  43. for (i = 0; i <= m - 1; i++)
  44. for (j = 0; j <= k - 1; j++)
  45. {
  46. u = i * k + j; c[u] = 0.0;
  47. for (l = 0; l <= n - 1; l++)
  48. c[u] = c[u] + a[i*n + l] * b[l*k + j];
  49. }
  50. return;
  51. }
  52. //求逆矩阵,当返回值为0时成功,a变为逆矩阵
  53. int Rinv(float *a, int n)
  54. {
  55. int i, j, k, l, u, v;
  56. float d, p;
  57. for (k = 0; k <= n - 1; k++)
  58. {
  59. d = 0.0;
  60. for (i = k; i <= n - 1; i++)
  61. for (j = k; j <= n - 1; j++)
  62. {
  63. l = i * n + j; p = fabs(a[l]);
  64. if (p > d) { d = p; g_Is[k] = i; g_Js[k] = j; }
  65. }
  66. if (g_Is[k] != k)
  67. for (j = 0; j <= n - 1; j++)
  68. {
  69. u = k * n + j; v = g_Is[k] * n + j;
  70. p = a[u]; a[u] = a[v]; a[v] = p;
  71. }
  72. if (g_Js[k] != k)
  73. for (i = 0; i <= n - 1; i++)
  74. {
  75. u = i * n + k; v = i * n + g_Js[k];
  76. p = a[u]; a[u] = a[v]; a[v] = p;
  77. }
  78. l = k * n + k;
  79. a[l] = 1.0 / a[l];
  80. for (j = 0; j <= n - 1; j++)
  81. if (j != k)
  82. {
  83. u = k * n + j; a[u] = a[u] * a[l];
  84. }
  85. for (i = 0; i <= n - 1; i++)
  86. if (i != k)
  87. for (j = 0; j <= n - 1; j++)
  88. if (j != k)
  89. {
  90. u = i * n + j;
  91. a[u] = a[u] - a[i*n + k] * a[k*n + j];
  92. }
  93. for (i = 0; i <= n - 1; i++)
  94. if (i != k)
  95. {
  96. u = i * n + k; a[u] = -a[u] * a[l];
  97. }
  98. }
  99. for (k = n - 1; k >= 0; k--)
  100. {
  101. if (g_Js[k] != k)
  102. for (j = 0; j <= n - 1; j++)
  103. {
  104. u = k * n + j; v = g_Js[k] * n + j;
  105. p = a[u]; a[u] = a[v]; a[v] = p;
  106. }
  107. if (g_Is[k] != k)
  108. for (i = 0; i <= n - 1; i++)
  109. {
  110. u = i * n + k; v = i * n + g_Is[k];
  111. p = a[u]; a[u] = a[v]; a[v] = p;
  112. }
  113. }
  114. return(0);
  115. }
  116. int FiltFilt(float* x, float* y, int len)
  117. {
  118. // int nfact = 4;
  119. int nfact = 2;
  120. int tlen; //length of g_Tx
  121. int i;
  122. float *p, *t, *end;
  123. float tmp, tmp1;
  124. //float sum = 0.0;
  125. //float average = 0.0;
  126. //for (int p = 0; p < len; p++)
  127. //{
  128. // sum += x[p];
  129. //}
  130. //average = (float)sum / len;
  131. printf("平均值 = %.2f", average);
  132. //for (int p = 0; p < len; ++p)
  133. //{
  134. // x[p] = x[p] - average;
  135. // //x2[p] = -1 * x2[p];
  136. //}
  137. //镜像到至少三倍长度
  138. tlen = 6 * nfact + len;
  139. tmp = x[0];
  140. for (p = x + 3 * nfact, t = g_Tx; p > x; --p, ++t)
  141. *t = 2.0*tmp - *p;
  142. for (end = x + len; p < end; ++p, ++t)
  143. *t = *p;
  144. tmp = x[len - 1];
  145. for (end = g_Tx + tlen, p -= 2; t < end; --p, ++t)
  146. *t = 2.0*tmp - *p;
  147. //g_Tx初始化
  148. end = g_Sp + nfact * nfact;
  149. p = g_Sp;
  150. // while (p < end) *p++ = 0.0L;
  151. while (p < end) *p++ = 0.0f;
  152. g_Sp[0] = 1.0 + a_ppg[1];
  153. for (i = 1; i < nfact; i++)
  154. {
  155. g_Sp[i*nfact] = a_ppg[i + 1];
  156. /* g_Sp[i*nfact + i] = 1.0L;
  157. g_Sp[(i - 1)*nfact + i] = -1.0L;*/
  158. g_Sp[i*nfact + i] = 1.0f;
  159. g_Sp[(i - 1)*nfact + i] = -1.0f;
  160. }
  161. for (i = 0; i < nfact; i++)
  162. {
  163. g_Tvec[i] = b_ppg[i + 1] - a_ppg[i + 1] * b_ppg[0];
  164. }
  165. if (Rinv(g_Sp, nfact))
  166. {
  167. for (i = 0; i < 50; i++)
  168. {
  169. g_Zi[i] = 0;
  170. }
  171. }
  172. else
  173. {
  174. Trmul(g_Sp, g_Tvec, g_Zi, nfact, nfact, 1);
  175. } //g_Zi延迟系数计算
  176. //1st filter
  177. tmp1 = g_Tx[0];
  178. if (g_Zi)
  179. for (p = g_Zi, end = g_Zi + nfact; p < end;) *(p++) *= tmp1;
  180. {
  181. //Filter(g_Tx, g_Tx1, tlen, a_ppg, b_ppg, 5, g_Zi);
  182. Filter(g_Tx, g_Tx1, tlen, a_ppg, b_ppg, 3, g_Zi);
  183. }
  184. //翻转g_Tx1
  185. for (p = g_Tx1, end = g_Tx1 + tlen - 1; p < end; p++, end--)
  186. {
  187. tmp = *p;
  188. *p = *end;
  189. *end = tmp;
  190. }
  191. //2nd filter
  192. tmp1 = (*g_Tx1) / tmp1;
  193. if (g_Zi)
  194. for (p = g_Zi, end = g_Zi + nfact; p < end;) *(p++) *= tmp1;
  195. {
  196. //Filter(g_Tx1, g_Tx, tlen, a_ppg, b_ppg, 5, g_Zi);
  197. Filter(g_Tx1, g_Tx, tlen, a_ppg, b_ppg, 3, g_Zi);
  198. }
  199. //output
  200. end = y + len;
  201. p = g_Tx + 3 * nfact + len - 1;
  202. while (y < end)
  203. {
  204. *y++ = *p--;
  205. }
  206. return 0;
  207. }
  208. // 需要滤波,否则会出现两个波峰/波谷的情况(在波峰/波谷处是直线,则会出现此情况)
  209. // 寻找波峰
  210. short FindPeak1(float *arr, short *peak_index)
  211. {
  212. short n = 0;
  213. for (short i = 1; i < 199; i++)
  214. {
  215. if (arr[i]>arr[i-1] && arr[i] > arr[i + 1] && n < 33)
  216. {
  217. peak_index[n] = i;
  218. n += 1;
  219. }
  220. }
  221. return n;
  222. }
  223. // 寻找波谷
  224. short FindPeak2(float *arr, short *peak_index)
  225. {
  226. short n = 0;
  227. for (short i = 1; i < 199; i++)
  228. {
  229. if (arr[i] < arr[i - 1] && arr[i] < arr[i + 1] && n < 33)
  230. {
  231. peak_index[n] = i;
  232. n += 1;
  233. }
  234. }
  235. return n;
  236. }
  237. // 跑步状态检测
  238. short RunStateDetection(float arr[], float data[], short peak1_index[], short peak2_index[], float allPeak1[], short allPeak1_index[], short allPeak1_nums[],
  239. float allPeak2[], short allPeak2_index[], short allPeak2_nums[])
  240. {
  241. short i = 0;
  242. // 1.低通滤波
  243. FiltFilt(arr, data, 200);
  244. // 2.寻找波峰/波谷
  245. for (i = 0; i < 33; i++)
  246. {
  247. peak1_index[i] = 0;
  248. peak2_index[i] = 0;
  249. }
  250. short peak1_nums = FindPeak1(data, peak1_index);
  251. short peak2_nums = FindPeak2(data, peak2_index);
  252. // 3.纠正波峰波谷
  253. if (allPeak1_nums[0] ==0 && allPeak2_nums[0] == 0) // 0条记录
  254. {
  255. // peak1
  256. for (i = 0; i < peak1_nums; i++)
  257. {
  258. allPeak1[i] = data[peak1_index[i]];
  259. allPeak1_index[i] = peak1_index[i];
  260. }
  261. allPeak1_nums[0] = peak1_nums;
  262. // peak2
  263. for (i = 0; i < peak2_nums; i++)
  264. {
  265. allPeak2[i] = data[peak2_index[i]];
  266. allPeak2_index[i] = peak2_index[i];
  267. }
  268. allPeak2_nums[0] = peak2_nums;
  269. }
  270. else // 有历史记录
  271. {
  272. short nums;
  273. if (allPeak1_nums[1] == 0 && allPeak2_nums[1] == 0)
  274. {
  275. nums = 1;
  276. }
  277. else if (allPeak1_nums[2] == 0 && allPeak2_nums[2] == 0)
  278. {
  279. nums = 2;
  280. }
  281. else
  282. {
  283. nums = 2;
  284. // 重置peak数据
  285. for (i = 0; i < 100; i++)
  286. {
  287. // peak1
  288. allPeak1[i] = (i < allPeak1_nums[1] + allPeak1_nums[2]) ? (allPeak1[allPeak1_nums[0] + i]) : 0;
  289. allPeak1_index[i] = (i < allPeak1_nums[1] + allPeak1_nums[2]) ? (allPeak1_index[allPeak1_nums[0] + i] - 200) : 0;
  290. // peak2
  291. allPeak2[i] = (i < allPeak2_nums[1] + allPeak2_nums[2]) ? (allPeak2[allPeak2_nums[0] + i]) : 0;
  292. allPeak2_index[i] = (i < allPeak2_nums[1] + allPeak2_nums[2]) ? (allPeak2_index[allPeak2_nums[0] + i] - 200) : 0;
  293. }
  294. for (i = 1; i < 3; i++)
  295. {
  296. allPeak1_nums[i - 1] = allPeak1_nums[i];
  297. allPeak2_nums[i - 1] = allPeak2_nums[i];
  298. }
  299. allPeak1_nums[2] = 0;
  300. allPeak2_nums[2] = 0;
  301. }
  302. // peak1
  303. short base_index1 = 0;
  304. short base_index2 = 0;
  305. for (i = 0; i < nums; i++)
  306. {
  307. base_index1 += allPeak1_nums[i];
  308. base_index2 += allPeak2_nums[i];
  309. }
  310. if (peak1_nums > 0 && peak2_nums > 0)
  311. {
  312. // 如果当前数据的第一个点是波峰,历史的最后一个点也是波峰,则删除当前第一个波峰
  313. if (peak1_index[0]<peak2_index[0] && allPeak1_index[base_index1 - 1]>allPeak2_index[base_index2 - 1])
  314. {
  315. for (i = 1; i < 33; i++)
  316. {
  317. peak1_index[i - 1] = (i < peak1_nums) ? peak1_index[i] : 0;
  318. }
  319. peak1_nums = peak1_nums - 1;
  320. }
  321. for (i = 0; i < peak1_nums; i++)
  322. {
  323. allPeak1[base_index1 + i] = data[peak1_index[i]];
  324. allPeak1_index[base_index1 + i] = peak1_index[i] + 200 * nums;
  325. }
  326. allPeak1_nums[nums] = peak1_nums;
  327. }
  328. // peak2
  329. if (peak1_nums > 0 && peak2_nums > 0)
  330. {
  331. // 如果当前数据的第一个点是波谷,历史的最后一个点也是波谷,则删除当前第一个波谷
  332. if (peak1_index[0]>peak2_index[0] && allPeak1_index[base_index1 - 1]<allPeak2_index[base_index2 - 1])
  333. {
  334. for (i = 1; i < 33; i++)
  335. {
  336. peak2_index[i - 1] = (i < peak2_nums) ? peak2_index[i] : 0;
  337. }
  338. peak2_nums = peak2_nums - 1;
  339. }
  340. for (i = 0; i < peak2_nums; i++)
  341. {
  342. allPeak2[base_index2 + i] = data[peak2_index[i]];
  343. allPeak2_index[base_index2 + i] = peak2_index[i] + 200 * nums;
  344. }
  345. allPeak2_nums[nums] = peak2_nums;
  346. }
  347. }
  348. // 4.删除开头和结尾的波峰点
  349. short peak1_total;
  350. short peak2_total;
  351. peak1_total = allPeak1_nums[0] + allPeak1_nums[1] + allPeak1_nums[2];
  352. if (allPeak1_index[0] < allPeak2_index[0]) // 开头
  353. {
  354. for (i = 1; i < 100; i++)
  355. {
  356. allPeak1_index[i - 1] = (i < peak1_total) ? allPeak1_index[i] : 0;
  357. allPeak1[i - 1] = (i < peak1_total) ? allPeak1[i] : 0;
  358. }
  359. allPeak1_nums[0] = allPeak1_nums[0] - 1;
  360. }
  361. peak1_total = allPeak1_nums[0] + allPeak1_nums[1] + allPeak1_nums[2];
  362. peak2_total = allPeak2_nums[0] + allPeak2_nums[1] + allPeak2_nums[2];
  363. if (allPeak1_index[peak1_total-1] > allPeak2_index[peak2_total -1]) // 结尾
  364. {
  365. for (i = 0; i < 100; i++)
  366. {
  367. allPeak1_index[i] = (i < peak1_total - 1) ? allPeak1_index[i] : 0;
  368. allPeak1[i] = (i < peak1_total - 1) ? allPeak1[i] : 0;
  369. }
  370. if (allPeak1_nums[1] == 0 && allPeak2_nums[1] == 0)
  371. {
  372. allPeak1_nums[0] = allPeak1_nums[0] - 1;
  373. }
  374. else if (allPeak1_nums[2] == 0 && allPeak2_nums[2] == 0)
  375. {
  376. allPeak1_nums[1] = allPeak1_nums[1] - 1;
  377. }
  378. else
  379. {
  380. allPeak1_nums[2] = allPeak1_nums[2] - 1;
  381. }
  382. }
  383. // 5.计算步数
  384. short step = 0;
  385. peak1_total = allPeak1_nums[0] + allPeak1_nums[1] + allPeak1_nums[2];
  386. peak2_total = allPeak2_nums[0] + allPeak2_nums[1] + allPeak2_nums[2];
  387. if (peak1_total< peak2_total)
  388. {
  389. for (i = 0; i < peak1_total; i++)
  390. {
  391. short distance1 = allPeak2_index[i + 1] - allPeak2_index[i];
  392. short distance2 = allPeak1[i] - allPeak2[i];
  393. if (distance1 > 25 && distance2 > 3000)
  394. {
  395. step += 1;
  396. }
  397. }
  398. }
  399. // 6.判断结果,2-跑步,0-非跑步
  400. short pred=0;
  401. pred = (step >= 5) ? 2 : 0;
  402. return pred;
  403. }
  404. void main()
  405. {
  406. float arr[] = { 3526, 3104, 2735, 2496, 2421, 2443, 2434, 2341, 2247, 2294, 2565, 3082, 3764, 4497, 5083, 5355, 5457, 5624, 5996, 6515, 6919, 7095, 7147, 7157, 7079, 6848, 6440, 5927, 5431, 4994, 4574, 4082, 3445, 2707, 2011, 1473, 1125, 877, 657, 471, 366, 417, 688, 1129, 1691, 2405, 3044, 3444, 3728, 3617, 3596, 6522, 11834, 13959, 12571, 10776, 9181, 7522, 6433, 5821, 5226, 4994, 4928, 4797, 4640, 4284, 3752, 3082, 2433, 2075, 1797, 1849, 2122, 2317, 2417, 2472, 2730, 3188, 3670, 4428, 5278, 5771, 6141, 6547, 6697, 6637, 6633, 6645, 6598, 6353, 5951, 5614, 5379, 5089, 4650, 4119, 3573, 3058, 2640, 2381, 2223, 2048, 1857, 1683, 1519, 1413, 1438, 1703, 2164, 2686, 3216, 3803, 4583, 5426, 6212, 6935, 7361, 7461, 7473, 7445, 7429, 7485, 7357, 6849, 6105, 5352, 4722, 4172, 3661, 3242, 2910, 2629, 2403, 2285, 2248, 2200, 2082, 1934, 1881, 2082, 2567, 3205, 3923, 4644, 5200, 5628, 6095, 6578, 6887, 7054, 7265, 7379, 7255, 6996, 6710, 6420, 6116, 5762, 5366, 4919, 4343, 3642, 2953, 2381, 1974, 1713, 1564, 1492, 1447, 1456, 1640, 2070, 2715, 3473, 4266, 5095, 5915, 6695, 7528, 8251, 8488, 8230, 7778, 7348, 6950, 6546, 6019, 5344, 4692, 4182, 3766, 3363, 2952, 2598, 2376, 2245, 2160, 2090, 2035, 2041 };
  407. // 100*2*4+136*2*2+200*4=2148字节 -100*2*4-100*2*2=948字节
  408. float allPeak1[100] = { 0 };
  409. short allPeak1_index[100] = { 0 };
  410. short allPeak1_nums[3] = { 0 };
  411. float allPeak2[100] = { 0 };
  412. short allPeak2_index[100] = { 0 };
  413. short allPeak2_nums[3] = { 0 };
  414. short peak1_index[33] = { 0 };
  415. short peak2_index[33] = { 0 };
  416. float data[200] = { 0 };
  417. for (short i = 0; i < 4; i++)
  418. {
  419. short label = RunStateDetection(arr, data, peak1_index, peak2_index, allPeak1, allPeak1_index, allPeak1_nums, allPeak2, allPeak2_index, allPeak2_nums);
  420. printf("label: %d\n",label);
  421. }
  422. }

状态识别_随机森林模型

load_model.c

  1. #include<stdio.h>
  2. #include "opencv2/core/core.hpp"
  3. #include "opencv2/ml/ml.hpp"
  4. #include <cstdio>
  5. #include <vector>
  6. #include <iostream>
  7. using namespace std;
  8. using namespace cv;
  9. using namespace cv::ml;
  10. // n维vector转mat
  11. Mat vector2Mat(vector<vector<float>> src)
  12. {
  13. int feature_nums = int(src.size()*src[0].size());
  14. Mat test(1, feature_nums, CV_32FC1); // CV_64FC1 1*200
  15. for (int i = 0; i < src.size(); ++i) {
  16. for (int j = 0; j < src[0].size(); j++)
  17. {
  18. int index = i * src[0].size() + j;
  19. test.at<float>(0, index) = src[i][j];
  20. }
  21. }
  22. return test;
  23. }
  24. // 数据输入为vector
  25. int StateEstimate(vector<vector<float>> acc, vector<vector<float>> gyr, vector<float> ppg, cv::Ptr<cv::ml::RTrees> model)
  26. {
  27. // 挑出测试数据
  28. vector<vector<float>> all_data;
  29. vector<float> az;
  30. for (int i = 0; i < acc.size(); i++)
  31. {
  32. az.push_back(acc[i][2]);
  33. }
  34. all_data.push_back(az);
  35. // 数据转换,vector转mat
  36. Mat test_data;
  37. test_data =vector2Mat(all_data);
  38. // 判断测试数据的特征维度是否正确,不正确返回-2
  39. if (test_data.cols != 200)
  40. {
  41. return -2;
  42. }
  43. // 模型预测
  44. cv::Mat res;
  45. model->predict(test_data, res);
  46. // 预测结果判断是否为空
  47. if (res.empty()) {
  48. return -1;
  49. }
  50. // 输出动作分类情况:-1-预测empty,-2-测试数据特征维度错误,0-非跑步,2-跑步
  51. int action = (int)(res.at<float>(0, 0));
  52. if (action==2)
  53. {
  54. return 2;
  55. }
  56. return 0;
  57. }
  58. int main() {
  59. 定义数据
  60. vector<vector<float>> acc;
  61. for (int i = 0; i < 200; i++)
  62. {
  63. vector<float>data;
  64. for (int j = 0; j < 3; j++)
  65. {
  66. data.push_back(i * 3 + j);
  67. }
  68. acc.push_back(data);
  69. }
  70. vector<vector<float>> gyr;
  71. for (int i = 0; i < 200; i++)
  72. {
  73. vector<float>data;
  74. for (int j = 0; j < 3; j++)
  75. {
  76. data.push_back(i * 3 + j);
  77. }
  78. gyr.push_back(data);
  79. }
  80. vector<float> ppg;
  81. for (int i = 0; i < 200; i++) {
  82. ppg.push_back(i);
  83. }
  84. // 模型加载
  85. cv::Ptr<cv::ml::RTrees> model = cv::ml::RTrees::load("svm-az.xml");
  86. // 模型预测:-1-预测empty,-2-测试数据特征维度错误,0-静止 ,1-走路
  87. int pred=StateEstimate(acc, gyr, ppg, model);
  88. std::cout << "预测结果为:" << pred << std::endl;
  89. }

声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号