1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
| class VitalSignsDetector { public: struct VitalSigns { bool is_present; float breathing_rate; float heart_rate; float movement_intensity; int64_t last_movement_time; }; VitalSigns Detect(const std::vector<RadarPoint>& point_cloud) { VitalSigns vital; auto filtered_points = FilterNoise(point_cloud); auto clusters = ClusterPoints(filtered_points); if (clusters.empty()) { vital.is_present = false; return vital; } auto doppler_signals = ExtractDopplerSignals(clusters); auto spectrum = ComputeFFT(doppler_signals); vital.breathing_rate = FindPeakFrequency(spectrum, 0.1f, 0.5f) * 60.0f; vital.heart_rate = FindPeakFrequency(spectrum, 0.8f, 2.0f) * 60.0f; if (vital.breathing_rate > 5.0f && vital.breathing_rate < 40.0f) { vital.is_present = true; } vital.movement_intensity = CalculateMovementIntensity(point_cloud); return vital; } private: std::vector<std::pair<float, float>> ComputeFFT( const std::vector<float>& signal) { cv::Mat signal_mat(signal, true); signal_mat.convertTo(signal_mat, CV_32F); cv::Mat spectrum; cv::dft(signal_mat, spectrum, cv::DFT_COMPLEX_OUTPUT); std::vector<cv::Mat> planes; cv::split(spectrum, planes); cv::magnitude(planes[0], planes[1], planes[0]); std::vector<std::pair<float, float>> freq_mag_pairs; for (int i = 0; i < planes[0].rows; ++i) { float freq = static_cast<float>(i) / signal.size(); float mag = planes[0].at<float>(i); freq_mag_pairs.emplace_back(freq, mag); } return freq_mag_pairs; } float FindPeakFrequency(const std::vector<std::pair<float, float>>& spectrum, float min_freq, float max_freq) { float max_mag = 0.0f; float peak_freq = 0.0f; for (const auto& [freq, mag] : spectrum) { if (freq >= min_freq && freq <= max_freq && mag > max_mag) { max_mag = mag; peak_freq = freq; } } return peak_freq; } };
|