def save_phase_data(bin_path, save_path, start_bin, end_bin, num_frames, chirp_index=5, is_diff=True): if is_diff: num_frames -= 1 # load Numpy Data adc_data = np.fromfile(bin_path, dtype=np.int16) adc_data = adc_data.reshape(numFrames, -1) adc_data = np.apply_along_axis(DCA1000.organize, 1, adc_data, num_chirps=numChirpsPerFrame, num_rx=numRxAntennas, num_samples=numADCSamples) range_data = dsp.range_processing(adc_data, window_type_1d=Window.BLACKMAN) range_data = arange_tx(range_data, num_tx=numTxAntennas) range_data = range_data[:, chirp_index, :, start_bin:end_bin] range_data = range_data.transpose((1, 2, 0)) # angle and unwrap sig_phase = np.angle(range_data) sig_phase = np.unwrap(sig_phase) # save file np.save(save_path, sig_phase) print("{} npy file saved!".format(save_path))
def range_cube(self): if self.__range_cube is not None: return self.__range_cube else: range_cube = dsp.range_processing(self.raw_cube) self.__range_cube = np.swapaxes(range_cube, 0, 2) return self.__range_cube
def plot_heatmap(adc_data_path, bin_start=4, bin_end=14, diff=False, remove_clutter=True, cumulative=False): num_bins = bin_end - bin_start npy_azi = np.zeros((numFrames, ANGLE_BINS, num_bins)) npy_ele = np.zeros((numFrames, ANGLE_BINS, num_bins)) adc_data = np.fromfile(adc_data_path, dtype=np.int16) adc_data = adc_data.reshape(numFrames, -1) adc_data = np.apply_along_axis(DCA1000.organize, 1, adc_data, num_chirps=numChirpsPerFrame, num_rx=numRxAntennas, num_samples=numADCSamples) # Start DSP processing range_azimuth = np.zeros((ANGLE_BINS, BINS_PROCESSED)) range_elevation = np.zeros((ANGLE_BINS, BINS_PROCESSED)) num_vec, steering_vec = dsp.gen_steering_vec(ANGLE_RANGE, ANGLE_RES, VIRT_ANT_AZI) num_vec_ele, steering_vec_ele = dsp.gen_steering_vec(ANGLE_RANGE, ANGLE_RES, VIRT_ANT_ELE) if cumulative: cum_azi = np.zeros((ANGLE_BINS, num_bins)) cum_ele = np.zeros((ANGLE_BINS, num_bins)) if diff: pre_h = np.zeros((ANGLE_BINS, num_bins)) pre_e = np.zeros((ANGLE_BINS, num_bins)) for frame_index in range(numFrames): """ 1 (Range Processing) """ frame = adc_data[frame_index] # --- range fft radar_cube = dsp.range_processing(frame) # range_bin_idx = 5 # radar_cube to """ 2 (Capon Beamformer) """ # --- static clutter removal # --- Do we need ? if remove_clutter: mean = radar_cube.mean(0) radar_cube = radar_cube - mean # --- capon beamforming beamWeights = np.zeros((VIRT_ANT_AZI, BINS_PROCESSED), dtype=np.complex_) radar_cube_azi = np.concatenate((radar_cube[0::numTxAntennas, ...], radar_cube[1::numTxAntennas, ...]), axis=1) # 4 virtual antenna # radar_cube_azi = radar_cube[0::numTxAntennas, ...] # Note that when replacing with generic doppler estimation functions, radarCube is interleaved and # has doppler at the last dimension. for i in range(BINS_PROCESSED): range_azimuth[:, i], beamWeights[:, i] = dsp.aoa_capon(radar_cube_azi[:, :, i].T, steering_vec, magnitude=True) # --- capon beamforming elevation (3,5) beamWeights_ele = np.zeros((VIRT_ANT_ELE, BINS_PROCESSED), dtype=np.complex_) radar_cube_ele = np.concatenate( (radar_cube[0::numTxAntennas, 2:3, ...], radar_cube[2::numTxAntennas, 0:1, ...]), axis=1) for i in range(BINS_PROCESSED): range_elevation[:, i], beamWeights_ele[:, i] = dsp.aoa_capon(radar_cube_ele[:, :, i].T, steering_vec_ele, magnitude=True) """ 3 (Object Detection) """ heatmap_azi = np.log2(range_azimuth[:, bin_start:bin_end]) heatmap_ele = np.log2(range_elevation[:, bin_start:bin_end]) if cumulative: cum_azi += heatmap_azi cum_ele += heatmap_ele if diff: heatmap_azi = heatmap_azi - pre_h heatmap_ele = heatmap_ele - pre_e pre_h = heatmap_azi pre_e = heatmap_ele # normalize heatmap_azi = heatmap_azi / heatmap_azi.max() heatmap_ele = heatmap_ele / heatmap_ele.max() npy_azi[frame_index] = heatmap_azi npy_ele[frame_index] = heatmap_ele return npy_azi, npy_ele
def plot_heatmap_capon(adc_data_path, save_path, bin_start=4, bin_end=14, diff=False, is_log=False, remove_clutter=True, cumulative=False): num_bins = bin_end - bin_start npy_azi = np.zeros((numFrames, ANGLE_BINS, num_bins)) npy_ele = np.zeros((numFrames, ANGLE_BINS, num_bins)) adc_data = np.fromfile(adc_data_path, dtype=np.int16) adc_data = adc_data.reshape(numFrames, -1) adc_data = np.apply_along_axis(DCA1000.organize, 1, adc_data, num_chirps=numChirpsPerFrame, num_rx=numRxAntennas, num_samples=numADCSamples) # Start DSP processing range_azimuth = np.zeros((ANGLE_BINS, BINS_PROCESSED)) range_elevation = np.zeros((ANGLE_BINS, BINS_PROCESSED)) num_vec, steering_vec = dsp.gen_steering_vec(ANGLE_RANGE, ANGLE_RES, VIRT_ANT_AZI) num_vec_ele, steering_vec_ele = dsp.gen_steering_vec(ANGLE_RANGE, ANGLE_RES, VIRT_ANT_ELE) if cumulative: cum_azi = np.zeros((ANGLE_BINS, num_bins)) cum_ele = np.zeros((ANGLE_BINS, num_bins)) if diff: pre_h = np.zeros((ANGLE_BINS, num_bins)) pre_e = np.zeros((ANGLE_BINS, num_bins)) for frame_index in range(numFrames): frame = adc_data[frame_index] radar_cube = dsp.range_processing(frame) # virtual antenna arrangement radar_cube = arange_tx(radar_cube, num_tx=numTxAntennas, vx_axis=1, axis=0) # --- static clutter removal if remove_clutter: mean = radar_cube.mean(0) radar_cube = radar_cube - mean # --- capon beamforming radar_cube_azi = radar_cube[:, VIRT_ANT_AZI_INDEX, :] radar_cube_ele = radar_cube[:, VIRT_ANT_ELE_INDEX, :] # Note that when replacing with generic doppler estimation functions, radarCube is interleaved and # has doppler at the last dimension. for i in range(BINS_PROCESSED): range_azimuth[:, i], _ = dsp.aoa_capon(radar_cube_azi[:, :, i].T, steering_vec, magnitude=True) range_elevation[:, i], _ = dsp.aoa_capon(radar_cube_ele[:, :, i].T, steering_vec_ele, magnitude=True) """ 3 (Object Detection) """ if is_log: heatmap_azi = 20 * np.log10(range_azimuth[:, bin_start:bin_end]) heatmap_ele = 20 * np.log10(range_elevation[:, bin_start:bin_end]) else: heatmap_azi = range_azimuth[:, bin_start:bin_end] heatmap_ele = range_elevation[:, bin_start:bin_end] if cumulative: cum_azi += heatmap_azi cum_ele += heatmap_ele if diff: heatmap_azi = heatmap_azi - pre_h heatmap_ele = heatmap_ele - pre_e pre_h = heatmap_azi pre_e = heatmap_ele # normalize # heatmap_azi = heatmap_azi / heatmap_azi.max() # heatmap_ele = heatmap_ele / heatmap_ele.max() npy_azi[frame_index] = heatmap_azi npy_ele[frame_index] = heatmap_ele save_path_azi = save_path + "_azi" save_path_ele = save_path + "_ele" np.save(save_path_azi, npy_azi) np.save(save_path_ele, npy_ele) print("{} npy file saved!".format(save_path))
def featureExtraction(folder, optPath): """ Return opt: numFrame, 3 (heatmaps), 46*46(angle bin), nLoopsPerFrame """ startTime = '' with open(folder+'adc_data_Raw_LogFile.csv') as csv_file: csv_reader = csv.reader(csv_file, delimiter=',') for row in csv_reader: if 'Capture start time' in str(row): startTimeRow = row break startTimeStr = startTimeRow[0].split(' - ')[1] timestamp = datetime.datetime.timestamp(parser.parse(startTimeStr)) timestampList = [] filename = folder + 'adc_data.bin' numFrames = 640 numADCSamples = 512 numTxAntennas = 2 numRxAntennas = 4 numLoopsPerFrame = 76 numChirpsPerFrame = numTxAntennas * numLoopsPerFrame BINS_PROCESSED = 55 ANGLE_RES = 1 ANGLE_RANGE = 70 ANGLE_BINS = (ANGLE_RANGE * 2) // ANGLE_RES + 1 reso = dsp.range_resolution(numADCSamples, dig_out_sample_rate=6000, freq_slope_const=39.010) reso = round(reso[0], 4) adc_data = np.fromfile(filename, dtype=np.uint16) # (1) Load Data if adc_data.shape[0]<398458880: padSize = 398458880 - adc_data.shape[0] print("padded size: ", padSize) adc_data = np.pad(adc_data, padSize)[padSize:] adc_data = adc_data.reshape(numFrames, -1) adc_data = np.apply_along_axis(DCA1000.organize, 1, adc_data, num_chirps=numChirpsPerFrame, num_rx=numRxAntennas, num_samples=numADCSamples) heatmaps = np.zeros((adc_data.shape[0], ANGLE_BINS, ANGLE_BINS), dtype = 'float32') numVirAntHori = 3 numVirAntVer = 4 # (2) Start DSP processing num_vec_4va, steering_vec_4va = dsp.gen_steering_vec(ANGLE_RANGE, ANGLE_RES, numVirAntVer) num_vec_3va, steering_vec_3va = dsp.gen_steering_vec(ANGLE_RANGE, ANGLE_RES, numVirAntHori) # (3) Process each frame for i, frame in enumerate(adc_data): timestamp+=0.033 timestampList.append(timestamp) range_azimuth = np.zeros((ANGLE_BINS, BINS_PROCESSED-10)) range_azimuth2 = np.zeros((ANGLE_BINS, BINS_PROCESSED-10)) range_elevation = np.zeros((ANGLE_BINS, BINS_PROCESSED-10)) # Range Processing radar_cube = dsp.range_processing(frame, window_type_1d=Window.BLACKMAN) """ (Capon Beamformer) """ # --- static clutter removal / normalize mean = radar_cube.mean(0) radar_cube = radar_cube - mean # --- capon beamforming beamWeights_azimuth = np.zeros((numVirAntHori, BINS_PROCESSED), dtype=np.complex_) beamWeights_azimuth2 = np.zeros((numVirAntHori, BINS_PROCESSED), dtype=np.complex_) beamWeights_elevation = np.zeros((numVirAntVer, BINS_PROCESSED), dtype=np.complex_) # Separate TX, rx 1234, vrx1234 radar_cube = np.concatenate((radar_cube[0::2, ...], radar_cube[1::2, ...]), axis=1) # Note that when replacing with generic doppler estimation functions, radarCube is interleaved and # has doppler at the last dimension. # Range bin processed for j in range(10,BINS_PROCESSED): range_azimuth[:, j-10], beamWeights_azimuth[:, j-10] = dsp.aoa_capon( radar_cube[:, 1:4 , j-10].T, steering_vec_3va, magnitude=True) range_azimuth2[:, j-10], beamWeights_azimuth2[:, j-10] = dsp.aoa_capon( radar_cube[:, 5:8 , j-10].T, steering_vec_3va, magnitude=True) range_elevation[:, j-10], beamWeights_elevation[:, j-10] = dsp.aoa_capon( radar_cube[:, [0,4,1,5] , j-10].T, steering_vec_4va, magnitude=True) # normalize prescale_factor = 10000000 range_azimuth = scale(range_azimuth/prescale_factor, axis = 1) range_azimuth2 = scale(range_azimuth2/prescale_factor, axis = 1) range_elevation = scale(range_elevation/prescale_factor, axis = 1) range_azimuth = resize(range_azimuth, (ANGLE_BINS, ANGLE_BINS/3)) range_azimuth2 = resize(range_azimuth2, (ANGLE_BINS, ANGLE_BINS/3)) range_elevation = resize(range_elevation, (ANGLE_BINS, ANGLE_BINS/3)) heatmaps[i,:,:] = np.concatenate((range_azimuth, range_azimuth2, range_elevation), axis = 1) # opt heatmaps=heatmaps.astype('float32') if np.isnan(heatmaps).sum() + np.isinf(heatmaps).sum() > 0: print('dtype: ', heatmaps.dtype, ', has NAN or INF error') else: print('dtype: ', heatmaps.dtype) if optPath != '': # if not os.path.isdir(optPath + '//'): # os.mkdir(optPath + '//') np.savez(optPath+'.npz', heatmaps=heatmaps, timestampList=timestampList) return heatmaps, np.array(timestampList), reso
def range_doppler_process2(dir_name, num_samples=256, num_chirps=64, num_tx=1, num_rx=4, frames_per_second=10): # parameters header_size = 32 # define video writing object frame_width = num_samples # // 2 # To remove the part correpsonding to negative frequencies frame_height = num_chirps save_path = '/mnt/c/work/rcube_extract/dca_capture/video_write/' video_file = save_path + dir_name.split('/')[-1] + '.avi' out = cv2.VideoWriter(video_file, cv2.VideoWriter_fourcc('M','J','P','G'), frames_per_second, (frame_width,frame_height), isColor=False) # read all the data files present in the folder # Note: radarcube axes [fast time, slow time, channels, frames (time progression)] file_index = 0 prev_file_data = np.array([]) hsi_header = [2780, 3290, 2780, 3290, 48, 1, 0, 0, 1731, 32, 515, 512, 271, 1, 512, 0] packet_len = num_samples * num_rx * 2 + 32 data_files = glob.glob(dir_name + '/datacard_record_hdr_0ADC*.bin') # print(data_files) for files in data_files: raw_data = np.fromfile(files, dtype=np.int16) raw_appended = np.insert(raw_data, 0, prev_file_data) #insert in the beginning # sanity check error1 = np.array_equal(raw_appended[0 : np.size(hsi_header)], hsi_header) == 0 error2 = np.array_equal(raw_appended[packet_len:packet_len+np.size(hsi_header)], hsi_header) == 0 if error1 or error2: print('Something wrong with data unwrapping!') rcube, next_frame_data = raw_radarcube(raw_appended, num_samples, num_chirps, num_rx, header_size) # range-doppler proessing of the raw data axis_range = 0 axis_doppler = 1 rcube_fft1 = range_processing(rcube, window_type_1d=Window.HAMMING, axis=axis_range) accumulateStatus = False rcube_fft2 = doppler_processing_custom(rcube_fft1, num_tx=1, clutter_removal_enabled=True, interleaved=False, window_type_2d=Window.HAMMING, accumulate=accumulateStatus, axis=axis_doppler) # convert to proper format # (2.3) transpose to obtain dopper axis as first dimension # if accumulate false, then select first channel if accumulateStatus: rcube_fft2_tr = np.transpose(rcube_fft2, (1,0,2)) else: rcube_fft2_tr = np.transpose(rcube_fft2[:,:,0,:], (1,0,2)) print('rcube dimensions : ' + str(rcube_fft2_tr.shape)) # video_in = rcube_fft2_tr[:, :num_samples//2, :] # to remove the part correpsonding to negative frequencies video_in = rcube_fft2_tr # for full range bins video # print(video_in.shape) # plot sample images # plt.imshow(video_in[:,:,1]) # plt.show() # normalize and write the frame to video object for frame in range(video_in.shape[2]): # img_normalize = cv2.normalize(src=video_in[:, :, frame], dst=None, alpha=0, beta=255, norm_type=cv2.NORM_L1, dtype=cv2.CV_8U) min = np.amin(video_in[:, :, frame], (0,1)) max = np.amax(video_in[:, :, frame], (0,1)) img_normalize = (video_in[:, :, frame] - min) / (max - min) img_normalize = np.round(img_normalize * 255).astype(np.uint8) out.write(img_normalize) if frame == 0 and file_index == 1: print(img_normalize) prev_file_data = next_frame_data file_index += 1 # release the video object out.release() print('range-doppler video written successfully ...') return
chair_avg = np.average(np.stack([chair_1, chair_2, chair_3]), axis=0) tot_empty = np.average(np.stack([chair_avg, empty_avg]), axis=0) all_data, range_res, velocity_res = load_file("data/data_0312/moved_Raw_0.bin") all_data_2, range_res, velocity_res = load_file("data/old/blanket.bin") # range_res = RANGE_RESOLUTION # all_data = all_data_2 # all_data_2 = all_data_2 - chair_avg # all_data = np.maximum(chair_avg - empty_avg,0) # Apply the range resolution factor to the range indices ranges = np.arange(adc_samples) * range_res chair_range_plot = dsp.range_processing(chair_avg, window_type_1d=Window.HAMMING) range_plot = dsp.range_processing(all_data, window_type_1d=Window.HAMMING) range_plot_2 = dsp.range_processing(all_data_2, window_type_1d=Window.HAMMING) # range_plot -= empty_avg # range_plot = range_plot - np.mean(range_plot,axis=0) powers = abs(range_plot) vmin = powers.min() vmax = powers.max() norm = colors.Normalize(vmin=vmin, vmax=vmax) ax = fig.add_subplot(111)
1, adc_data, num_chirps=numChirpsPerFrame, num_rx=numRxAntennas, num_samples=numADCSamples) dataCube = np.copy(adc_data) print("Data Loaded!") from mmwave.dsp.utils import Window # figure preparation fig, axes = plt.subplots(3, 2, figsize=(120, 60)) # (1) processing range data # window types : Bartlett, Blackman p, Hanning p and Hamming range_data = dsp.range_processing(adc_data, window_type_1d=Window.BLACKMAN) range_data_copy = np.copy(range_data) selected_range_data = range_data[:, :, 3, :numDisplaySamples] # plot range profile range_profile = selected_range_data.reshape((-1, numDisplaySamples)) axes[0, 0].imshow(np.abs(range_profile).T, interpolation='nearest', aspect='auto') # (2) variance magnitude determine argmax var = np.var(np.abs(selected_range_data), axis=(0, 1)) # bin_index = np.argmax(var, axis=0) # plot variance axes[0, 1].bar(np.arange(0, numDisplaySamples), var)
def range_doppler_process( self, dir_name, save_path='/mnt/c/work/rcube_extract/dca_capture/video_write/'): """ Compute range-doppler fft on raw data and save the output as a video Inputs: - data specifications provided with class instantiation - full filename of the data directory - save path Outputs: - None """ # (1) define video writing object # (1.1) video specs frame_width = self.num_samples # // 2 # To remove the part correpsonding to negative frequencies frame_height = self.num_chirps video_file = save_path + dir_name.split('/')[-1] + '.avi' # (1.2) instantiate video writer object out = cv2.VideoWriter(video_file, cv2.VideoWriter_fourcc('M', 'J', 'P', 'G'), self.frames_per_second, (frame_width, frame_height), isColor=False) # (2) implement range-doppler processing axis_range = 0 axis_doppler = 1 # (2.1) initiate the raw_data generator function raw_data = self.raw_data_cube(dir_name) data_status = True while data_status: rcube = next(raw_data, []) # output 0 when no done reading all data files data_status = np.size(rcube) if len(rcube) == 0: break # (2.2) peform range-doppler ffts rcube_fft1 = range_processing(rcube, window_type_1d=Window.HAMMING, axis=axis_range) accumulateStatus = False rcube_fft2 = doppler_processing_custom( rcube_fft1, num_tx=1, clutter_removal_enabled=True, interleaved=False, window_type_2d=Window.HAMMING, accumulate=accumulateStatus, axis=axis_doppler) # (2.3) transpose to obtain dopper axis as first dimension # if accumulate false, then select first channel if accumulateStatus: rcube_fft2_tr = np.transpose(rcube_fft2, (1, 0, 2)) else: rcube_fft2_tr = np.transpose(rcube_fft2[:, :, 0, :], (1, 0, 2)) # (2.4) select range spectrum in video and compute magnitude of complex data # video_in = np.abs(rcube_fft2_tr[:, :num_samples//2, :]) # remove negative frequencies video_in = np.abs(rcube_fft2_tr) # for full range spectrum # print(video_in.shape) # plot sample images # plt.imshow(video_in[:,:,1]) # plt.show() # (2.5) normalize and write the frame to video object for frame in range(video_in.shape[2]): # (2.5.1) normalize to [0, 255] for each frame # img_normalize = cv2.normalize(src=video_in[:, :, frame], dst=None, alpha=0, beta=255, norm_type=cv2.NORM_L1, dtype=cv2.CV_8U) min = np.amin(video_in[:, :, frame], (0, 1)) max = np.amax(video_in[:, :, frame], (0, 1)) img_normalize = (video_in[:, :, frame] - min) / (max - min) img_normalize = np.round(img_normalize * 255).astype(np.uint8) out.write(img_normalize) #if frame == 0: # // for debugging # print(img_normalize) # (3) release the video object out.release() print('range-doppler video written successfully ...\n') return
MapRecord(x.strip().split(), root_path) for x in open(annotaton_path) ] half_attention = True plot_debug = True for record in record_list: if record.index_err == 1: adc_data = np.fromfile(record.path, dtype=np.int16) adc_data = adc_data.reshape(numFrames, -1) adc_data = np.apply_along_axis(DCA1000.organize, 1, adc_data, num_chirps=numChirpsPerFrame, num_rx=numRxAntennas, num_samples=numADCSamples) print("{} >> Data Loaded!".format(record.path)) # processing range data range_data = dsp.range_processing(adc_data, window_type_1d=Window.HANNING) # reshape frame data range_data = arange_tx(range_data, num_tx=numTxAntennas) b_index = 8 out = peak_detection(range_data[..., b_index], half=half_attention, plot=plot_debug)
adc_data = adc_data.reshape(numFrames, -1) adc_data = np.apply_along_axis(DCA1000.organize, 1, adc_data, num_chirps=numChirpsPerFrame, num_rx=numRxAntennas, num_samples=numADCSamples) print("Data Loaded!") # data segmentation # adc_data = adc_data[0:220,:,0,:] adc_data = adc_data[:, :, 0, :] from mmwave.dsp.utils import Window # processing data adc_data = dsp.range_processing(adc_data, window_type_1d=None) frame_data = adc_data.reshape((-1, numADCSamples)) plt.imshow(np.abs(frame_data).T, interpolation='nearest', aspect='auto') plt.ylabel('Range Bins') plt.title('Interpreting a Single Frame - Range') plt.show() print("") # get the duration of eye blinking # adc_data = adc_data[290:291, :, 1, :] # buffer = [] # for frame in adc_data: # radar_cube = dsp.range_processing(frame) # range_plot = adc_data.reshape((-1, numADCSamples)) # fig, axes = plt.subplots(1, 1, figsize=(80,100)) # range_plot = radar_cube[:, 0, :]
from mmwave import dsp # Radar specific parameters from mmwave.dsp import Window from radar_utils.data_loader import load_file from dsp_utils import extract_phases from etc.config_1 import adc_samples, NUM_FRAMES from filter_params import dist_range_bottom, dist_range_top, all_data, freq_range_top, freq_range_bottom, \ slow_sample_rate, time_filter_bottom, time_filter_top from plot_utils import plot_named_list, plot_range_maps data, range_res, vel_res = load_file("data/010121/adc_data_Raw_0.bin") data_avgd = np.average(data, axis=1) data_first = data[:, 0, :] range_map = dsp.range_processing(data_first, Window.HANNING) ranges = np.arange(adc_samples) * range_res range_mask = (dist_range_bottom < ranges) & (ranges < dist_range_top) ranges_filtered = ranges[range_mask] range_plot_filtered = range_map[:, range_mask] powers = np.sqrt(range_plot_filtered.imag**2 + range_plot_filtered.real**2) print(np.max(powers)) plot_range_maps({"multi": powers}) avg_power = np.average(powers, axis=0) plt.plot(ranges_filtered, avg_power) plt.show()
# name: load_file(all_data[name])[0] for name in data_set "stationary": table } # working_data = { # "nimrod_minus_empty_-10db": raw_data["nimrod_10_1"] - raw_data["empty_10_1"] # } # data, range_res, vel_res = load_file("data/010121/adc_data_Raw_0.bin") # data_avgd = np.average(data, axis=1) # working_data = {"avg" : data_avgd} range_maps = { name: dsp.range_processing(raw, window_type_1d=Window.HANNING) for name, raw in working_data.items() } # range_maps = working_data range_maps_filtered = { name: rtm[:, range_mask] for name, rtm in range_maps.items() } raw_power_maps = { name: np.sqrt(rtm.imag**2 + rtm.real**2) for name, rtm in working_data.items() }
if load_data: adc_data = np.fromfile('./data/circle.bin', dtype=np.uint16) adc_data = adc_data.reshape(NUM_FRAMES, -1) all_data = np.apply_along_axis(DCA1000.organize, 1, adc_data, num_chirps=NUM_CHIRPS*2, num_rx=NUM_RX, num_samples=NUM_ADC_SAMPLES) # Start DSP processing range_azimuth = np.zeros((ANGLE_BINS, BINS_PROCESSED)) num_vec, steering_vec = dsp.gen_steering_vec(ANGLE_RANGE, ANGLE_RES, VIRT_ANT) tracker = EKF() for frame in all_data: """ 1 (Range Processing) """ # --- range fft radar_cube = dsp.range_processing(frame) """ 2 (Capon Beamformer) """ # --- static clutter removal mean = radar_cube.mean(0) radar_cube = radar_cube - mean # --- capon beamforming beamWeights = np.zeros((VIRT_ANT, BINS_PROCESSED), dtype=np.complex_) radar_cube = np.concatenate((radar_cube[0::2, ...], radar_cube[1::2, ...]), axis=1) # Note that when replacing with generic doppler estimation functions, radarCube is interleaved and # has doppler at the last dimension. for i in range(BINS_PROCESSED): range_azimuth[:,i], beamWeights[:,i] = dsp.aoa_capon(radar_cube[:, :, i].T, steering_vec, magnitude=True)
def micro_doppler_stft( self, dir_name, max_velocity, save_path='/mnt/c/work/rcube_extract/dca_capture/micro_doppler/'): ''' Steps for short-time Fourier tranform based micro-Doppler processing: 1. Perform windowing and fft in range for each frame 2. Compress over range in each frame 3. Perform windowing followed by fft in Doppler Inputs: - data specifications provided with class instantiation - full filename of data directory - path to save micro-doppler image Outputs: - numpy array of micro-doppler spectrogram ''' # (0) variables and parameters axis_range = 0 axis_doppler = 0 # range axis is removed during range accumulation data_status = True micro_doppler_spectrum = np.zeros((self.num_chirps, 0)) # (1) instantiate the raw_data generator raw_data = self.raw_data_cube(dir_name) # print(type(raw_data)) # (2) keep appending micro-doppler spectrogram while data_status is active while data_status: # (2.0) read the next data_cube from generator data_cube = next(raw_data, [0]) # (2.1) perform range-fft and sum over range axis if len(data_cube) == 1: break data_cube_fft1 = range_processing(data_cube, window_type_1d=Window.HAMMING, axis=axis_range) data_range_accum = np.sum(data_cube_fft1, axis=axis_range) # print(data_range_accum.shape) # (2.2) perform doppler-fft accumulateStatus = True micro_doppler_file_raw = doppler_processing_custom( data_range_accum, num_tx=1, clutter_removal_enabled=True, interleaved=False, window_type_2d=Window.HAMMING, accumulate=accumulateStatus, axis=axis_doppler) # (2.3) resize based on accumulation status and compute magnitude of complex data if accumulateStatus: micro_doppler_file = np.abs(micro_doppler_file_raw) else: micro_doppler_file = np.abs( micro_doppler_file_raw[:, 0, :]) # first channel selected micro_doppler_spectrum = np.append(micro_doppler_spectrum, micro_doppler_file, axis=1) print('micro-doppler dimensions: ' + str(micro_doppler_spectrum.shape)) # update the active status for next iteration data_status = np.size(data_cube) # (3) image is names as the raw_data directory image_name = dir_name.split('/')[-1] save_file = save_path + image_name + '.jpg' plt.imshow(micro_doppler_spectrum, aspect=2, extent=[ 0, micro_doppler_spectrum.shape[1] / self.frames_per_second, -max_velocity, max_velocity ], cmap='gnuplot2') plt.ylabel('velocity [m/s]') plt.xlabel('time [s]') plt.colorbar(label='log scale') plt.savefig(save_file, dpi=1000, bbox_inches='tight', pad_inches=0.1) plt.close() print('micro-doppler image written successfully ...\n') return micro_doppler_spectrum
label = np.zeros(num_data) index = 0 for l, e in enumerate(emotion_list): for i in range(start_index, end_index): bin_path = data_path.format(e, i) # load data adc_data = np.fromfile(bin_path, dtype=np.int16) adc_data = adc_data.reshape(numFrames, -1) adc_data = np.apply_along_axis(DCA1000.organize, 1, adc_data, num_chirps=numChirpsPerFrame, num_rx=numRxAntennas, num_samples=numADCSamples) range_data = dsp.range_processing(adc_data, window_type_1d=Window.BLACKMAN) range_data = range_data[..., bin_index] sig = range_data.reshape( (-1, numTxAntennas, numLoopsPerFrame, numRxAntennas)) sig = sig[:, :, chirp_index, :] c_data = np.zeros((len(antenna_order), numSample)) for c_i, o in enumerate(antenna_order): va_order = o - 1 t, r = virtual_array[va_order] t, r = tx_map[t], r - 1 va_sig = sig[:, t, r] va_phase = np.angle(va_sig) va_unwrap_phase = np.unwrap(va_phase)
def generate_spectrum_from_RDC(filename, numFrames=500, numADCSamples=128, numTxAntennas=3, numRxAntennas=4, numLoopsPerFrame=128, numAngleBins=64, chirpPeriod=0.06, logGabor=False, accumulate=True, save_full=False): numChirpsPerFrame = numTxAntennas * numLoopsPerFrame # ============================================================================= # numADCSamples = number of range bins # numLoopsPerFrame = number of doppler bins # ============================================================================= range_resolution, bandwidth = dsp.range_resolution(numADCSamples) doppler_resolution = dsp.doppler_resolution(bandwidth) if filename[-4:] != '.bin': filename += '.bin' adc_data = np.fromfile(filename, dtype=np.int16) adc_data = adc_data.reshape(numFrames, -1) adc_data = np.apply_along_axis(DCA1000.organize, 1, adc_data, num_chirps=numChirpsPerFrame, num_rx=numRxAntennas, num_samples=numADCSamples) print("Data Loaded!") dataCube = adc_data micro_doppler_data = np.zeros((numFrames, numLoopsPerFrame, numADCSamples), dtype=np.float64) theta_data = np.zeros((numFrames, numLoopsPerFrame, numTxAntennas * numRxAntennas, numADCSamples), dtype=np.complex) for i, frame in enumerate(dataCube): # (2) Range Processing from mmwave.dsp.utils import Window radar_cube = dsp.range_processing(frame, window_type_1d=Window.BLACKMAN) assert radar_cube.shape == ( numChirpsPerFrame, numRxAntennas, numADCSamples), "[ERROR] Radar cube is not the correct shape!" # (3) Doppler Processing det_matrix, theta_data[i] = dsp.doppler_processing( radar_cube, num_tx_antennas=3, clutter_removal_enabled=True, window_type_2d=Window.HAMMING) # --- Shifts & Store det_matrix_vis = np.fft.fftshift(det_matrix, axes=1) micro_doppler_data[i, :, :] = det_matrix_vis # Data should now be ready. Needs to be in micro_doppler_data, a 3D-numpy array with shape [numDoppler, numRanges, numFrames] # LOG GABOR if logGabor: if accumulate: image = micro_doppler_data.sum(axis=1).T else: image = micro_doppler_data.T from LogGabor import LogGabor import holoviews as hv lg = LogGabor("default_param.py") lg.set_size(image) lg.pe.datapath = 'database/' image = lg.normalize(image, center=True) # display input image # hv.Image(image) # display log gabor'd image image = lg.whitening(image) * lg.mask hv.Image(image) uDoppler = image elif accumulate: uDoppler = micro_doppler_data.sum(axis=1).T else: uDoppler = micro_doppler_data.T if save_full: return range_resolution, doppler_resolution, uDoppler, theta_data else: return range_resolution, doppler_resolution, uDoppler
from mmwave.dsp import Window from radar_utils.data_loader import load_file from etc.config_1 import adc_samples, NUM_CHIRPS fig = plt.figure() # Discard Rx axis all_data, range_res, velocity_res = load_file("data/mom_1_Raw_0.bin") # Apply the range resolution factor to the range indices ranges = np.arange(adc_samples) * range_res partial_stacked = np.vstack(all_data[500:600]) range_plot = dsp.range_processing(partial_stacked, window_type_1d=Window.HAMMING) # for rbin in range(20, 50): # # Select middle frame, at ~1.6m range bin # range_plot_target = range_plot.T[rbin] # phases = np.arctan2(range_plot_target.imag, range_plot_target.real) # # plt.plot(np.arange(NUM_CHIRPS*100), phases) # plt.title(rbin * range_res) # plt.show() best_bin_idx = 37 range_plot_target = range_plot.T[best_bin_idx] phases = np.arctan2(range_plot_target.imag, range_plot_target.real) # y = butter_bandpass_filter(phases, 0.1, 0.6, 4000 * 1000, order=6) # plt.plot(np.arange(NUM_CHIRPS * 100), y)
rcube = organize(raw_data, num_chirps, num_rx, num_samples, header_size) print('radarcube dimensions: ' + str(rcube.shape)) rcube_formattime = time_ms() print('rcube formatting time: ' + str(rcube_formattime - start_time) + ' ms\n') ''' Now, start processing the data. Firstly, perform 2-D FFT to obtain range-Doppler FFT plot. Save the output as video for interpretation and further use. Also, create plot for verification of range-Doppler FFT. ''' axis_range = 0 axis_doppler = 1 rcube_fft1 = range_processing(rcube, window_type_1d=None, axis=axis_range) rcube_fft2 = doppler_processing_custom(rcube_fft1, num_tx_antennas=1, clutter_removal_enabled=False, interleaved=False, window_type_2d=None, accumulate=False, axis=axis_doppler) print('accumulated rcube dimensions: ' + str(rcube_fft2.shape)) fft_processtime = time_ms() print('fft processing time: ' + str(fft_processtime - rcube_formattime) + ' ms\n') ''' Write the output as a video ''' # convert to proper format rcube_fft2_tr = np.transpose(rcube_fft2, (1,0,2)) video_in = rcube_fft2_tr #[:, :num_samples//2, :] print(video_in.shape) # plot sample images