如何处理眼动仪噪声数据?需保留有效分组并标记其余数据
眼动数据有效分组保留与噪声处理方案(基于Tobii框架)
核心思路
要实现仅保留有效数据分组、噪声数据用圆圈标记的需求,需先明确有效数据的判定规则,再对采集到的(x,y)数据做实时过滤、分组,最后分别处理有效数据和噪声数据。
步骤1:定义有效数据判定规则
结合眼动数据特性,我们采用「Tobii内置有效性标记+自定义偏移阈值」的判定方式:
- 优先使用Tobii提供的
isValid参数判断数据是否为有效眼动点 - 对有效点额外校验连续点间的坐标偏移,过滤抖动过大的噪声
步骤2:修改代码实现逻辑
替换原有的gazePointDataStream处理逻辑,整合有效分组、噪声标记的完整代码如下:
sw.WriteLine("X(pixel),Y(pixel),time_now,timer,data_type"); var gazePointDataStream = host.Streams.CreateGazePointDataStream(Tobii.Interaction.Framework.GazePointDataMode.LightlyFiltered); // 有效数据缓存,用于构建连续分组 List<(double x, double y, DateTime time)> validDataGroup = new List<(double, double, DateTime)>(); const int minGroupSize = 5; // 有效分组的最小点数 const double maxPixelOffset = 40; // 同组内连续点的最大偏移阈值 gazePointDataStream.GazePoint((x, y, timestamp, isValid) => // 启用Tobii内置有效性参数 { if (!enableGazeMouseControl) return; var currentTime = DateTime.Now; bool isCurrentValid = isValid && !double.IsNaN(x) && !double.IsNaN(y); if (isCurrentValid) { // 检查当前点是否能加入现有有效分组 if (validDataGroup.Count > 0) { var lastPoint = validDataGroup.Last(); double offsetX = Math.Abs(x - lastPoint.x); double offsetY = Math.Abs(y - lastPoint.y); if (offsetX <= maxPixelOffset && offsetY <= maxPixelOffset) { validDataGroup.Add((x, y, currentTime)); } else { // 现有分组达到最小规模则保存,否则直接丢弃 if (validDataGroup.Count >= minGroupSize) { foreach (var point in validDataGroup) { sw.WriteLine($"{point.x:F2},{point.y:F2},{point.time},{form.label5.Text},valid"); } } // 重置分组,加入当前点 validDataGroup.Clear(); validDataGroup.Add((x, y, currentTime)); } } else { validDataGroup.Add((x, y, currentTime)); } // 有效数据直接控制光标并更新显示 moveCursor((int)x, (int)y); form.label3.Invoke((MethodInvoker)(() => form.label3.Text = x.ToString("F2"))); form.label4.Invoke((MethodInvoker)(() => form.label4.Text = y.ToString("F2"))); } else { // 噪声数据:绘制蓝色圆圈标记,不控制光标,记录为噪声 if (!double.IsNaN(x) && !double.IsNaN(y)) { form.Invoke((MethodInvoker)(() => { using (Graphics g = form.CreateGraphics()) { g.FillEllipse(new SolidBrush(Color.Blue), (int)(x - 5), (int)(y - 5), 10, 10); // 放大圆圈区分噪声 } })); sw.WriteLine($"{x:F2},{y:F2},{currentTime},{form.label5.Text},noise"); } } // 程序关闭时检查剩余未保存的有效分组 form.FormClosing += (s, e) => { if (validDataGroup.Count >= minGroupSize) { foreach (var point in validDataGroup) { sw.WriteLine($"{point.x:F2},{point.y:F2},{point.time},{form.label5.Text},valid"); } } }; });
关键优化点说明
- 有效分组管理:通过缓存连续有效点,筛选出符合偏移阈值、达到最小点数的分组才保存,避免零散有效点被误判为噪声
- 噪声可视化:无效数据用放大的蓝色圆圈标记,和有效数据的光标操作做明确区分
- 资源优化:使用
using语句自动释放Graphics资源,避免内存泄漏 - 数据可追溯:CSV新增
data_type字段,明确标记有效/噪声数据,方便后续分析 - 精度提升:坐标显示保留两位小数,提升可读性
可调参数说明
minGroupSize:有效分组的最小点数,可根据眼动停留时长需求调整maxPixelOffset:同组内连续点的最大偏移阈值,数值越小过滤噪声的强度越高
内容的提问来源于stack exchange,提问作者Taisir Alhilo
相关产品推荐
相关产品推荐

