Visual Vibration Tracking 0.2
Загрузка...
Поиск...
Не найдено
vibrating_point.cpp
1#include "VVT-V2/vibrating_point.h"
2
4{
5 bool absolute_peak = false;
6
7 std::vector<Point2f> fft_result;
8 std::vector<Point2f> p2;
9 std::vector<Point2f> p1;
10 std::vector<double> frequencies;
11 std::vector<int> indexes_of_peak_frequencies;
12 std::vector<float> magnitudes;
13
14 std::vector<double> peak_frequencies;
15
16 int samples_amount = point_coordinates_.size();
17
18 Scalar mean_coordinates_of_point_ = mean(point_coordinates_);
19 //std::cout << mean_coordinates_of_point_ << std::endl;
20 double meaned_x = mean_coordinates_of_point_.val[0];
21 double meaned_y = mean_coordinates_of_point_.val[1];
22
24 x_coordinates_.clear();
25 y_coordinates_.clear();
26 for (int i = 0; i < point_coordinates_.size(); i++)
27 {
28 vec_meaned_coordinates_of_point_.push_back(Point2f(point_coordinates_[i].x - meaned_x, point_coordinates_[i].y - meaned_y));
29 x_coordinates_.push_back(point_coordinates_[i].x - meaned_x);
30 y_coordinates_.push_back(point_coordinates_[i].y - meaned_y);
31 }
32
33 dft(vec_meaned_coordinates_of_point_, fft_result);
34
35 // computing two-sided spectrum P2
36 for (int i = 0; i < fft_result.size(); i++)
37 {
38 Point2f tmp;
39 tmp.x = abs(fft_result[i].x / samples_amount);
40 tmp.y = abs(fft_result[i].y / samples_amount);
41 p2.push_back(tmp);
42 }
43
44 // computing single-sided spectrum P1 based on P2 and the even-valued signal length (the same as size_of_vecs_)
45 for (int i = 0; i < p2.size(); i++)
46 {
47 size_t idx = 0;
48 idx = (int)(((double)(i)) / 2.0 + 1.0);
49 p1.push_back(p2[idx]);
50 }
51
52 // possible frequencies
53 for (int i = 0; i < samples_amount; i++)
54 {
55 float tmp = sampling_rate_ * ((double)(i) / 2) / samples_amount;
56 frequencies.push_back(tmp);
57 }
58
59 for (int i = 0; i < p1.size(); i++)
60 {
61 float current_magnitude = sqrt(p1[i].x * p1[i].x + p1[i].y * p1[i].y);
62 magnitudes.push_back(current_magnitude);
63 }
64
67
68 /*
69 * FOR DEBUG
70 *
71 if (point_coordinates_.size() > 5)
72 {
73 std::fstream file;
74 file.open("C:/Users/seeyo/source/repos/Visual-Vibration-Tracking-V2/docs/magnitudes.txt", 'w');
75
76 //for (int i = 0; i < magnitudes.size(); i++)
77 //{
78 // std::string tmp = std::to_string(frequencies[i]) + " " + std::to_string(magnitudes[i]) + " " + std::to_string(p1[i].x) + " " + std::to_string(p1[i].y);
79 // file << tmp << std::endl;
80 //}
81
82 for (int i = 0; i < point_coordinates_.size(); i++)
83 {
84 std::string tmp = std::to_string(point_coordinates_[i].x) + " " + std::to_string(point_coordinates_[i].y) + " " + std::to_string(point_time_coordinates_[i]);
85 file << tmp << std::endl;
86 }
87
88 file.close();
89 }
90 */
91
92 x_ = frequencies;
93 y_ = magnitudes;
94
95 // Вызов отрисовщика гистограммы
97
98 bool candidate_for_being_full_zero = false;
99 int zero_flag = 0;
100
101 if (!absolute_peak)
102 {
103 // searching peaks in output vector of magnitudes
104
105 PeakFinder::findPeaks(magnitudes, indexes_of_peak_frequencies, false, 1);
106
107 int maxIdx = 0;
108
109 zero_flag = indexes_of_peak_frequencies.size();
110
111 double mag_sum = 0;
112
113 // filling in vector of peak_frequencies with the just found peak frequencies
114 for (int i = 0; i < indexes_of_peak_frequencies.size(); i++)
115 {
116 peak_frequencies.push_back(frequencies[indexes_of_peak_frequencies[i]]);
117
118 //std::cout << "mag: " << magnitudes[indexes_of_peak_frequencies[i]] << std::endl;
119 mag_sum += magnitudes[indexes_of_peak_frequencies[i]];
120 if ((magnitudes[indexes_of_peak_frequencies[i]]) < 0.01f)
121 zero_flag--;
122 }
123
124 main_frequency_ = frequencies[HelperFunctions::FindGlobalMaxIdx(magnitudes)];
125 float max_diff = HelperFunctions::CalculateMaxDifferenceInVector(magnitudes);
126 mag_max_differences_.push_back(max_diff);
127 float mean_diff_of_max_diffs = 0;
128 if (mag_max_differences_.size() > 1)
130
131 if (mean_diff_of_max_diffs < sensivity_ || std::isnan(mean_diff_of_max_diffs))
132 confidence_level_ -= 0.01;
133 else
134 confidence_level_ += 0.01;
135
136 if (zero_flag == 0 && indexes_of_peak_frequencies.size() != 0)
137 {
138 frequencies_.clear();
139 frequencies_.push_back(0.0);
140 }
141 else
142 {
143 frequencies_ = peak_frequencies;
144 }
145 }
146
147}
148
150{
151 // Обновляем прямоугольник взаимодействия
152 interaction_box_ = Rect(
153 Point2i(position.x - interaction_offset_, position.y - interaction_offset_),
154 Point2i(position.x + interaction_offset_, position.y + interaction_offset_)
155 );
156
157 point_coordinates_.push_back(position);
158}
159
161{
162 point_time_coordinates_.push_back(time);
163}
164
165bool VibratingPoint::IsInteracted(Point2i coordinates)
166{
167 interacted_ = interaction_box_.contains(coordinates);
168 return interacted_;
169}
170
171void VibratingPoint::SetSensivity(double sensivity)
172{
173 sensivity_ = sensivity;
174}
175
177{
181 float max_meaned_x = 0;
182 float max_meaned_y = 0;
183
184 // Создаем контей
185
188
189 float relative_amplitude_x = 0.0f;
190 float relative_amplitude_y = 0.0f;
191
192 Scalar mean_of_mean_coordinates_of_point = mean(vec_meaned_coordinates_of_point_);
193 double meaned_mean_x = mean_of_mean_coordinates_of_point.val[0];
194 double meaned_mean_y = mean_of_mean_coordinates_of_point.val[1];
195
197 if (point_coordinates_.size() > 2)
198 {
199 relative_amplitude_x = (max_meaned_x) / (max_meaned_x + max_meaned_y);
200 relative_amplitude_y = (max_meaned_y) / (max_meaned_x + max_meaned_y);
201 }
202
203 /*
204 // FOR DEBUG PURPOSES
205 if (std::isnan(relative_amplitude_x) || std::isnan(relative_amplitude_y))
206 {
207 std::cout << "!DEBUG first inf (x): " << relative_amplitude_x << " second inf (y): " << relative_amplitude_y << std::endl;
208 std::cout << "!DEBUG max_meaned_x: " << vec_meaned_coordinates_of_point_[HelperFunctions::FindGlobalMaxIdx(x_coordinates)].x << " max_meaned_y: " << vec_meaned_coordinates_of_point_[HelperFunctions::FindGlobalMaxIdx(y_coordinates)].y << std::endl;
209 std::cout << "vec size: " << point_coordinates_.size() << std::endl;
210 for (int i = 0; i < point_coordinates_.size(); i++)
211 {
212 std::cout << i << "-th coords: " << point_coordinates_[i] << std::endl;
213 }
214 }
215
216 if ((relative_amplitude_x > 1) || (relative_amplitude_y > 1))
217 {
218 std::cout << "!DEBUG first big (x): " << relative_amplitude_x << " second big (y): " << relative_amplitude_y << std::endl;
219 std::cout << "!DEBUG max_meaned_x: " << max_meaned_x << " max_meaned_y: " << max_meaned_y << std::endl;
220 }
221 */
222
223 if (!(std::isnan(relative_amplitude_x) || std::isnan(relative_amplitude_y)))
224 {
225 relative_amplitude_.x = relative_amplitude_x;
226 relative_amplitude_.y = relative_amplitude_y;
227 current_amplitude_.x = max_meaned_x - meaned_mean_x;
228 current_amplitude_.y = max_meaned_y - meaned_mean_y;
229 }
230}
231
233{
234 return point_coordinates_.back();
235}
236
238{
239 return frequencies_;
240}
241
243{
244 return main_frequency_;
245}
246
248{
249 return relative_amplitude_;
250}
251
253{
254 return current_amplitude_;
255}
256
258{
259 return confidence_level_;
260}
void ExecuteFFT()
Выполняет БПФ для нахождения частоты вибрации.
bool interacted_
Флаг взаимодействия с точкой
double GetCurrentConfidenceLevel()
Возвращает последний найденный уровень достоверности
void AddNewPointPosition(Point2f position)
Добавляет новую пространственную координату в конец контейнера VibratingPoint::point_coordinates_;.
virtual void DrawHistogram()=0
Отрисовывает гистограмму спектра частот колебаний точки (полученную после БПФ в методе ExecuteFFT())
std::vector< double > GetCurrentVibrationFrequency()
Возвращает вектор текущих частот точки
bool IsInteracted(Point2i coordinates)
Проверяет точку на наличие взаимодействия с ней (если курсор попал в область взаимодействия точки Vib...
void AddNewPointTime(double time)
Добавляет новую временную координату (время кадра, на котором новая позиция точки была трекнута) в ко...
Point3f current_amplitude_
Фактические амплитуды вибрации по x, y. Выражаюытся в пикселях
Rect interaction_box_
Прямоугольник (область) взаимодействия с точкой
double GetCurrentMainFrequency()
Возвращает текущую "основную" частоту
std::vector< double > y_coordinates_
Контейнер для координат точки по оси Y.
std::vector< double > x_
Контейнер для хранения координат гистограммы по оси X (фактически - найденный спектр частот вибрации ...
std::vector< double > x_coordinates_
Контейнер для координат точки по оси X.
double sampling_rate_
Частота сэмплирования (фактически - FPS исходного видео)
std::vector< float > mag_max_differences_
Максимальная разнциа в магнитудах в найденном спектре после БПФ
double confidence_level_
Рейтинг достоверности вибрации
int interaction_offset_
Половина длины прямоугольника взаимодействия
Point3f relative_amplitude_
Относительные амплитуды вибрации по x, y. Выражается отношением амплитуды
double main_frequency_
Главная частота (основная)
std::vector< float > y_
Контейнер для хранения координат гистограммы по оси Y (фактически - найденные магнитуды точки после в...
std::vector< cv::Point2f > vec_meaned_coordinates_of_point_
Контейнер для координат точки относительно нулевого уровня
double sensivity_
Чувствительность определения вибрации
Point3f GetCurrentAmplitude()
Возвращает последнюю найденную относительную амплитуду
std::vector< double > point_time_coordinates_
Контейнер для временных координат точки
void SetSensivity(double sensivity)
Устанавливает чувствительность, влияющую на confidence.
std::vector< double > frequencies_
Контейнер для частот точки
Point3f GetRelativeAmplitude()
Возвращает последнюю найденную относительную амплитуду
Point2f GetLastFoundCoordinates()
Возвращает последний элемент вектора координат
std::vector< Point2f > point_coordinates_
Контейнер для координат точки
void CalculateAmplitude()
Проводит необходимые для вычисления амплитуды вычисления
void DeadzoneFilter(std::vector< T > &input_vector)
Частотный фильтр для нижней части диапазона
Definition: helper.h:61
int FindGlobalMaxIdx(std::vector< T > src)
Возвращает индекс самого большого элемента вектора src.
Definition: helper.h:127
T CalculateMaxDifferenceInVector(std::vector< T > src)
Вычисляет максимальное значение разности элементов массива
Definition: helper.h:171
T CalculateMeanDifferenceInVector(std::vector< T > src)
Вычисляет среднее значение разности элементов массива в виде ((a0 - a1) + (a1 - a2)) / 3.
Definition: helper.h:96
void findPeaks(std::vector< float > x0, std::vector< int > &peakInds, bool includeEndpoints=true, float extrema=1)
Definition: peak_finder.cpp:66