import numpy as np import matplotlib.pyplot as plt from pyts.preprocessing import InterpolationImputer # Parameters n_samples, n_timestamps = 100, 48 # Toy dataset rng = np.random.RandomState(41) X = rng.randn(n_samples, n_timestamps) missing_idx = rng.choice(np.arange(1, 47), size=14, replace=False) X[:, missing_idx] = np.nan # Show the results for different strategies for the first time series plt.figure(figsize=(16, 10)) for i, strategy in enumerate(['linear', 'quadratic', 'cubic', 'nearest']): imputer = InterpolationImputer(strategy=strategy) X_imputed = imputer.transform(X) plt.subplot(2, 2, i + 1) plt.plot(X_imputed[0], 'o--', color='C1', label='Imputed') plt.plot(X[0], 'o--', color='C0', label='Original') plt.title("{0} Interpolation".format(strategy.capitalize()), fontsize=16) plt.legend(loc='best', fontsize=14) plt.suptitle('Interpolating missing values with different strategies', fontsize=20) plt.tight_layout() plt.subplots_adjust(top=0.9) plt.show()
def load_skeleton(VIDEO_ROOT_DIR, folder, video): """ load the skeleton data from csv files :param VIDEO_ROOT_DIR: video's root directory :param folder: video folder :param video: video file name :return: """ # number of time steps to crop NUM_TIMESTEPS = 130 file_dir = os.path.join(VIDEO_ROOT_DIR, folder, video[:-4]) joint_data = pd.read_csv(os.path.join(file_dir, "jointdata.csv")) joint_data["data"] = joint_data["data"].apply(json.loads) index_1 = len(joint_data) // 3 index_2 = len(joint_data) // 3 * 2 if joint_data.iloc[index_1]["data"][8][0] > joint_data.iloc[index_2][ "data"][8][0]: # walking towards image left Direction = "L" else: Direction = "R" # flip the x coordinate, according to walk direction if Direction == "L": for i in range(len(joint_data)): for j in range(25): joint_data["data"][i][j][ 0] = IMAGE_W - joint_data["data"][i][j][0] # index in the original when it starts to have valid skeleton data idx_start = int(round(joint_data["time"][0] * 30 / 1000)) # index of the last frame with valid skeleton data idx_end = int( round(joint_data["time"][joint_data.shape[0] - 1] * 30 / 1000)) seq_len = idx_end - idx_start + 1 left_seq = [None] * seq_len right_seq = [None] * seq_len back_seq = [None] * seq_len index_seq = [None] * seq_len for i in range(joint_data.shape[0]): # calculate the index of the original video, according to the "time" time stamp original_index = int(round(joint_data["time"][i] * 30 / 1000)) # left lower leg's sequence (KNEE_LEFT, ANKLE_LEFT) left_seq[original_index - idx_start] = (calculate_angles( joint_data["data"][i][13], joint_data["data"][i][14])) # right lower leg's sequence (KNEE_RIGHT, ANKLE_RIGHT) right_seq[original_index - idx_start] = (calculate_angles( joint_data["data"][i][10], joint_data["data"][i][11])) # back angle's sequence (Neck, MidHip) back_seq[original_index - idx_start] = (calculate_angles( joint_data["data"][i][1], joint_data["data"][i][8])) # save the relative index compared to idx_start index_seq[original_index - idx_start] = i # # visualize the original left lower leg's sequence # plt.plot(left_seq) # plt.show() # interpolate the missing data in the sequences imputer = InterpolationImputer() impute_index = list(range(idx_start, idx_end + 1)) left = np.array(imputer.transform([impute_index, left_seq])[1]) right = np.array(imputer.transform([impute_index, right_seq])[1]) back = np.array(imputer.transform([impute_index, back_seq])[1]) # # visualize the left lower leg's sequence after interpolation # plt.plot(left) # plt.show() # peaks, properties = find_peaks(left, prominence=(10, None)) # peaks_left, _ = find_peaks(left,prominence=(30, None)) peaks_right, _ = find_peaks(right, prominence=(30, None)) # prominences_left = peak_prominences(left, peaks_left)[0] # prominences_right = peak_prominences(right, peaks_right)[0] # peak_left_index = [index_seq[i] for i in peaks_left] # peak_right_index = [index_seq[i] for i in peaks_right] # # period of each cycle # T_left = [peak_left_index[i+1] - peak_left_index[i] for i in range(len(peak_left_index)-1) ] # T_right = [peak_right_index[i+1] - peak_right_index[i] for i in range(len(peak_right_index)-1) ] # # average period # T_L = sum(T_left)/len(T_left) # T_R = sum(T_right)/len(T_right) # start cropping from the first peak point of the right sequence start = peaks_right[0] # crop from the first peak point CROP = True if CROP: if len(joint_data) - start < NUM_TIMESTEPS: print("not enough data, sequence length: {}".format( len(joint_data) - start)) return seqs = np.array([ left[start:start + NUM_TIMESTEPS], right[start:start + NUM_TIMESTEPS], back[start:start + NUM_TIMESTEPS] ]) # # blue line - left lower leg # plt.plot(left[start:start+NUM_TIMESTEPS]) # plt.show() # # orange line - right lower leg # plt.plot(right[start:start+NUM_TIMESTEPS]) # plt.plot(back[start:start+NUM_TIMESTEPS]) # plt.ylim(-90, 90) # plt.show() else: if len(joint_data) < NUM_TIMESTEPS: print("not enough data, sequence length: {}".format( len(joint_data) - start)) return seqs = np.array([ left[:NUM_TIMESTEPS], right[:NUM_TIMESTEPS], back[:NUM_TIMESTEPS] ]) # # blue line - left lower leg # plt.plot(left[:NUM_TIMESTEPS]) # plt.show() # # orange line - right lower leg # plt.plot(right[:NUM_TIMESTEPS]) # plt.plot(back[:NUM_TIMESTEPS]) # plt.ylim(-90, 90) # plt.show() return seqs
def load_skeleton(VIDEO_ROOT_DIR, folder, video): file_dir = os.path.join(VIDEO_ROOT_DIR, folder, video[:-4]) joint_data = pd.read_csv(os.path.join(file_dir, "jointdata.csv")) joint_data["data"] = joint_data["data"].apply(json.loads) index = pd.read_csv(file_dir + "primer.csv", header=None)[0][0] index_1 = len(joint_data) // 3 index_2 = len(joint_data) // 3 * 2 if joint_data.iloc[index_1]["data"][8][0] > joint_data.iloc[index_2][ "data"][8][0]: # walking towards image left Direction = "L" else: Direction = "R" # flip the x coordinate, according to walk direction if Direction == "L": for i in range(len(joint_data)): for j in range(25): joint_data["data"][i][j][ 0] = IMAGE_W - joint_data["data"][i][j][0] # calculate speed pixel/second Neck_1 = joint_data["data"][index_1][1] Neck_2 = joint_data["data"][index_2][1] MidHip_1 = joint_data["data"][index_1][8] MidHip_2 = joint_data["data"][index_2][8] delta_x_OP = (Neck_2[0] + MidHip_2[0]) / 2 - (Neck_1[0] + MidHip_1[0]) / 2 delta_t = abs(joint_data["time"][index_2] - joint_data["time"][index_1]) / 1000 if delta_t == 0: print("error in speed calculation") return -1 else: SpeedOPose = abs(delta_x_OP / delta_t) # calculate 3 angles Neck = joint_data["data"][index][1] MidHip = joint_data["data"][index][8] Nose = joint_data["data"][index][0] Body_Lean = calculate_angles(Nose, MidHip) Back_Lean = calculate_angles(Neck, MidHip) Neck_Lean = calculate_angles(Nose, Neck) # index in the original when it starts to have valid skeleton data idx_start = int(round(joint_data["time"][0] * 30 / 1000)) # index of the last frame with valid skeleton data idx_end = int( round(joint_data["time"][joint_data.shape[0] - 1] * 30 / 1000)) seq_len = idx_end - idx_start + 1 left_seq = [None] * seq_len right_seq = [None] * seq_len index_seq = [None] * seq_len for i in range(joint_data.shape[0]): # calculate the index of the original video, according to the "time" time stamp original_index = int(round(joint_data["time"][i] * 30 / 1000)) # left lower leg's sequence (KNEE_LEFT, ANKLE_LEFT) left_seq[original_index - idx_start] = calculate_angles( joint_data["data"][i][13], joint_data["data"][i][14]) # right lower leg's sequence (KNEE_RIGHT, ANKLE_RIGHT) right_seq[original_index - idx_start] = calculate_angles( joint_data["data"][i][10], joint_data["data"][i][11]) # save the relative index compared to idx_start index_seq[original_index - idx_start] = i imputer = InterpolationImputer() impute_index = list(range(idx_start, idx_end + 1)) left = np.array(imputer.transform([impute_index, left_seq])[1]) right = np.array(imputer.transform([impute_index, right_seq])[1]) # plt.plot(impute_index,left_seq) # plt.show() # plt.plot(impute_index,left) # plt.show() peaks_left, bottom_left = sequence_extrema(left) peaks_right, bottom_right = sequence_extrema(right) left_stance, left_swing = stance_swing(peaks_left, bottom_left) right_stance, right_swing = stance_swing(peaks_right, bottom_right) # Asymmetry Stance phase AStP = calculate_asymmetry(left_stance, right_stance) # Asymmetry Swing phase ASwP = calculate_asymmetry(left_swing, right_swing) cadence = calculate_cadence(peaks_left, peaks_right) left_peak_amp = np.mean([left[i] for i in peaks_left]) left_bottom_amp = np.mean([left[i] for i in bottom_left]) right_peak_amp = np.mean([right[i] for i in peaks_right]) right_bottom_amp = np.mean([right[i] for i in bottom_right]) # Asymmetry Peak Amplitude APA = calculate_asymmetry(left_peak_amp, right_peak_amp) # Asymmetry Bottom Amplitude ABA = calculate_asymmetry(left_bottom_amp, right_bottom_amp) L_index = ceil(len(peaks_left) / 2) - 1 R_index = ceil(len(peaks_right) / 2) - 1 # left lower leg: peaks_left[L_index] to peaks_left[L_index+1] # right lower leg: peaks_right[R_index] to peaks_right[R_index+1] # step length stride length: distance between the heel contact point of one foot and that of the other foot. left_step_length = abs( joint_data["data"][index_seq[peaks_left[L_index]]][21][0] - joint_data["data"][index_seq[peaks_left[L_index]]][24][0]) right_step_length = abs( joint_data["data"][index_seq[peaks_left[R_index]]][21][0] - joint_data["data"][index_seq[peaks_left[R_index + 1]]][24][0]) # Asymmetry Step length ASl = calculate_asymmetry(left_step_length, right_step_length) stride_length = abs( joint_data["data"][index_seq[peaks_left[L_index]]][21][0] - joint_data["data"][index_seq[peaks_right[L_index]]][21][0]) falling_risk = abs( joint_data["data"][index_seq[peaks_left[L_index]]][0][0] - (joint_data["data"][index_seq[peaks_left[L_index]]][21][0] + joint_data["data"][index_seq[peaks_left[L_index]]][24][0]) / 2 ) / (abs(joint_data["data"][index_seq[peaks_left[L_index]]][19][0] - joint_data["data"][index_seq[peaks_left[L_index]]][24][0]) / 2) features = [ SpeedOPose, Body_Lean, Back_Lean, Neck_Lean, left_stance, left_swing, right_stance, right_swing, AStP, ASwP, cadence, left_peak_amp, right_peak_amp, left_bottom_amp, right_bottom_amp, APA, ABA, left_step_length, right_step_length, ASl, stride_length, falling_risk ] return features
def test_parameter_check(params, error, err_msg): """Test parameter validation.""" imputer = InterpolationImputer(**params) with pytest.raises(error, match=re.escape(err_msg)): imputer.transform(X)