Skip to content

Instantly share code, notes, and snippets.

@ifq
Created July 5, 2013 06:47
Show Gist options
  • Save ifq/5932464 to your computer and use it in GitHub Desktop.
Save ifq/5932464 to your computer and use it in GitHub Desktop.
根据脉搏电压数据检测心跳的程序
/* ifqqfi在gmail.com
* [2013-07-05 五]
*
* 脉搏检测程序
*/
#include <stdio.h>
#include <stdlib.h>
/* 临时这个么搞,读数据的缓冲区大小 */
#define MAX_LEN 999999
/* 每秒采样次数,根据实际系统的采样率调整 */
#define SCAN_FREQ 78
/* 快速射血期 的扫描次数 */
#define QUICK_BLOOD_INJECT ((int)(SCAN_FREQ * 0.11))
/* 检测到一次之后的跳跃点数 */
#define JUMP_INTERVAL ((int)(SCAN_FREQ * 0.382))
/* 过滤用的门限值 */
#define THRESH_RATE (float)(1 - 0.618)
#define DBG_SW 1
#ifdef DBG_SW
int cnt_diff_under = 0;
int cnt_range_under = 0;
#endif
/* 读取文件的buff */
float alldata[MAX_LEN];
int inline is_diff_peak(float *diff, int pos, float thr_max)
{
float tmp;
float *iter;
int i;
if (*(diff + pos) < thr_max) {
#ifdef DBG_SW
cnt_diff_under++;
#endif
return 0;
}
iter = diff + pos - (int)(QUICK_BLOOD_INJECT / 2);
tmp = 0;
for (i = 0; i < QUICK_BLOOD_INJECT; ++i, ++iter) {
tmp += *iter;
}
tmp /= QUICK_BLOOD_INJECT;
if (tmp < thr_max) {
#ifdef DBG_SW
//printf ("pos =%d, tmp = %f\n", pos, tmp);
cnt_range_under++;
#endif
return 0;
}
return 1;
}
/* http://ifq.github.io */
int rhythmcount(float *fifo , int len)
{
int i;
float *diff; /* 导数缓冲区 */
float dif_max=0; /* 导数最大值 */
float thr_max; /* 导数阀值 */
int j=0;
int k[1000]; /* 用于存放最大值位置,有多少心跳次数就用多少 */
int rhythm;
float DR_R; /* 心跳间隔的采样点数品均值 */
//printf ("len = %d\n", len);
diff = malloc(sizeof(float) * (len+2));
if (!diff) {
perror("malloc fail\n");
return (-1);
}
*diff=0; /* 头两个字节置0 */
*(diff+1)=0;
/* 按DIFF(i)=f(i+1)-f(i-1)+2*f(i+2)-2*f(i-2)公式计算导数 */
for (i=2;i<len-2;i++)
{
*(diff+i) = (*(fifo+i+1)) + 2 * (*(fifo+i+2))
- (*(fifo+i-1)) - 2 * (*(fifo+i-2));
if ((dif_max) < *(diff+i)) {
dif_max=*(diff+i);
}
}
*(diff+len-1)=0; /* 置0 */
*(diff+len)=0;
thr_max=dif_max * THRESH_RATE; //设定阈值
#ifdef DBG_SW
printf ("max dif=%f, thr=%f\n", dif_max, thr_max);
#endif
/* 检测 */
for (i = 1; i < len - 2; i++)
{
if (is_diff_peak(diff, i, thr_max)) {
k[j++]=i;
i += JUMP_INTERVAL;
}
}
DR_R=(k[j-1]-k[0])/(float)(j-1); //计?算?R-R间?距¨¤
printf ("dr_r %f, j=%d, gap=%d \n", DR_R, j, k[j-1]-k[0]);
rhythm=(len/DR_R); //通ª¡§过y公?式º?200*60/DR-R求¨®得Ì?心?率¨º值¦Ì
free(diff);
return rhythm;
}
/* ifqqfi */
int main(int argc, char **argv)
{
float tmp;
int reallen = 0;
int totlebeat;
float time;
if (argc < 3) {
printf ("argc not enough!\n");
exit(-1);
}
time = atof(argv[2]);
FILE *fp = fopen(argv[1],"r");
while (fscanf(fp, "%f", &tmp) != EOF) {
alldata[reallen++] = tmp > 255 ? 255 : tmp;
}
fclose(fp);
#if 0
for (i = 0; i < reallen; ++i) {
printf ("%f\n", alldata[i]);
}
#endif
totlebeat = rhythmcount(alldata, reallen);
#ifdef DBG_SW
printf("dbg diff=%d, range=%d\n",cnt_diff_under, cnt_range_under);
#endif
/* http://iwood.co.nr */
printf("total beat = %d, rate = %f\n", totlebeat, totlebeat/time);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment