import pandas as pd import numpy as np import getopt import sys import traceback roads = ["i-80", "us-101"] # dety = 15 dety = 33 # vehy = 3 vehy = 9.8 step = 10 # time division feature_interest = ["v_Vel", "Local_X", "Local_Y", "v_Class"] empty_car = [0, 0, 0, 0] overt_rat = 0.2 # mid_bound = 3 mid_bound = 9.8 # far_bound = 15 far_bound = 33 def extract_feature(target): result = [] for f in feature_interest: if isinstance(target, pd.Series): result.append(target[f]) else: result.append(target[f].values[0]) return result def discard_wrong_lane(data): data_new = data[data['Lane_ID'] < 5] data_new = data_new[data_new['Lane_ID'] > 0] return data_new def check_frame_length(data, vehicle_id, length): # see if the vehicle have enough frame if data.loc[data["Vehicle_ID"] == vehicle_id].Total_Frames.values[0] < length: return False else: return True def search_side(frame, target): ''' ----------------------------------- bl_3 l_2 fl_1 ----------------------------------- b_8 target f_7 ----------------------------------- br_6 r_5 fr_4 ----------------------------------- ''' target_v_len = 0.5 * target["v_length"].values[0] # print(frame.shape) left_side = frame[(frame["Lane_ID"] >= (target["Lane_ID"] - 1).values[0]) & (frame["Local_X"] < (target["Local_X"] - 0.5 * target["v_Width"]).values[0]) & (frame["Local_Y"] < (target["Local_Y"] + target_v_len + dety).values[0]) & (frame["Local_Y"] > (target["Local_Y"] - target_v_len - dety).values[0])] right_side = frame[(frame["Lane_ID"] <= (target["Lane_ID"] + 1).values[0]) & (frame["Local_X"] > (target["Local_X"] + 0.5 * target["v_Width"]).values[0]) & (frame["Local_Y"] < (target["Local_Y"] + target_v_len + dety).values[0]) & (frame["Local_Y"] > (target["Local_Y"] - target_v_len - dety).values[0])] bl = l = fl = br = r = fr = 0 if len(left_side) != 0 or len(right_side) != 0: for index, c in left_side.sort_values(by=["Local_Y", "Vehicle_ID"]).iterrows(): if (c["Local_Y"] < (target["Local_Y"] - target["v_length"]-vehy).values[0]): bl = 1 elif l is 0 and (c["Local_Y"] < target["Local_Y"]).any(): l = 1 elif fl is 0: fl = 1 for index, c in right_side.sort_values(by=["Local_Y", "Vehicle_ID"]).iterrows(): if (c["Local_Y"] < (target["Local_Y"] - target["v_length"]).values[0]): br = 1 elif r is 0 and (c["Local_Y"] < target["Local_Y"]).any(): r = 1 elif fr is 0: fr = 1 if target["Lane_ID"].values[0] == 1: bl = l = fl = 1 if target["Lane_ID"].values[0] == 5: br = r = fr = 1 result = [fl, l, bl, fr, r, br] return result def search_acc(frame, target): ''' ----------------------------------- bl_3 l_2 fl_1 ----------------------------------- b_8 target f_7 ----------------------------------- br_6 r_5 fr_4 ----------------------------------- ''' # cache target Local_Y value & v_length target_lane_id = target["Lane_ID"].values[0] target_local_y = target["Local_Y"].values[0] target_local_x = target["Local_X"].values[0] target_v_len = 0.5 * target["v_length"].values[0] # half of the length target_v_width = 0.5 * target["v_Width"].values[0] # gather left side vehicle frame data left_side = frame[(frame["Lane_ID"] >= (target_lane_id - 1)) & (frame["Local_X"] < (target_local_x - target_v_width)) & (frame["Local_Y"] < (target_local_y + target_v_len + dety)) & (frame["Local_Y"] > (target_local_y - target_v_len - dety))] # gather right side vehicle frame data right_side= frame[(frame["Lane_ID"] <= (target_lane_id + 1)) & (frame["Local_X"] > (target_local_x + target_v_width)) & (frame["Local_Y"] < (target_local_y + target_v_len + dety)) & (frame["Local_Y"] > (target_local_y - target_v_len - dety))] # gather back side vehicle data preceding_id = target["Preceding"].values[0] back_side = frame[(frame["Vehicle_ID"] == preceding_id)] # gather front side vehicle data following_id = target["Following"].values[0] front_side = frame[(frame["Vehicle_ID"] == following_id)] front_acc = back_acc = fl_acc = l_acc = bl_acc = fr_acc = r_acc = br_acc = tar_acc = tar_lan = 0, -1 if len(front_side) != 0: front_acc = front_side["v_Acc"].values[0], front_side["Vehicle_ID"].values[0] front_side = front_side[front_side["Local_Y"] > (target_local_y + target_v_len + far_bound)] #see if it's out of range if not front_side.empty: front_acc = 0, -1 if len(back_side) != 0: back_acc = back_side["v_Acc"].values[0], back_side["Vehicle_ID"].values[0] back_side = back_side[back_side["Local_Y"] < (target_local_y - target_v_len - far_bound)] # if(front_side["Local_Y"] > (target_local_y + target_v_len + far_bound)): # if front car out of boundary, clear the number if not back_side.empty: back_acc = 0, -1 if len(left_side) != 0: left_side_sort = left_side.sort_values(by=["Local_Y", "Vehicle_ID"]) # if(left_side_sort["Local_Y"] < (target_local_y + target_v_len + far_bound) & left_side_sort["Local_Y"] > (target_local_y - target_v_len - far_bound).values[0]): # fl_group = frame[(left_side_sort["Local_Y"] > (target_local_y + target_v_len + vehy) & left_side_sort["Local_Y"] < (target_local_y + target_v_len + far_bound))] fl_group = left_side_sort[(left_side_sort['Local_Y'] > (target_local_y + target_v_len + vehy)) & (left_side_sort['Local_Y'] < (target_local_y + target_v_len + far_bound))] if not fl_group.empty: fl = fl_group.iloc[0] # take the closest on fl_acc = fl["v_Acc"], fl["Vehicle_ID"] # if(left_side_sort["Local_Y"] < (target_local_y + target_v_len + mid_bound) & left_side_sort["Local_Y"] > (target_local_y - target_v_len - mid_bound).values[0]): # l_group = frame[(left_side_sort["Local_Y"] < (target_local_y - target_v_len + vehy) & left_side_sort["Local_Y"] > (target_local_y - target_v_len - vehy))] l_group = left_side_sort[(left_side_sort["Local_Y"] < (target_local_y - target_v_len + vehy)) & (left_side_sort["Local_Y"] > (target_local_y - target_v_len - vehy))] if not l_group.empty: l = l_group.iloc[0] #take the closest one l_acc = l["v_Acc"], l["Vehicle_ID"] # if(left_side_sort["Local_Y"] < (target_local_y - target_v_len - mid_bound) & left_side_sort["Local_Y"] > (target_local_y - target_v_len - far_bound).values[0]): #following the upper bound and lowwer bound by the range and half of the vehicle length # bl_group = frame[(left_side_sort["Local_Y"] < (target_local_y - target_v_len - vehy) & left_side_sort["Local_Y"] > (target_local_y - target_v_len - far_bound))] bl_group = left_side_sort[(left_side_sort["Local_Y"] < (target_local_y - target_v_len - vehy)) & (left_side_sort["Local_Y"] > (target_local_y - target_v_len - far_bound))] if not bl_group.empty: bl = bl_group.iloc[len(bl_group)-1]#take the closest one bl_acc = bl["v_Acc"], bl["Vehicle_ID"] if len(right_side) != 0: right_side_sort = right_side.sort_values(by=["Local_Y", "Vehicle_ID"]) # if(right_side_sort["Local_Y"] < (target_local_y + target_v_len + far_bound) & right_side_sort["Local_Y"] > (target_local_y - target_v_len - far_bound).values[0]): # fr_group = frame[(right_side_sort["Local_Y"] > (target_local_y + target_v_len + vehy) & right_side_sort["Local_Y"] < (target_local_y + target_v_len + far_bound))] fr_group = right_side_sort[(right_side_sort["Local_Y"] > (target_local_y + target_v_len + vehy)) & (right_side_sort["Local_Y"] < (target_local_y + target_v_len + far_bound))] if not fr_group.empty: fr = fr_group.iloc[0] #take the closest one fr_acc = fr["v_Acc"], fr["Vehicle_ID"] # if(right_side_sort["Local_Y"] < (target_local_y + target_v_len + mid_bound) & right_side_sort["Local_Y"] > (target_local_y - target_v_len - mid_bound).values[0]): # r_group = frame[(right_side_sort["Local_Y"] < (target_local_y - target_v_len + vehy) & right_side_sort["Local_Y"] > (target_local_y - target_v_len - vehy))] r_group = right_side_sort[(right_side_sort["Local_Y"] < (target_local_y - target_v_len + vehy)) & (right_side_sort["Local_Y"] > (target_local_y - target_v_len - vehy))] if not r_group.empty: r = r_group.iloc[0] #take the closest one r_acc = r["v_Acc"], r["Vehicle_ID"] # if(right_side_sort["Local_Y"] < (target_local_y - target_v_len - mid_bound) & right_side_sort["Local_Y"] > (target_local_y - target_v_len - far_bound).values[0]): # br_group = frame[((right_side_sort["Local_Y"] < (target_local_y - target_v_len - vehy) & right_side_sort["Local_Y"] > (target_local_y - target_v_len - far_bound)))] br_group = right_side_sort[(right_side_sort["Local_Y"] < (target_local_y - target_v_len - vehy)) & (right_side_sort["Local_Y"] > (target_local_y - target_v_len - far_bound))] if not br_group.empty: br = br_group.iloc[len(br_group)-1] #take the closest one br_acc = br["v_Acc"], br["Vehicle_ID"] tar_acc = target["v_Acc"].values[0], target["Vehicle_ID"].values[0] tar_lan = target["Lane_ID"].values[0], target["Vehicle_ID"].values[0] result = np.array([front_acc[0], back_acc[0], fl_acc[0], l_acc[0], bl_acc[0], fr_acc[0], r_acc[0], br_acc[0], tar_acc[0], tar_lan[0]]) ids = np.array([front_acc[1], back_acc[1], fl_acc[1], l_acc[1], bl_acc[1], fr_acc[1], r_acc[1], br_acc[1], tar_acc[1], tar_lan[1]]) return result, ids def get_acc(frame, vehicle_ids): result = [0] * len(vehicle_ids) for i in range(len(vehicle_ids)): #asdf vehicle = frame[frame["Vehicle_ID"] == vehicle_ids[i]] if not vehicle.empty: result[i] = vehicle["v_Acc"].values[0] return np.array(result) def action_detect(frame_1, frame_2, target_1, target_2): left = right = front = back = 0 # get acceleration of vehicles in current frame arr_1, ids = search_acc(frame_1, target_1) arr_1 = arr_1.astype(float) arr_2 = get_acc(frame_2, ids[: len(ids) - 1]).astype(float) arr_2 = np.append(arr_2, target_2["Lane_ID"].values[0]) # arr_2 = search_acc(frame_2, target_2).astype(float) # get acceleration of env vehicles in next frame # arr_2 = get_acc(arr_1[:len(arr_1)-2,1], frame_2).astype(float) ###print ("arr_1: {}".format(arr_1)) ###print("arr_2: {}".format(arr_2)) # acc_per = (arr_2 - arr_1) / arr_1 i = len(arr_2) # for j in range(8): # if (arr_2[j] > 0.1 and arr_2[j] < -0.1): # arr_2[j] = 0 # i -= 1 # acc_sum = sum(arr_2) # acc_per_ave = acc_sum / i for j in range(len(arr_2)-1): if (arr_2[j] > 0.1 and arr_2[j] < -0.1): arr_2[j] = 0 i -= 1 acc_sum = sum(arr_2) if not i == 0: acc_per_ave = acc_sum / i for j in range(len(arr_2)-1): if(arr_2[j] - acc_per_ave > 2 or arr_2[j] - acc_per_ave < -2): i -= 1 arr_2[j] = 0 else: acc_per_ave_drop = 0 acc_sum_drop = sum(arr_2) if not i == 0: acc_per_ave_drop = acc_sum_drop / i else: acc_per_ave_drop = 0 if((arr_2[8] - acc_per_ave_drop) >= 2): front = 1 back = 0 elif((arr_2[8] - acc_per_ave_drop) <= -2): back = 1 front = 0 target_lane_1 = int(target_1["Lane_ID"].values[0]) target_lane_2 = int(target_2["Lane_ID"].values[0]) right = left = 0 if (target_lane_1 < target_lane_2): right = 1 left = 0 elif (target_lane_1 > target_lane_2): left = 1 right = 0 result = [front, back, left, right] return result def extract_data(data, road, input_frames, target_frames, teaching_force=True): # locate all traffics given the road if not road: traffics = data else: traffics = data[data["Location"] == road] # gather all vehicle ids vehicles = traffics["Vehicle_ID"].unique() extracted = [] # extract data for each vehicle for i in vehicles: #print("Extracting data for vehicle {}...".format(i)) try: extracted_one = [None] * (input_frames + target_frames) # make sure vehicle has enough frames in data if check_frame_length(traffics, i, input_frames + target_frames): # get the starting(i.e. min) frame id as the initial frame start_frame = traffics[traffics["Vehicle_ID"] == i]["Frame_ID"].values.min() cur_frame = 0 one_row = [] while cur_frame < input_frames + target_frames: #print("Analyzing frame {} & {}...".format( # start_frame + cur_frame, start_frame + cur_frame + step)) # locate the traffics information at given frame id frame_view = traffics[traffics["Frame_ID"] == (start_frame + cur_frame)] frame_view_plus = traffics[traffics["Frame_ID"] == (start_frame + cur_frame + step)] #next fram data if frame_view.empty: raise Exception("missing frame") # get target frame info target = frame_view[frame_view["Vehicle_ID"] == i] target_plus = frame_view_plus[frame_view_plus["Vehicle_ID"] == i] if target.empty or target_plus.empty: print("Vehicle missing in frames!?!\n") break # elif len(target) > 1 or len(target_plus) > 1: # print("> 1 frame data for target vehicle?!?!") # get front vehicle frames front_id = target["Preceding"].values[0] front = frame_view[frame_view["Vehicle_ID"] == front_id] if not front.empty: front_valid = int((front['Local_Y'].values[0] - target["Local_Y"].values[0]) <= vehy)##@@@@@@ else: front_valid = 0 # get back vehicle frames back_id = target["Following"].values[0] back = frame_view[frame_view["Vehicle_ID"] == back_id] if not back.empty: back_valid = int((target["Local_Y"].values[0] - back['Local_Y'].values[0]) <= vehy)##@@@@@@ else: back_valid = 0 # search side vehicles sides = search_side(frame_view, target) # detect action for vehicles acc = action_detect(frame_view, frame_view_plus, target, target_plus) result = [start_frame + cur_frame] # result.extend(extract_feature(target)) # [target, f, b, bl, l, fl, br, r, fr] # if front_valid: # result.extend(0) # else: # result.extend(1) # if back_valid: # result.extend(0) # else: # result.extend(1) result.append(front_valid) result.append(back_valid) result.extend(sides) result.extend(acc) # for c in sides: # if c is None: # result.extend([0 for i in range(6)]) # else: # result.extend(extract_feature(c)) one_row.append(result) if not result[11] == 0: print(one_row) #extracted_one[cur_frame] = one_row # go to next frame cur_frame += step #print("Extract data of {0}\n".format(i)) # pd.DataFrame(data=transform(np.array(one_row)[250:, 2:])).to_csv("{0}.csv".format(front_id)) extracted.append(one_row) # print(extracted) else: print("Not enough frames!\n") except Exception as e: # print(e) traceback.print_exc() continue return extracted def transform(traj_data): ''' frame_id, x, y, velocity, type type=-1 represents target car ''' result = [] for frame in range(len(traj_data)): f = traj_data[frame] result.append([frame, f[1], f[2], f[0], -1]) for car in range(1, 9): if f[car:car+3] != empty_car: result.append([frame, f[car*4+1], f[car*4+2], f[car*4], f[car*4+3]]) return result def main(argv): input_file = "" try: opts, args = getopt.getopt(argv, "r:i:", ["road=", "ifile="]) except getopt.GetoptError: print("Invalid argument.") exit(2) for opt, arg in opts: if opt in ["-i", "--ifile"]: input_file = arg else: print("Invalid argument.") exit(2) output_file = "{0}.npy".format(input_file.split(".")[0]) print("read file", input_file) print("output to", output_file) data = pd.read_csv(input_file) data_new = discard_wrong_lane(data) result = extract_data(data_new, "us-101", 500, 0) np.array(result).dump(open(output_file, "wb")) pd.DataFrame(np.array(result)).to_csv('{0}_1.csv'.format(input_file.split(".")[0])) if __name__ == '__main__': main(sys.argv[1:]) def action_detect_wrong(frame_1, frame_2, target): left = right = front = back = 0 array_1 = search_acc(frame_1, target).astype(float) arr_2 = search_acc(frame_2, target).astype(float) acc_per = (arr_2 - array_1) / array_1 i = 9 for j in range(8): if (acc_per[j] > 0.1 and acc_per[j] < -0.1): acc_per[j] = 0 i -= 1 acc_per_sum = [sum(acc_per[i]) for i in range(8)] acc_per_ave = acc_per_sum / i if((acc_per[9] - acc_per_ave) > 0.1): front = 1 elif((acc_per[9] - acc_per_ave) < -0.1): back = 1 # sum([acc_per[0], [acc_per[1], [acc_per[2], [acc_per[3], [acc_per[4], [acc_per[5], [acc_per[6], [acc_per[7]]) if(array_1[len(array_1) - 1] < arr_2[len(arr_2) - 1]): right = 1 elif(array_1[len(array_1) - 1] > arr_2[len(arr_2) - 1]): left = 1 result = [front, back, left, right] return result