% ========================================================================= % Feature Extraction Script for GRABMyoFlow (Wrist Data) % ========================================================================= % This script processes the .mat files generated by the Python converter. % It extracts features for the WRIST electrodes (using the first 6 channels). % % INPUT: % - Folder generated by Python script (e.g., 'static_extension_MATLAB') % - Structure: Root/SessionX/sessionX_participantY.mat % % OPTIONS: % 1. Whole Set (W): IDs 1-63 % 2. Extension Set (E): IDs 44-63 % 3. Original Set (O): IDs 1-43 % % OUTPUT: % - Folder: 'Feature_Extracted_BM_[POSTFIX]' % - Files: 'Wrist_Session1_[POSTFIX].mat', etc. % ========================================================================= clear; clc; % ========================================================================= % STEP 1: USER CONFIGURATION % ========================================================================= disp('---------------------------------------------------------'); disp(' GRABMyoFlow Wrist Feature Extraction'); disp('---------------------------------------------------------'); disp('Which dataset do you want to process?'); disp(' [W] Whole Dataset (IDs 1-63)'); disp(' [E] Extension Only (IDs 44-63)'); disp(' [O] Original Only (IDs 1-43)'); disp('---------------------------------------------------------'); choice = input('Enter selection (W/E/O): ', 's'); if strcmpi(choice, 'W') sub_list = 1:63; dataset_postfix = '_whole_set'; default_title = 'Select the "static_whole_MATLAB" folder'; elseif strcmpi(choice, 'E') sub_list = 44:63; dataset_postfix = '_extension_set'; default_title = 'Select the "static_extension_MATLAB" or the "static_whole_MATLAB" folder'; elseif strcmpi(choice, 'O') sub_list = 1:43; dataset_postfix = '_original_set'; default_title = 'Select the "static_whole_MATLAB" or the original "Output_BM"(from grabmyo) folder'; else error('Invalid selection. Please run script again and type W, E, or O.'); end % Select the input folder fprintf('\nPlease select the folder containing the converted MAT files...\n'); base_input_folder = uigetdir(pwd, default_title); if base_input_folder == 0 error('No folder selected.'); end % Constants fs = 2048; % Sampling frequency NGESTURE = 16; % Total number of gestures (Script loads 1:NGESTURE+1 for rest) NTRIALS = 7; % Total number of trials NSESSION = 3; % Number of sessions % Define Output Folder with Postfix output_dir = [pwd filesep 'Feature_Extracted_BM' dataset_postfix]; if ~exist(output_dir, 'dir') mkdir(output_dir); fprintf('Created output folder: %s\n', output_dir); else fprintf('Output folder exists (%s). Overwriting content...\n', output_dir); end % ========================================================================= % STEP 2: LOAD AND FLATTEN DATA % ========================================================================= for isession = 1:NSESSION CompleteSet = []; current_session_folder = [base_input_folder filesep 'Session' num2str(isession)]; if ~exist(current_session_folder, 'dir') warning(['Session folder not found: ' current_session_folder]); continue; end fprintf('\nProcessing Session %d (%s)...\n', isession, dataset_postfix); valid_sub_count = 0; for isub = sub_list fileName = ['session' num2str(isession) '_participant' num2str(isub) '.mat']; filePath = [current_session_folder filesep fileName]; if ~exist(filePath, 'file') warning(['File missing: ' fileName]); continue; end temp_load = load(filePath, 'DATA_WRIST'); datafile = temp_load.DATA_WRIST; a2 = []; for igesture = 1:(NGESTURE + 1) a1 = []; for itrial = 1:NTRIALS if isempty(datafile{itrial, igesture}) warning(['Empty data for Sub ' num2str(isub) ' Ges ' num2str(igesture)]); continue; end a1 = [a1; datafile{itrial, igesture}]; end a2 = [a2, {a1}]; end CompleteSet = [CompleteSet; a2]; valid_sub_count = valid_sub_count + 1; if mod(valid_sub_count, 10) == 0 fprintf('Loaded %d subjects...\n', valid_sub_count); end end if isempty(CompleteSet) warning(['No data loaded for Session ' num2str(isession) '. Skipping.']); continue; end % ========================================================================= % STEP 3: SEGMENTATION AND FEATURE EXTRACTION % ========================================================================= fprintf('Extracting Features for Session %d...\n', isession); FeatSet = {}; num_rows_processed = 0; for idx = 1:size(CompleteSet, 1) for igesture = 1:NGESTURE OneSet = CompleteSet{idx, igesture}'; post_process = zeros(6, size(OneSet, 2)); temp_6ch = OneSet(1:6, :); common_avg = mean(temp_6ch, 1); for ich = 1:6 post_process(ich, :) = OneSet(ich, :) - common_avg; end % --- SEGMENTATION --- % 0.2s window, 0.15s slide segData = segmentEMG(post_process', 0.2, 0.15, NTRIALS*5, fs, 1); % --- FEATURE EXTRACTION --- feat = featiDFTl(2048, 6, segData); FeatSet(idx, igesture) = {feat}; end num_rows_processed = num_rows_processed + 1; end % Save Result with Postfix saveName = [output_dir filesep 'Wrist_Session' num2str(isession) dataset_postfix '.mat']; disp(['Saving: ' saveName]); save(saveName, 'FeatSet'); end disp('Feature Extraction Complete.');