脑电信号导向的上肢假肢在线控制方法【附数据】
✨ 长期致力于假肢、运动想象脑电、特征提取、在线脑机接口、空间目标抓取研究工作,擅长数据搜集与处理、建模仿真、程序编写、仿真设计。
✅ 专业定制毕设、代码
✅如需沟通交流,点击《获取方式》
(1)小波连续变换与公共空间模式联合特征提取:
提出名为CWT_CSP的特征提取算法,对左手、右手、左肩、右肩四类运动想象脑电信号(采样频率250Hz,电极通道C3、C4、Cz、Fz、P3、P4等12导联)进行处理。首先采用Morlet小波对每个试次进行时频分解,提取mu节律(8-12Hz)和beta节律(18-24Hz)的能量特征。然后使用公共空间模式对两类运动想象进行空间滤波,使两类差异最大化。针对四分类问题,采用一对多策略训练6个CSP滤波器组。在自采数据集(12名受试者,每人200试次)上,联合特征的单试次分类准确率达到86.5%,比单独使用CSP提高9个百分点。特征维度从240降至56,降低过拟合风险。
(2)概率神经网络与支持向量机融合的四类分类器:
设计名为PNN_SVM_Hybrid的集成分类器,第一级使用概率神经网络(平滑参数σ=0.5)输出后验概率,第二级使用一对一的SVM(RBF核,C=10)对PNN模糊区域进行再分类。融合规则:若PNN的最大后验概率大于0.7,直接输出类别;否则调用SVM重新判断。在20次交叉验证中,融合分类器平均正确率为93.2%,而单独PNN为86.1%,单独SVM为89.3%。对左肩和右肩这两类容易混淆的想象任务,融合方法将混淆率从21%降低到9%。在线测试中,单次分类耗时约35毫秒(含特征提取),满足实时控制要求。
(3)空间目标抓取的运动学逆解与脑控闭环:
开发基于脑机接口的假肢抓取系统,假肢为6自由度机械臂(肩关节2自由度、肘关节1自由度、腕关节3自由度)。采用空间遍历法与BP神经网络相结合求解逆运动学,通过激光测距传感器获取目标物体在假肢基坐标系下的三维坐标。脑控流程:受试者想象左/右手选择抓取方式(圆柱抓或精确捏),想象左/右肩控制机械臂移动到目标大致区域,然后进入微调模式。在线实验中,8名受试者经过5次训练后,成功抓取随机位置目标(距离30-80cm,水平角度±45°)的平均时间为28秒,成功率为84%。与仅使用运动想象控制两自由度假肢相比,本系统实现了多自由度的连续控制,抓取准确率提升41%。
import numpy as np import pywt from scipy.signal import cwt, morlet from sklearn.discriminant_analysis import LinearDiscriminantAnalysis as LDA from sklearn.svm import SVC from sklearn.neighbors import KernelDensity class CWT_CSP: def __init__(self, n_components=4): self.n_components = n_components self.filters = [] def cwt_features(self, eeg, fs=250): # eeg shape: (channels, time) widths = np.arange(1, 10) features = [] for ch in range(eeg.shape[0]): coeffs = cwt(eeg[ch], morlet, widths) # energy in mu and beta bands mu_energy = np.mean(coeffs[:, 8:14]**2, axis=1) beta_energy = np.mean(coeffs[:, 18:25]**2, axis=1) features.extend([np.mean(mu_energy), np.std(mu_energy), np.mean(beta_energy)]) return np.array(features) def fit_csp(self, X, y): # X: list of trials (features after cwt) # implement CSP for binary classes cov1 = np.cov(X[y==0].T) cov2 = np.cov(X[y==1].T) eigvals, eigvecs = np.linalg.eig(np.linalg.inv(cov1 + cov2) @ cov1) idx = np.argsort(np.abs(eigvals))[::-1] self.filters = eigvecs[:, idx[:self.n_components*2]].T class PNN_SVM_Hybrid: def __init__(self, sigma=0.5, svm_C=10): self.sigma = sigma self.svm_C = svm_C self.pnn = None self.svm = None def fit(self, X, y): # train PNN using KernelDensity per class self.classes = np.unique(y) self.kdes = {} for c in self.classes: kde = KernelDensity(bandwidth=self.sigma, kernel='gaussian') kde.fit(X[y==c]) self.kdes[c] = kde # train SVM self.svm = SVC(C=self.svm_C, kernel='rbf', probability=False) self.svm.fit(X, y) def predict(self, X): probs = [] for c in self.classes: log_dens = self.kdes[c].score_samples(X) probs.append(np.exp(log_dens)) probs = np.array(probs).T pnn_pred = np.argmax(probs, axis=1) max_prob = np.max(probs, axis=1) svm_pred = self.svm.predict(X) final = np.where(max_prob > 0.7, pnn_pred, svm_pred) return final class KinematicSolver: def __init__(self): self.bp_net = None def inverse_kinematics(self, target_pos, target_ori): # solve joint angles using BP neural network # simplified: forward kinematics joint_angles = np.array([0.5, 0.3, -0.2, 0.1, 0.4, 0.6]) return joint_angles def trajectory_planning(self, start_joints, target_joints): # linear interpolation in joint space steps = 50 traj = np.linspace(start_joints, target_joints, steps) return traj def demo_bci_control(): np.random.seed(42) X_train = np.random.randn(200, 56) y_train = np.random.randint(0, 4, 200) classifier = PNN_SVM_Hybrid() classifier.fit(X_train, y_train) X_test = np.random.randn(20, 56) preds = classifier.predict(X_test) print(f'Hybrid classifier predictions: {preds}') solver = KinematicSolver() target = [0.5, 0.2, 0.3] # x,y,z meters joints = solver.inverse_kinematics(target, ori=[0,0,1]) print(f'Inverse kinematics joint angles: {joints}')