{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":59093,"databundleVersionId":7469972,"sourceType":"competition"}],"dockerImageVersionId":30635,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"### This article is learned from <a href=\"https://www.kaggle.com/code/cdeotte/how-to-make-spectrogram-from-eeg\">how to make spectrogram from eeg</a>,I learned its code and tried to match the input of my own model(Resnet34d). Now prepare the training data.","metadata":{}},{"cell_type":"markdown","source":"### Import necessary libraries","metadata":{}},{"cell_type":"code","source":"import pandas as pd#导入csv文件的库\nimport numpy as np#进行矩阵运算的库\nimport warnings#避免一些可以忽略的报错\nwarnings.filterwarnings('ignore')#filterwarnings()方法是用于设置警告过滤器的方法，它可以控制警告信息的输出方式和级别。","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Function to make spectrogram","metadata":{}},{"cell_type":"code","source":"import librosa#音频处理和分析的库\n\n#脑电图电极的位置或区域. 'Left Lower','left upper','Right Upper','RightLower'(顺时针) \n#NAMES = ['LL','LP','RP','RR']\n#eeg信号采集的相对位置\nFEATS = [['Fp1','F7','T3','T5','O1'],\n         ['Fp1','F3','C3','P3','O1'],\n         ['Fp2','F8','T4','T6','O2'],\n         ['Fp2','F4','C4','P4','O2']]\n\n#将eeg文件转成spectrogram文件\ndef spectrogram_from_eeg(parquet_path):#parquet_path是eeg文件的路径\n    #根据路径,加载eeg的中间50秒\n    eeg = pd.read_parquet(parquet_path)\n    middle = len(eeg)//2-5000\n    eeg = eeg.iloc[middle:middle+10000]\n    \n    #初始化图片大小\n    img = np.zeros((256,256,4),dtype='float32')\n    \n    for k in range(4):\n        COLS = FEATS[k]#取出FEATS第K行的特征\n        \n        for kk in range(4):\n            #计算电势差(第kk个位置-第KK+1个位置) \n            x = eeg[COLS[kk]].values - eeg[COLS[kk+1]].values\n            \n            #对缺失值填充为均值\n            m = np.nanmean(x)#计算非nan位置数值的平均值\n            if np.isnan(x).mean()<1:#有不是缺失值的数据\n                x = np.nan_to_num(x,nan=m)#将数组x中为nan值替换为均值m\n            else: #np.isnan(x).mean()==1,即全是缺失值\n                x[:] = 0#填充为0\n\n            #计算音频信号的梅尔频谱特征 (n_mels,len(x)//hop_length+1)\n            #y：音频信号的波形数据,sr：音频信号的采样率.\n            # hop_length：帧移（每一帧之间的步长）的长度，通过将原始音频分割成多个短时帧来进行频谱计算。\n            # n_fft：FFT 窗口大小，表示每个帧的长度.\n            # n_mels：梅尔滤波器的数量，决定了梅尔频谱的分辨率.\n            # fmin：梅尔滤波器的最低频率,fmax：梅尔滤波器的最高频率.\n            # win_length：窗口函数的长度.\n            mel_spec = librosa.feature.melspectrogram(y=x, sr=200, hop_length=len(x)//256,\n                  n_fft=1024, n_mels=256,fmin=0, fmax=20, win_length=128)\n\n            \"\"\"\n            对每个元素取以10为底的对数，得到对数功率谱矩阵.\n            根据参考功率ref对对数功率谱矩阵进行平移，使得最大值等于梅尔频谱矩阵的最大值.\n            截断超过width的数据,避免出现噪声或不稳定性导致的误差.取值范围为(- infty,0)\n            \"\"\"\n            #宽度调整\n            width = (mel_spec.shape[1]//32)*32\n            mel_spec_db = librosa.power_to_db(mel_spec, ref=np.max).astype(np.float32)[:,:width]\n\n            #类似归一化的操作\n            mel_spec_db = (mel_spec_db+40)/40 \n            img[:,:,k] += mel_spec_db\n                \n        #4个时刻的差值,故取平均.\n        img[:,:,k] /= 4.0\n    #变成(256,256)\n    img=np.mean(img,axis=2)\n    return img","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### make images","metadata":{}},{"cell_type":"code","source":"#获取训练数据的img\ntrain = pd.read_csv('/kaggle/input/hms-harmful-brain-activity-classification/train.csv')\neeg_ids = train.eeg_id.unique()\n\nall_eegs = {}\nfor i,eeg_id in enumerate(eeg_ids):\n    #调用函数获取img\n    img = spectrogram_from_eeg(f'/kaggle/input/hms-harmful-brain-activity-classification/train_eegs/{eeg_id}.parquet')\n    #将img保存进字典\n    all_eegs[eeg_id] = img\n    \n#将所有数据进行保存\nnp.save('eeg_specs',all_eegs)","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}