RangineniBalaji / Heart-rate-and-Breath-rate-estimation-using-Infenon-Radar

5 stars 1 forks source link

What radar model was used in the project? #2

Open 909ma opened 7 months ago

909ma commented 7 months ago

My radar model is the Infineon DEMO BGT60TR13C (60GHz sensor), along with Fusion GUI version 3.5.4.202310251420.

I encountered an issue at the initial stage of processing the data extracted(I'm in the process of converting the recorded numpy file to fit the code.). The shape of my numpy file is (450, 3, 128, 128), indicating that I recorded 450 frames, with 3 antennas transmitting 128 chirps per frame, and each chirp comprising 128 samples.

Upon reshaping it to (450, 16384) and attempting to proceed, I noticed a significant discrepancy between my values and yours.

Since my radar antenna receives values of 3 channels at 12 bits each, the values don't match as expected. Therefore, I suspect that there might be differences in radar antenna specifications.

Below, I've attached the code I used for conversion along with the results.


Folding/Unfolding ### my origin and converted numpy file [my_numpy_file.zip #1](https://github.com/RangineniBalaji/Heart-rate-and-Breath-rate-estimation-using-Infenon-Radar/files/14583281/my_numpy_file.zip) If the link doesn't work, I've uploaded the attachment here. [my_numpy_file.zip #2](https://github.com/909ma/Repository-for-Study/blob/master/my_numpy_file.zip) --- > ### convert code
import numpy as np

file_path = 'radar.npy'
loaded_data = np.load(file_path)

# print("Loaded data:", loaded_data)
print(file_path, "shape:", loaded_data.shape)
print(file_path, "data[0] shape:", loaded_data.shape[0])

data_shape = loaded_data.shape
reshaped_shape = (data_shape[0], data_shape[2] * data_shape[3])
reshaped_data = loaded_data[:, 0, :, :]
print("reshaped_data shpae: ", reshaped_data.shape)

final_data = reshaped_data.reshape(reshaped_shape)

# np.save('scaled_data.npy', final_data)
# print("final_data shape: ", final_data[0:10])
print("final_data shape: ", final_data.shape)

log_data = np.log1p(np.abs(final_data))
print("final_data shape: ", log_data[0:10])
print("log_data shape: ", log_data.shape)

--- ### convert code's result
radar.npy shape: (450, 3, 128, 128)
radar.npy data[0] shape: 450
reshaped_data shpae:  (450, 128, 128)
final_data shape:  (450, 16384)
final_data shape:  [[7.635304  7.621685  7.6162834 ... 7.6453977 7.650169  7.6539693]
 [7.639161  7.6275444 7.6211953 ... 7.6444407 7.6549172 7.662468 ]
 [7.629004  7.6063876 7.591357  ... 7.641084  7.6425242 7.6425242]
 ...
 [7.6381984 7.623153  7.6123366 ... 7.6453977 7.6453977 7.6463537]
 [7.629976  7.6093664 7.6004024 ... 7.6420445 7.647309  7.6530204]
 [7.6449194 7.636752  7.629976  ... 7.64874   7.6530204 7.6549172]]
log_data shape:  (450, 16384)
--- ### main.py
import numpy as np
import matplotlib.pyplot as plt
# from data_processing import load_data, scale_data, reshape_data
# from analysis import count_points_above_threshold, calculate_mean_values, count_values_within_threshold
# from rate_estimation import estimate_rate
from imputation import impute_values
# from averaging import find_average

# === data_processing.py ================================================================================
def load_data(file_path, isNpy):
    if isNpy:
        data = np.load(file_path)
        loaded_data = np.log1p(np.abs(data))
        return loaded_data
    else:
        with open(file_path, "rb") as f:
            data = np.fromfile(f, dtype="complex128")
        return data

def scale_data(data):
    scaled_data = np.log1p(np.abs(data))
    return scaled_data

def reshape_data(data, isNpy):
    if isNpy:
        pass
    else:
        data = data[155:]
        reshaped_data = data.reshape((450,16384)) 
        return reshaped_data

# === analysis.py =============================================================================================================
def count_points_above_threshold(data, threshold):
    count_greater_than_threshold = np.sum(data > threshold, axis=1)
    return count_greater_than_threshold

def calculate_mean_values(count_array, window_size):
    mean_values = np.mean(count_array.reshape(-1, window_size), axis=1)
    return mean_values

def count_values_within_threshold(data, threshold_lower, threshold_upper):
    count_within_threshold = np.sum((data > threshold_lower) & (data < threshold_upper), axis=1)
    return count_within_threshold

# === averaging.py ==========================================================================================================
def find_average(signal):
    threshold = np.mean(signal)
    averaged = []

    for i in range(60):
        start_index = i * int(len(signal) / 60)  # Divide the total length by 60 for a 60-second interval
        end_index = start_index + int(len(signal) / 60)  # Divide the total length by 60 for a 60-second interval

        # Extract the subset of the signal within the window
        window_signal = signal[start_index:end_index]

        # Average the values within the window to get a single value
        averaged_value = np.mean(window_signal)

        # Append the averaged value to the breath rates array
        averaged.append(averaged_value)
    return averaged

# === rate_estimation.py ==============================================================
from scipy.signal import find_peaks

def estimate_rate(signal, threshold, frame_rate):
    rate_list = []

    for i in range(len(signal)):
        start_index = i * 1  
        end_index = start_index + 25

        window_signal = signal[start_index:end_index]
        peaks, _ = find_peaks(window_signal, height=threshold)

        time_diffs = np.diff(peaks) / frame_rate

        rate = 60 / np.mean(time_diffs) if len(time_diffs) > 0 else 0
        rate_list.append(int(np.ceil(rate)))
    return rate_list

# === main =====================================================================================================================
if __name__ == "__main__":
    # Load and preprocess data
    isNpy = True
    if isNpy:
        #.npy file
        # scaled_data = load_data("combined_scaled_data.npy", isNpy)

        # scaled_data = load_data("radar.npy", isNpy)
        # reshaped_data = reshape_data(scaled_data, isNpy)

        reshaped_data = load_data("scaled_data.npy", isNpy)
    else:
        data = load_data("data1.raw.bin", isNpy)
        scaled_data = scale_data(data)
        reshaped_data = reshape_data(scaled_data, isNpy)

    print(reshaped_data.shape)

    # Breath Rate
    BR_threshold = 600
    count_array = count_points_above_threshold(reshaped_data, BR_threshold)
    mean_values = calculate_mean_values(count_array, 5)
    averaged = find_average(mean_values)
    breath_rate_list = estimate_rate(averaged, np.mean(averaged), 1)

    # Heart Rate
    # HR_threshold_lower = 200
    # HR_threshold_upper = 300
    # count_array = count_values_within_threshold(reshaped_data, HR_threshold_lower, HR_threshold_upper)
    # mean_values = calculate_mean_values(count_array, 2)
    # heart_rate_list = estimate_rate(np.ceil(mean_values), np.mean(mean_values), 4)
    # heart_rate_list = find_average(heart_rate_list)
    # heart_rate_list = impute_values(heart_rate_list, 60)

    # Plotting
    # plt.plot(heart_rate_list, label="Heart Rate")
    plt.plot(breath_rate_list, label="Breath Rate")
    plt.title("Heart Rate and Breath Rate Estimation Over Time")
    plt.xlabel("Time")
    plt.ylabel("Rate")
    plt.legend()
    plt.show()

my_eyes

909ma commented 7 months ago

Also, I'm curious about how the threshold value was determined.
Because if the data values vary, it makes sense that the threshold value would also change.

RangineniBalaji commented 7 months ago

Also, I'm curious about how the threshold value was determined. Because if the data values vary, it makes sense that the threshold value would also change.

Thresholds are identified manually by analyzing plots(through where the peaks are frequent), still working to make it automate. Breath rate: if the chest is moved forward the amplitude will be increased so therefore the peaks in the graph are high so identify the point from you graph which is little below the high of your values. Heart rate: As radar is specialized for capturing the small movements, analyze the more frequent peaks in middle of the graph to find the thresholds.

And about first question .npy files Use the algorithm to proceed further i mean as per your data characteristics change the code accordingly. Mail me further details Mail: balajinaidu501@gmail.com Ill collaborate with you and help you through the project. thank you.

RangineniBalaji commented 7 months ago

My radar model is the Infineon DEMO BGT60TR13C (60GHz sensor), along with Fusion GUI version 3.5.4.202310251420.

I encountered an issue at the initial stage of processing the data extracted(I'm in the process of converting the recorded numpy file to fit the code.). The shape of my numpy file is (450, 3, 128, 128), indicating that I recorded 450 frames, with 3 antennas transmitting 128 chirps per frame, and each chirp comprising 128 samples.

Upon reshaping it to (450, 16384) and attempting to proceed, I noticed a significant discrepancy between my values and yours.

Since my radar antenna receives values of 3 channels at 12 bits each, the values don't match as expected. Therefore, I suspect that there might be differences in radar antenna specifications.

Below, I've attached the code I used for conversion along with the results.

Folding/Unfolding

my origin and converted numpy file

my_numpy_file.zip #1

If the link doesn't work, I've uploaded the attachment here. my_numpy_file.zip #2

convert code

import numpy as np

file_path = 'radar.npy' loaded_data = np.load(file_path)

print("Loaded data:", loaded_data)

print(file_path, "shape:", loaded_data.shape) print(file_path, "data[0] shape:", loaded_data.shape[0])

data_shape = loaded_data.shape reshaped_shape = (data_shape[0], data_shape[2] * data_shape[3]) reshaped_data = loaded_data[:, 0, :, :] print("reshaped_data shpae: ", reshaped_data.shape)

final_data = reshaped_data.reshape(reshaped_shape)

np.save('scaled_data.npy', final_data)

print("final_data shape: ", final_data[0:10])

print("final_data shape: ", final_data.shape)

log_data = np.log1p(np.abs(final_data)) print("final_data shape: ", log_data[0:10]) print("log_data shape: ", log_data.shape)

convert code's result

radar.npy shape: (450, 3, 128, 128) radar.npy data[0] shape: 450 reshaped_data shpae: (450, 128, 128) final_data shape: (450, 16384) final_data shape: [[7.635304 7.621685 7.6162834 ... 7.6453977 7.650169 7.6539693] [7.639161 7.6275444 7.6211953 ... 7.6444407 7.6549172 7.662468 ] [7.629004 7.6063876 7.591357 ... 7.641084 7.6425242 7.6425242] ... [7.6381984 7.623153 7.6123366 ... 7.6453977 7.6453977 7.6463537] [7.629976 7.6093664 7.6004024 ... 7.6420445 7.647309 7.6530204] [7.6449194 7.636752 7.629976 ... 7.64874 7.6530204 7.6549172]] log_data shape: (450, 16384)

main.py

import numpy as np import matplotlib.pyplot as plt

from data_processing import load_data, scale_data, reshape_data

from analysis import count_points_above_threshold, calculate_mean_values, count_values_within_threshold

from rate_estimation import estimate_rate

from imputation import impute_values

from averaging import find_average

=== data_processing.py ================================================================================

def load_data(file_path, isNpy): if isNpy: data = np.load(file_path) loaded_data = np.log1p(np.abs(data)) return loaded_data else: with open(file_path, "rb") as f: data = np.fromfile(f, dtype="complex128") return data

def scale_data(data): scaled_data = np.log1p(np.abs(data)) return scaled_data

def reshape_data(data, isNpy): if isNpy: pass else: data = data[155:] reshaped_data = data.reshape((450,16384)) return reshaped_data

=== analysis.py =============================================================================================================

def count_points_above_threshold(data, threshold): count_greater_than_threshold = np.sum(data > threshold, axis=1) return count_greater_than_threshold

def calculate_mean_values(count_array, window_size): mean_values = np.mean(count_array.reshape(-1, window_size), axis=1) return mean_values

def count_values_within_threshold(data, threshold_lower, threshold_upper): count_within_threshold = np.sum((data > threshold_lower) & (data < threshold_upper), axis=1) return count_within_threshold

=== averaging.py ==========================================================================================================

def find_average(signal): threshold = np.mean(signal) averaged = []

for i in range(60):
    start_index = i * int(len(signal) / 60)  # Divide the total length by 60 for a 60-second interval
    end_index = start_index + int(len(signal) / 60)  # Divide the total length by 60 for a 60-second interval

    # Extract the subset of the signal within the window
    window_signal = signal[start_index:end_index]

    # Average the values within the window to get a single value
    averaged_value = np.mean(window_signal)

    # Append the averaged value to the breath rates array
    averaged.append(averaged_value)
return averaged

=== rate_estimation.py ==============================================================

from scipy.signal import find_peaks

def estimate_rate(signal, threshold, frame_rate): rate_list = []

for i in range(len(signal)):
    start_index = i * 1  
    end_index = start_index + 25

    window_signal = signal[start_index:end_index]
    peaks, _ = find_peaks(window_signal, height=threshold)

    time_diffs = np.diff(peaks) / frame_rate

    rate = 60 / np.mean(time_diffs) if len(time_diffs) > 0 else 0
    rate_list.append(int(np.ceil(rate)))
return rate_list

=== main =====================================================================================================================

if name == "main":

Load and preprocess data

isNpy = True
if isNpy:
    #.npy file
    # scaled_data = load_data("combined_scaled_data.npy", isNpy)

    # scaled_data = load_data("radar.npy", isNpy)
    # reshaped_data = reshape_data(scaled_data, isNpy)

    reshaped_data = load_data("scaled_data.npy", isNpy)
else:
    data = load_data("data1.raw.bin", isNpy)
    scaled_data = scale_data(data)
    reshaped_data = reshape_data(scaled_data, isNpy)

print(reshaped_data.shape)

# Breath Rate
BR_threshold = 600
count_array = count_points_above_threshold(reshaped_data, BR_threshold)
mean_values = calculate_mean_values(count_array, 5)
averaged = find_average(mean_values)
breath_rate_list = estimate_rate(averaged, np.mean(averaged), 1)

# Heart Rate
# HR_threshold_lower = 200
# HR_threshold_upper = 300
# count_array = count_values_within_threshold(reshaped_data, HR_threshold_lower, HR_threshold_upper)
# mean_values = calculate_mean_values(count_array, 2)
# heart_rate_list = estimate_rate(np.ceil(mean_values), np.mean(mean_values), 4)
# heart_rate_list = find_average(heart_rate_list)
# heart_rate_list = impute_values(heart_rate_list, 60)

# Plotting
# plt.plot(heart_rate_list, label="Heart Rate")
plt.plot(breath_rate_list, label="Breath Rate")
plt.title("Heart Rate and Breath Rate Estimation Over Time")
plt.xlabel("Time")
plt.ylabel("Rate")
plt.legend()
plt.show()

my_eyes

My code will work bin file i read that as complex and there we have 7372955 values. I research about the bin file data from data it stored sequentially. as per my radar specifications num of samples per frame: 128 num of chirps per frame: 128 At one instant my radar records around 16328 points(128*128) so i converted that to frames 450 is the highest possible. and proceed through my algorithm and Your Case is completely different. Your radar may record differently make your reasearch and proceed with the code.