基于python 自写Tobii VI-T滤波器

2023-11-15

官网参考文档

Tobii的默认注视点滤波器是I-VT,官方给出了参考文档《The Tobii I-VT Fixation Filter》。今天学习了一下,这里做个笔记。
主要看第三小节“The Tobii Studio implementation of the Tobii I-VT filter”的内容,简单概述I-VT滤波器的基本操作流程:内插fixations=>眼动位置确定=>降噪处理=>速度计算=>分类=>临近注视区合并。
整个流程的关键参数就在下面这张图中,下面分别介绍具体操作流程:
在这里插入图片描述

Gap fill-in interpolation

主要目的是将一些missing的fixations通过内插的方式填补上,关键的参数‘Max gap length’。为避免将一些由于被试眨眼,转头和遮挡等非采取误差导致数据填补,系统默认设置Max gap length小于正常眨眼的时间,一般为75mm。(通常2~6秒就要眨眼一次,每次眨眼要用0.2~0.4秒钟时间
对于数据的填补就是简单线性内插即可。
在这里插入图片描述

Eye selection

相对很好理解,由于采集的两只眼的眼动信息,需要选取以哪只眼的fixations位置为准。可选择的有左右眼,以及平均。我们选择avarage就好,即两只眼都采集到数据时去两者位置的平均,只有一只眼时只取一只眼的数据。

Noise reduction

Tobii采用的non-weighted moving-average filter,也是一个很好理解的滤波方式,即连续取某一个时刻前N和后N个样本点,取平均位置。

y [ n ] = 1 2 ∗ N + 1 ∑ k = − N N x [ n − k ] y[n]=\frac{1}{2 * N+1} \sum_{k=-N}^{N} x[n-k] y[n]=2N+11k=NNx[nk]
显然样本点的个数将直接影响fixations的位置曲线,样本点越多曲线越平滑,对应的眼动速度也越低。这样操作虽然能消除噪音的影响也会对影响数据准确度,所以需要合适选取数据。
采样时间间隔乘以N需要远小于眼跳的时间间隔。
在这里插入图片描述
相比均值降噪,中位数降噪能减少对过度区域的过平滑操作。
在这里插入图片描述

Velocity calculator

为方便分类阈值的设定,这里眼动速度一般采用视角,桌面式的眼动仪器因为知道被试与刺激物的纵向距离,视角便可以方便计算得到。
在这里插入图片描述
视角速度的计算就是两个注视点的距离除以一个时间间隔,其中window length需要进行合理设置,经验选取20ms可以有效降噪且避免打乱数据。

v t 1 t 2 = ∣ s t 1 − s t 2 ∣ ∣ t 1 − t 2 ∣ v_{t_{1} t_{2}}=\frac{\left|s_{t_{1}}-s_{t_{2}}\right|}{\left|t_{1}-t_{2}\right|} vt1t2=t1t2st1st2

I-VT classifier

接下来就是根据velocity threshold对注视点进行分类了,默认设置为30°/s。但是根据数据的信噪比,需要合理调整阈值。每秒的眼跳次数为2-5次,眼跳持续时间10-100ms,一次注视的时间约200-500ms,可据此检验阈值设置的可靠性。比如下图左侧,噪声较多,阈值需要设置大一些,右侧噪声少,阈值设当设置小一些。
在这里插入图片描述

Merge adjacent fixations

对于临近的注视点处理,主要基于三个参数:
max time between fixations: 75ms(大约75超过眼跳,应该时眨眼等行为)
max angle between fixations: 0.5°(小于这个数值,合并)
merge adjacent fixations: 60ms (小于一次注视的时长合并)
意思都很好理解了,提出的机理是根据文献中人的行为特点决定的,比如最后一个参数注视时长是人视觉观察物体,并提取关键信息所必须的最短时长。
至此便完成了对眼动数据的滤波处理。

官方文档

https://www.tobiipro.com/learn-and-support/learn/steps-in-an-eye-tracking-study/data/how-are-fixations-defined-when-analyzing-eye-tracking-data/

python 代码

粗略写了一个,后续再更新

import matplotlib as mpl 
import glob, os, cv2, time
import json, csv, math
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from scipy import signal
import matplotlib.gridspec as gridspec
import matplotlib

matplotlib.rcParams['font.size'] = 16
matplotlib.rcParams['figure.titlesize'] = 16
# matplotlib.rcParams['figure.figsize'] = figsz
matplotlib.rcParams['font.family'] = ['Times New Roman']
matplotlib.rcParams['axes.unicode_minus']=False

def read_json(json_file):
    with open (json_file, 'r') as f:
        res_data = json.load(f)
    return res_data

def get_fixation_list(fixation_dict):
    # 删除最后一帧画面的眼动
    fixation_dict.pop('frame{:0>6}'.format(len(fixation_dict)-1))
    fixations=[]
    for key, fix in fixation_dict.items():
        fixations.extend(fix)
    return fixations

class Tobii_IVT_filter():
    '''
    filter_mode: fixation/attention/user_define
    '''
    def __init__(self, sample_fps,filter_mode, 
                seating_dis=650, screen= (527.1, 296.5),
                resolution=[1280,720], **filter_kwargs):
        self.sample_fps = sample_fps
        self.filter_mode=filter_mode
        self.seat_dis = seating_dis
        self.resolution=resolution
        self.screen_w = screen[0]
        self.screen_h = screen[1]

        if filter_mode=='fixation':
            self.fixation_filter()
        elif filter_mode=='attention':
            self.attention_filter()
        else:
            self.user_defined_filter(**filter_kwargs)

    def fixation_filter(self, ):
        self.max_gap_length=75
        self.noise_window_size=3
        self.velocity_window_size=20
        self.velocity_threshold=30
        self.merge_max_time=75
        self.merge_max_angle=0.5
        self.discard_min_duration=60

    def attention_filter(self, ):
        self.max_gap_length=75
        self.noise_window_size=3
        self.velocity_window_size=20
        self.velocity_threshold=100
        self.merge_max_time=75
        self.merge_max_angle=0.5
        self.discard_min_duration=60
    
    def user_defined_filter(self, **filter_kwargs):
        self.max_gap_length=filter_kwargs['max_gap_length']
        self.noise_window_size=filter_kwargs['noise_window_size']
        self.velocity_window_size=filter_kwargs['velocity_window_size']
        self.velocity_threshold=filter_kwargs['velocity_threshold']
        self.merge_max_time=filter_kwargs['merge_max_time']
        self.merge_max_angle=filter_kwargs['merge_max_angle']
        self.discard_min_duration=filter_kwargs['discard_min_duration']

    def filter_process(self,fixations):
        fixations_gap=self.GapFill(fixations)
        fixations_merge=self.MovingMedian(fixations_gap)
        
        # self.scatter_plot1([np.array(fixations), np.array(fixations_gap),
        #                 np.array(fixations_merge)])

        velocity_list = self.VelocityCal(fixations_merge)
        self.scatter_plot2(velocity_list)
        self.FixClassifier(fixations_merge, velocity_list)
    
    def GapFill(self, fixations):
        # 小于interval_num 需要内插
        interval_num = self.sample_fps*self.max_gap_length/1000
        fix_len = len(fixations)
        nan_index = np.isnan(fixations)[:,0]
        
        # FT定义为开始 TF定义为结束
        start_idx, end_idx = [], []
        for ii in range(fix_len-2):
            if (nan_index[ii] == False) & \
                (nan_index[ii+1] == True) :
                start_idx.append(ii)
            if (nan_index[ii] == True) & \
                (nan_index[ii+1] == False):
                end_idx.append(ii)
        for start, end in zip(start_idx, end_idx):
            # print('start_idx:{}, end_idx:{}'.format(start, end), \
            #     nan_index[start:end+2])
            # print('start_idx:{}, end_idx:{}'.format(start, end), \
            #     'fixation_array:',fixations[start:end+2])
            nan_len = end-start
            if nan_len<interval_num:
                px = [fixations[start][0], fixations[end+1][0]]
                py = [fixations[start][1], fixations[end+1][1]]
                interx = ((px[1]-px[0])*np.arange(nan_len+1)/float(nan_len+1)+px[0]).tolist()
                intery = ((py[1]-py[0])*np.arange(nan_len+1)/float(nan_len+1)+py[0]).tolist()
                    # fixations[]
                for ii in range(1, len(interx)):
                    fixations[start+ii]=[interx[ii], intery[ii]]

                # print('\n Post: start_idx:{}, end_idx:{}'.format(start, end), \
                #     'fixation_array:',fixations[start:end+2])
        return fixations

    def MovingMedian(self, fixations):

        fixations = np.array(fixations)
        num = self.noise_window_size
        for ii in range(num, len(fixations)-num):
            fix_slice = fixations[ii-num: ii+num+1]
            det_x = fix_slice[:,0].max()-fix_slice[:,0].min()
            det_y = fix_slice[:,1].max()-fix_slice[:,1].min()

            if det_x>det_y: median_idx = np.argsort(fix_slice[:,0])[num]
            else: median_idx = np.argsort(fix_slice[:,1])[num]

            fixations[ii,:] = fix_slice[median_idx,:]
        return fixations.tolist()

    def angle_pixel(self, ):
        angle_h = math.degrees(math.atan2(self.screen_h, self.seat_dis))
        angle_w = math.degrees(math.atan2(self.screen_w, self.seat_dis))
        angle_h_pixel = angle_h/self.resolution[1]
        angle_w_pixel = angle_w/self.resolution[0]
        return angle_h_pixel

    def VelocityCal(self, fixations):
        fixations = np.array(fixations)
        fixations[:,0] = fixations[:,0]*1280
        fixations[:,1] = fixations[:,1]*720
        num = int(self.sample_fps*self.velocity_window_size/1000)
        angle_h_pixel = self.angle_pixel()
        vel_list = []
        for ii in range(len(fixations)-num):
            # 换算成像素
            start = np.array(fixations[ii])
            end = np.array(fixations[ii+num])
            dist = np.sqrt(sum(np.power((end - start), 2)))
            vel = dist*angle_h_pixel*1000/self.velocity_threshold
            vel_list.append(vel)
        return vel_list


    def FixClassifier(self, fixations, velocity):
        
        fixations = np.array(fixations)
        fixations[:,0] = fixations[:,0]*1280
        fixations[:,1] = fixations[:,1]*720
        velocity = np.array(velocity)
        # nan替换为100,不替换nan比任何数都笑
        index = np.where(np.isnan(velocity)==True)
        velocity[index]=100

        fix_idx = velocity>self.velocity_threshold
        # FT定义为开始 TF定义为结束
        start_idx, end_idx = [], []
        for ii in range(len(velocity)-1):
            if (fix_idx[ii] == False) & \
                (fix_idx[ii+1] == True) :
                start_idx.append(ii)
            if (fix_idx[ii] == True) & \
                (fix_idx[ii+1] == False):
                end_idx.append(ii)
        num_fixation = len(start_idx) 
        print('number fixations:', num_fixation)

        # max angle
        angle_h_pixel = self.angle_pixel()
        max_angle=[]
        for start, end in zip(start_idx, end_idx):
            point_s = fixations[start]
            point_e = fixations[end]
            dist = np.sqrt(sum(np.power((point_e-point_s),\
                 2)))*angle_h_pixel
            if dist<self.merge_max_angle:
                max_angle.append([start, end])
        print('less than max angle(0.5):', len(max_angle))

        # max time between fixations to remove blinks
        num = int(self.sample_fps*self.merge_max_time/1000)
        num_blink=[]
        for start, end in zip(start_idx, end_idx):
            if end-start>num:
                # start_idx.remove(start)
                # end_idx.remove(end)
                num_blink.append([start,end])
        print('greater than blink(75ms) number:', len(num_blink))
        # print('number fixations:', len(start_idx))

        # minimum fixation duration
        num = int(self.sample_fps*self.discard_min_duration/1000)
        num_short_fix = []
        for idx, start in enumerate (start_idx):
            if idx==0: end=0
            elif idx==len(start_idx): end=len(start_idx)
            else: end=start_idx[idx-1]
            if start-end<num:
                num_short_fix.append([end, start])
        print('shorter than fixation(60ms) number:', len(num_short_fix))



    def scatter_plot1(self, data):
        fig, ax = plt.subplots(figsize=(8,4.5))
            
        end = len(data[0])*(1/self.sample_fps)
        x = np.arange(0, end ,1/self.sample_fps)
        
        ax.plot(x, data[0], label=['raw_x', 'raw_y'])
        ax.plot(x, data[1], label=['gap_fill_x', 'gap_fill_y'])
        ax.plot(x, data[2], label=['merge_x', 'merge_y'])
        plt.legend()
        plt.show()

    def scatter_plot2(self, data):
        fig, ax = plt.subplots(figsize=(8,4.5))
            
        end = len(data)*(1/self.sample_fps)
        x = np.arange(0, end ,1/self.sample_fps)
        ax.plot(x, data, label='velocity')
        plt.show()
        
if __name__ == '__main__':

    fixation_path = './postprocess_data/fixation.json'
    fixation_list = read_json(fixation_path)
    fixations = get_fixation_list(fixation_list)

    Filter = Tobii_IVT_filter(1200, 'fixation')
    Filter.filter_process(fixations)


在使用的过程中发现了一些小问题:

  1. 眼跳最大速度在阈值速度附近时候会出现一个眼跳多个开始结束点的情况;
  2. 眨眼的周围区间会出现大量失真的速度点,这些点会影响眼跳区间的确定;
  3. 以速度阈值确定的区间并不是眼跳的区间,需要进一步以更小的阈值确定正确的区间;
  4. 在数据噪声比较明显的时候,会出现开始和结尾不匹配成对的情况,因此相比上面先找出所有区间,再进行筛选的逻辑。更好准确的策略应该是一对对的找区间,确保每个区间的正确性。在这里插入图片描述

GITHUB c代码

https://github.com/uxifiit/GazeToolkit

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于python 自写Tobii VI-T滤波器 的相关文章

  • pip 安装最新的依赖版本

    当我使用安装包时pip install e 它仅安装不满足的依赖项并忽略依赖项升级 如何在每次运行时安装最新的依赖版本pip install e 我尝试过使用pip install upgrade e 但是使用这个选项没有任何改变 我仍然得
  • 从 Python 中的 message_from_string() 获取发件人地址

    有人可以告诉我如何在Python中从email message from string 获取发件人地址吗 谢谢 我试过 message email message from string email text from message Fr
  • 用于读取类似 CSV 行的 Python 正则表达式

    我想解析传入的类似 CSV 的数据行 值用逗号分隔 逗号周围可能有前导和尾随空格 并且可以用 或 引用 例如 这是有效的行 data1 data2 data3 data4 data5 但这是格式错误的 data1 data2 da ta3
  • 使用python编辑html,但是lxml将漂亮的html实体转换为奇怪的编码

    我正在尝试使用 python 带有 pyquery 和 lxml 来更改和清理一些 html Eg html div p It 146 s a spicy meatball p div lxml html clean 函数 clean ht
  • MacOS Big Sur 中的 NPM 错误“找不到 Python 可执行文件”

    我已经花了整整一周的时间寻找这个问题的答案 但没有成功 我查看了每个 StackOverflow 帖子 Google 的每一篇文章以及我能找到的每个相关的 Github 问题 大多数相关错误似乎都比较旧 所以我想知道我的问题是否由于我使用的
  • TemplateSyntaxError:“settings_tags”不是有效的标签库

    当我尝试运行此测试用例时 出现此错误 这是在我的 django 应用程序的tests py 中编写的 def test accounts register self self url http royalflag com pk accoun
  • python win32com.client 调整窗口大小

    我正在使用 Python 3 4 1 通过 win32com client 控制 Windows 应用程序 我可以激活它 我可以发送击键 点击等 现在我想知道是否有办法调整窗口大小并将其设置到特定位置 我找不到方法 这里有一些代码片段 所以
  • Python SQLite3 SQL注入漏洞代码

    我知道下面的代码片段由于 format 的原因很容易受到 SQL 注入的攻击 但我不知道为什么 有谁明白为什么这段代码容易受到攻击以及我从哪里开始修复它 我知道这些代码片段使输入字段保持打开状态 以便通过 SQL 注入执行其他恶意命令 但不
  • Plotly:如何设置文本格式(下划线、粗体、斜体)

    使用注释时 我尝试在绘图中为文本添加下划线 我使用添加注释 import plotly graph objects as go g go FigureWidget make subplots rows 1 cols 1 g update l
  • 如何停止 PythonShell

    如何终止 停止 Node js 中 PythonShell 执行的 Python 脚本的执行 我在交互模式下运行 输出通过 socket io 发送到给定的房间 如果没有更多的客户端连接到这个房间 我想停止 python 脚本的执行 这是我
  • python 硒 按名称查找元素

    查找电子邮件输入的正确代码是什么https accounts google com ServiceLogin html 是
  • 使用最新值进行采样

    考虑以下系列 created at 2014 01 27 21 50 05 040961 80000 00 2014 03 12 18 46 45 517968 79900 00 2014 09 05 20 54 17 991260 636
  • 如何在 tkinter 后台运行函数[重复]

    这个问题在这里已经有答案了 我是 GUI 编程新手 我想用 tkinter 编写一个 Python 程序 我想要它做的就是在后台运行一个可以通过 GUI 影响的简单函数 该函数从 0 计数到无穷大 直到按下按钮为止 至少这是我想要它做的 但
  • 在添加数据之前使用 Python gdata 清除工作表中的行

    我有一个 Google 电子表格 我使用 python 脚本和 gdata 库填充值 如果我多次运行脚本 它会将新行附加到工作表中 我希望脚本在填充之前首先清除行中的所有数据 这样每次运行时我都会有一组新的数据脚本 我尝试过使用 Updat
  • 在 Keras 中使用有状态 LSTM 训练多变量多级数回归问题

    我有时间序列P过程 每个过程的长度各不相同 但都有 5 个变量 维度 我试图预测测试过程的估计寿命 我正在用有状态的方法来解决这个问题LSTM在喀拉斯 但我不确定我的训练过程是否正确 我将每个序列分成长度的批次30 所以每个序列都是这样的形
  • 数据类和属性装饰器

    我一直在阅读 Python 3 7 的数据类 作为命名元组的替代品 我通常在必须将数据分组到结构中时使用它 我想知道数据类是否与属性装饰器兼容 以便为数据类的数据元素定义 getter 和 setter 函数 如果是这样 是否在某处进行了描
  • 从 SUDS 中的 SOAP 响应中提取 Cookie

    我必须使用具有多种服务的 API 所有这些都需要来自下面的身份验证的 JSESSION cookie 然而 当我调用下一个服务时 它不会保留 cookie 因此会拒绝它们 from suds client import Client url
  • 根据标签位置计算 Pandas DataFrame 的索引

    我正在尝试计算标签的索引Pandas https pandas pydata org DataFrame在每一列中 基本上我有以下内容DataFrame d col1 label1 label2 label3 col2 label2 lab
  • 如何将另一整列作为参数传递给 pandas fillna()

    我想用另一列中的值填充一列中的缺失值 使用fillna方法 我读到循环遍历每一行将是非常糟糕的做法 最好一次完成所有事情 但我不知道如何使用fillna 之前的数据 Day Cat1 Cat2 1 cat mouse 2 dog eleph
  • Python 子进程:无法转义引号

    我知道以前曾问过类似的问题 但它们似乎都是通过重新设计参数的传递方式 即使用列表等 来解决的 但是 我这里有一个问题 因为我没有这个选项 有一个特定的命令行程序 我使用的是 Bash shell 我必须向其传递带引号的字符串 它不能不被引用

随机推荐

  • FPGA、PLC、STM32、单片机、计算机等概念间的关系、区别及各自的优缺点

    FPGA PLC STM32 Arduino 单片机 计算机等概念间的关系 区别及各自的优缺点 入门之初 对于标题所列各个概念总是含混不清的 这样一来 不知道自己应该从何学起 或者不知道自己想要实现的IDEA应该使用什么样的硬件系统最合适
  • ethercard php_关于EtherCard的webClient代码分析

    以下代码摘自EtherCard的webClient实例 主要功能是打开指定网址 Serial print const char Ethernet buffer off 这一行显示服务器返回的数据 当输出一个没有任何格式的页面的时候 也返回一
  • 稳压二极管(齐纳Zener二极管)的接法和应用详解

    http www elecfans com dianzichangshi 20170529520260 html http www elecfans com yuanqijian erjiguang 20180103610356 html
  • Zabbix学习笔记(二)Zabbix的配置

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 目录 前言 1 数据库设置 2 zabbix 服务器设置 1 访问并配置zabbix 总结 前言 近期学习网络运维监控方面的知识 在使用Zabbix系统中遇到了许多的问题 在
  • 深入理解CSS中em, rem, ex区别,及使用技巧

    CSS 中常见尺寸 单位 描述 百分比 in 英寸 cm 厘米 mm 毫米 ex 一个 ex 是一个字体的 x height x height 通常是字体尺寸的一半 pt 磅 1 pt 等于 1 72 英寸 pc 12 点活字 1 pc 等
  • 华为三层交换机VRRP与DHCP综合实验

    要求设计 1 公司有三个部门 为确保通信安全 每个部门都处于独立的广播域 2 Vlan40为外来人员所在的Vlan 此vlan中的主机只能访问DHCP服务器 3 每个部门的 IP地址规划为 192 168 xx 0 24 4 每个部门的主机
  • 【前端】Vue项目:旅游App-(18)TabBar:debug,非点击tabBar的路由跳转active显示问题

    文章目录 目标 过程与代码 原因与属性的添加 currentIndex的修改 效果 总代码 修改的文件 tab bar vue 本项目博客总结 前端 Vue项目 旅游App 博客总结 目标 当我们在url处实现路由跳转时 tabBar没有产
  • java程序语句_Java-语言编程

    创建节点和插入节点 很多时候我们想要在某个位置插入一个新的节点 此时我们首先需要有一个节点存在 可以通过以下几种方式创建新节点 创建节点 方法描述createElement 创建一个新的节点 需要传入节点的标签名称 返回创建的元素对象cre
  • 100天精通Python(数据分析篇)——第74天:Panda索引标签修改函数大全(参数说明+代码实战)

    文章目录 本文导读 一 添加标签前后缀 1 add prefix str 2 add suffix str 二 标签重命名 1 set axis 1 修改行标签 2 修改列标签
  • oracle统计信息详解

    收集oracle统计信息 优化器统计范围 表统计 行数 块数 行平均长度 all tables NUM ROWS BLOCKS AVG ROW LEN 列统计 列中唯一值的数量 NDV NULL值的数量 数据分布 DBA TAB COLUM
  • RGMII Delay的一点理解

    RGMII delay 如何产生的 可能是RGMII协议规定如此 因此在soc内部集成的RGMII片内外设 将时钟边沿与数据跳变在同一时刻发生 但是RGMII接收端是需要在时钟的边沿处捕获数据的 因此就需要将发送时钟移位 进而使接收端可以正
  • js 数组id去重

    可以用下面的方法来去除数组中的重复项 先将数组转换为 Set 类型 然后再转回数组 这种方法的缺点是会丢失原数组的顺序 const arr 1 2 3 3 2 1 const unique new Set arr console log u
  • C语言PTA题目:7-22 1022 利息

    输入存款金额money 存期year和年利率rate 根据下列公式计算存款到期时的利息interest 税前 输入格式 输入可能有多行 每行有3个整数 分别表示金额 存期 年 年利率 百分比数 输出格式 根据money 1 rate yea
  • 服务器怎么把自己的项目放上去,怎么把项目放到云服务器上

    怎么把项目放到云服务器上 内容精选 换一换 云服务器组是对云服务器的一种逻辑划分 云服务器组中的弹性云服务器遵从同一策略 当前仅支持反亲和性 即同一云服务器组中的弹性云服务器分散地创建在不同的主机上 提高业务的可靠性 您可以使用云服务器组将
  • 微信小程序:字体保持大小

    小程序和网页差不多 前台用wxml把内容摆好 然后用css调整样式 所以和web一样 必须要能够精确控制每一个元素的大小 在Web中 通过CSS基本达到了像素级的控制 但在小程序中 情况有所不同 下面是我通过微信提供的事件分析 把近7天访问
  • 数字化转型方法论汇总(学习笔记)

    数字化转型方法论汇总 德勤制造业数字化转型方法论 数字化转型的3大要点 1 从满足利益相关者期望出发 2 以企业价值引领业务模式创新 3 以信息作为企业神经中枢 重塑组织协同 一 关注集团利益相关者 两类利益相关者 集团外部的证监会 国资委
  • 比较2个数组是否一样

    需求 如果两个数组的类型 元素个数 元素顺序和内容是一样的我们就认为这2个数组是一模一样的 请使用方法完成 能够判断任意两个整型数组是否一样 并返回true或者false 分析 1 定义方法 接收2个整型数组 gt 是否需要参数 返回值类型
  • 《Win10——如何进入高级启动选项》

    Win10 如何进入高级启动选项 第一种方法 1 管理员命令提示符输入如下代码 自动重启并进入高级启动选项 shutdown r o f t 00 第二种方法 1 管理员命令提示符输入以下代码 开机时按下F8 进入高级启动选项 bcdedi
  • java基础总结(二十五)--访问修饰符protected

    三 protected 关键字的真正内涵 很多介绍Java语言的书籍 包括 Java编程思想 都对protected介绍的比较的简单 基本都是一句话 就是 被protected修饰的成员对于本包和其子类可见 这种说法有点太过含糊 常常会对大
  • 基于python 自写Tobii VI-T滤波器

    文章目录 官网参考文档 Gap fill in interpolation Eye selection Noise reduction Velocity calculator I VT classifier Merge adjacent f