基于mindwave脑电波进行疲劳检测算法的设计(4)
上一次的实验做到可以从pc端读取到MindWave传输过来的脑电波原始数据了。
我是先定义一个结构体,该结构体对应保存所有能从硬件中取到的原始数据。
struct FD_DATA
{
int battery;//电量
int poor_signal;//连接质量
int attention;//专注度
int meditation;//冥想度
int raw;//原始数据
int delta;//δ波段
int theta;//θ脑波
int alpha1;//α脑波
int alpha2;//α脑波
int beta1;//β脑波
int beta2;//β脑波
int gamma1;//γ脑波
int gamma2;//γ脑波
int blink;//眨眼强度
};
读取的函数为
struct FD_DATA FD_GetData(int conID)
{
struct FD_DATA data;
TG_ReadPackets(conID,);//一次读取多个,否则在多线程中会因为某些数据包在缓存中而没有读取
data.battery=TG_GetValue(conID,TG_DATA_BATTERY);
data.poor_signal=TG_GetValue(conID,TG_DATA_POOR_SIGNAL);
data.attention=TG_GetValue(conID,TG_DATA_ATTENTION);
data.meditation=TG_GetValue(conID,TG_DATA_MEDITATION);
data.raw=TG_GetValue(conID,TG_DATA_RAW);
data.delta=TG_GetValue(conID,TG_DATA_DELTA);
data.theta=TG_GetValue(conID,TG_DATA_THETA);
data.alpha1=TG_GetValue(conID,TG_DATA_ALPHA1);
data.alpha2=TG_GetValue(conID,TG_DATA_ALPHA2);
data.beta1=TG_GetValue(conID,TG_DATA_BETA1);
data.beta2=TG_GetValue(conID,TG_DATA_BETA2);
data.gamma1=TG_GetValue(conID,TG_DATA_GAMMA1);
data.gamma2=TG_GetValue(conID,TG_DATA_GAMMA2);
data.blink=TG_GetValue(conID,TG_DATA_BLINK_STRENGTH);
if(data.poor_signal<=)
{
ErrorNo=;
data.poor_signal=;
return data;
}
return data;
}
对于获取数据的时间间隔,就有可能有不同的取法了,理论上是时时刻刻的取值的。但是,这样就太占系统cpu了,那到底是多少时间取一次数据比较好呢,我试着1ms,10ms,100ms,500ms,1s,5s等不同的取数据,然后分析。在TG_BAUD_9600波特率情况下大概每500ms各个值就会有变化。
下面这个图是我在100ms取一次数据获得的
分别对应 attention meditation raw delta theta alpha1 alpha2 ... ... 可以可以看到所有有效的数据大概都是5次一次刷新,而其中的raw列就每次都刷新,这个raw波段,我们此次不会涉及到,只是说明每次都是有实际从硬件取到值的。
对于取多少比较好呢,我再进行测试的时候是1s取一次。(我觉得如果该算法用于实际,觉得这个取值的时间间隔可以再大一点。)这里我们就会有一个疑问了,每次从硬件中取到的数都不一样,我们1s取一次的话,会不会丢失疲劳信息的有效数据呢。还有就是,按道理人脑是时时刻刻都再发射脑电波的。如果准确的说,1s有无数次采样的话,会有无数种结果。到底为什么可以1s取一次,5s取一次呢?(Ps:这个时间间隔叫做采样间隔)。
这个问题困扰我很长时间了,到最近才知道为什么。这个跟时域和频域有关。还有什么傅立叶等等概念有关。
音乐——其实就是时/频分析的一个极好例子,乐谱就是音乐在频域的信号分布,而音乐就是将乐谱变换到时域之后的函数。从音乐到乐谱,是一次傅立叶或小波变换;从乐谱到音乐,就是一次傅立叶或小波逆变换。
关于这方面的知识我也似懂非懂的。我也不好解释。反正就是最后对结果的影响不会很大,基本没有影响。还有一点,那个脑电波耳机内部其实还是有做了一些处理的。具体的处理也是上面提到的各种很复杂的级数变换吧。
(^-^)?有点跑题了,接下来就是对取到的数据进行绘图分析。为了看图的方便,我这里只画出attention和meditation的曲线,其他的类似。
我们截取其中的一段,可以看到,这些线波动很大,基本看不到有效的关系。
我这里采用两种办法进行预处理。用两种办法是为了反正在进行预处理的时候把有效的信息给处理掉了。所以要两种办法,然后这两种办法再进行一个相关性的假设检验。
1.第一种办法是使用常用的办法,就是采用滑动窗口。原理就是这个点的取值是通过计算左右的值的平均值。然后来确定这个值的。这样就能保证是相对稳定的显示了。
2.第二种办法是采用自己叫做补偿算法的。原理就是下一个点的值由上一个点来确定,下一个点取当前该点的值减去上一次的值的六十分之一再加上前一个点的值。(思路是这样就能确保每次的增加或减少都是在可控的返回内,每次只是对前一个值的修修补补,不会有大的变化,这一点在接下来的图中可以看出)。还有就是为什么是六十分之一其实百分之一,千分之一。数量级越小,表示受时间影响越大。不同环境该数值应该不同。
第二种办法作用是检验attention和meditation在滑动窗口和补偿算法中是否有显著性相关,我们采用 基于成对数据的假设检验(t检验),来确定滑动窗口这个算法对数据的预处理的有效的,并不会破坏数据的有效信息。如果有显著性相关的话就说明第一种办法是可行的,那么,以后的处理就可以这是一种方法的预处理就可以了。
得到的是这样的效果,分别是attention两条曲线,meditation两条曲线。这样看就比较正常了,不像上面那样没有规律。我们这样一眼望过去就可以知道两种办法取得的曲线是有点相关性的。作为一个专业的人来说,仅仅靠目测法是不行的。我们要怎样解决呢?这里就要用到t检验了。这个是概率论与数理统计方面的。这个课是大二学的,具体的都忘了,当时也没有怎么认真的学。现在看到这个问题就后悔当初没有认真听课了。(这里插一句,不能不想起当年大一的时候一个ACM的师兄说的一句话“你们是不是觉得大学的高数学了没有用,那是你们还没有到用到它的水平。”当时的理解是这是一个学霸师兄赤果果的嘲讽。现在想想也是有道理的。那个线性代数我是学那个矩阵快速幂算法的时候有用到,而这里的t检验是第一次实际例子中用到数理统计的。而前面提到的傅立叶是在高数中有提到的。如果时间可以倒流,回到那个时候,你还会不会认真的对待这些数学。我肯定的回答,应该还是不会。)
d’是样本均值 Sd是样本方差 n是样本个数 α是置信区间 具体其他的就自己看书了。
还是给出代码比较好理解吧
//基于成对数据的假使检验
double FD_t_check_pair(double * x,double * y,int size)
{
double * d;
double avg=0.0;//用于计算平均数
double sd=0.0;//用于保存方差
int i,j;
d=(double *)malloc(size*sizeof(double));
for(i=;i<size;i++)
{
d[i]=x[i]-y[i];
avg=avg+d[i];
}
avg=avg/size;
sd=0.0;
for(i=;i<size;i++)
{
sd=sd+((avg-d[i])*(avg-d[i]));
}
sd=sd/(size-);
printf("sd=%lf\n",sd);
double t;
t=fabs(avg/(sd/sqrt(size)));
free(d);
return t;
}
我得出的结论是在置信区间a=0.025 n=500 是attention和meditation对应的t值都是小于2.4的,说明观察值|t| 不落在拒绝域内,故接受H假使,认为使用两种预处理得到的结果无显著差异。
好了,这一节就到这里了,有什么错误欢迎指出。下一节将讲述 αβθ之间的关系,对人体的疲劳状态是否有明显的相关性。这一步将通过这些关系与硬件提供的attention值和meditation值进行相关性检验,来确定硬件给出的值是否有效,还有通过对人的具体实验进行分析。总体代码现在比较乱,就先不给出了,等以后有机会整理完再发吧。
参考资料:
概率论与数理统计及其应用 (高等教育出版社) (盛 骤 谢式千)
还有一个音乐的例子,网上都是写转载,但没有给出出处,我就不好写了。
本文链接:http://www.cnblogs.com/wunaozai/p/3766779.html
基于mindwave脑电波进行疲劳检测算法的设计(4)的更多相关文章
- 基于mindwave脑电波进行疲劳检测算法的设计(5)
时隔两个多月了,前段时间在弄Socket,就没有弄这个了.现在好了,花了几天的时间,终于又完成了一小部分了.这一小节主要讲α,β,δ,θ等等波段之间的关系.废话不多说,直接给出这几天的成果. 上一次, ...
- 基于mindwave脑电波进行疲劳检测算法的设计(1)
一.简介 脑波,又称之为脑电波,是人大脑发出的电波,非常的微弱,只能通过设备来检测.人的脑波在不同状态下,会不同,因此可以通过脑波来量化分析人的精神状态. 科学家讲脑电波分为四种,以下为详细解释 (1 ...
- 基于mindwave脑电波进行疲劳检测算法的设计(2)
上文讲到的是保证硬件的接通.接下来是用C语言在它提供的API接口进行连接. 在网盘中下载MindSet Development Tools这个开发包.这个目录下MindSet Development ...
- 基于mindwave脑电波进行疲劳检测算法的设计(3)
这一节我将讲解thinkgear.h 里面的函数和宏定义.这一些都可以在MindSet Development Tools\ThinkGear Communications Driver\docs\h ...
- 基于深度学习的目标检测算法:SSD——常见的目标检测算法
from:https://blog.csdn.net/u013989576/article/details/73439202 问题引入: 目前,常见的目标检测算法,如Faster R-CNN,存在着速 ...
- 基于Shading Model(对光照变化一定不变性)的运动目标检测算法
光照模型(Shading Model)在很多论文中得到了广泛的应用,如robust and illumination invariant change detection based on linea ...
- 基于候选区域的深度学习目标检测算法R-CNN,Fast R-CNN,Faster R-CNN
参考文献 [1]Rich feature hierarchies for accurate object detection and semantic segmentation [2]Fast R-C ...
- 【计算机视觉】基于Shading Model(对光照变化一定不变性)的运动目标检测算法
光照模型(Shading Model)在很多论文中得到了广泛的应用,如robust and illumination invariant change detection based on linea ...
- 【计算机视觉】基于样本一致性的背景减除运动目标检测算法(SACON)
SACON(SAmple CONsensus)算法是基于样本一致性的运动目标检测算法.该算法通过对每个像素进行样本一致性判断来判定像素是否为背景. 算法框架图 由上图可知,该算法主要分为四个主要部分, ...
随机推荐
- KAFKA的安装使用
一:介绍 1.官网 kafka.apache.org 2.产生 Kafka由 linked-in 开源 kafka-即是解决上述这类问题的一个框架,它实现了生产者和消费者之间的无缝连接. kafk ...
- Unity报错 : BCE0004: Ambiguous reference 'preview': CameraMotionBlurEditor.preview, UnityEditor.Editor.preview.
建立项目版本为Unity4.6,改为5.3.4版本,运行项目报如下错误: “BCE0004: Ambiguous reference 'preview': CameraMotionBlurEditor ...
- 附001.Docker阿里云Registry加速器配置
一 安装配置docker 1.1 安装docker 见<002.docker版本及安装>. 1.2 配置国内阿里云加速器 见<002.docker版本及安装>. 二 配置阿里云 ...
- spring整合ssmXML版
以下是一个简单的ssm项目:如果中途报错,肯定是tomcat配置或者数据库配置有问题,在程序中注意将包名等配置换成自己的.数据库表需要提前建好,并加入数据,注意表结构要和实体对象对应. 1.开发条件: ...
- LoRaWAN 1.1 网络协议规范 - 3 物理层帧格式
LoRaWAN 1.1 网络协议规范 LoRaWAN 1.1 版本封稿很久了也没有完整啃过一遍,最近边啃边翻译,趁着这个机会把它码下来. 如果觉得哪里有问题,欢迎留言斧正. 翻译不易,转载请申明出处和 ...
- Node+Express+MongoDB+Socket.io搭建实时聊天应用实战教程(一)--MongoDB入门
前言 本文并不是网上流传的多少天学会MongoDB那种全面的教程,而意在总结这几天使用MongoDB的心得,给出一个完整的Node+Express+MongoDB+Socket.io搭建实时聊天应用实 ...
- AGC027 A - Candy Distribution Again
目录 题目链接 题解 代码 题目链接 AGC027 A - Candy Distribution Again 题解 贪心即可 代码 #include<cstdio> #include< ...
- C# 的枚Enum
简短的解释: enum 关键字用来声明枚举,一种包含一组被称为枚举数列表的 enum myType{ a, b, c,} int num = 1;Console.Write((myType)num); ...
- C# Invoke方法
留下备用,具体如下: Invoke()方法是U3D的一种委托机制: 1.它可以在脚本的生命周期(Start.Update.OnGUI.FixedUpdate.LateUpdate)中调用. 2.Inv ...
- api日常总结
异步加载JS和CSS <script type="text/javascript"> (function () { var s = document.createEle ...