Advertisement
dan-masek

Untitled

Oct 13th, 2018
550
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.48 KB | None | 0 0
  1. #include <opencv2/opencv.hpp>
  2.  
  3. void dump(std::string const& name, std::vector<double>& v)
  4. {
  5.     std::cout << name << " = [";
  6.     for (auto val : v) {
  7.         std::cout << val << ", ";
  8.     }
  9.     std::cout << "]\n";
  10. }
  11.  
  12. cv::Mat1d gen_time_steps(double sample_freq, int32_t sample_count)
  13. {
  14.     cv::Mat1d t;
  15.     for (int32_t i(0); i < sample_count; ++i) {
  16.         t.push_back(i / sample_freq);
  17.     }
  18.     return t.reshape(1, 1); // Make it single row
  19. }
  20.  
  21.  
  22. // Generate complex sine wave
  23. cv::Mat2d gen_sine_wave(double freq, cv::Mat1d const& t)
  24. {
  25.     cv::Mat2d y;
  26.     for (auto ts : t) {
  27.         y.push_back(cv::Vec2d(sin(ts * (2 * CV_PI) * freq), 0));
  28.     }
  29.     return y.reshape(2, 1); // Make it single row
  30. }
  31.  
  32. // Get magnitude from a complex spectrum
  33. cv::Mat1d get_magnitudes(cv::Mat2d fd)
  34. {
  35.     std::vector<cv::Mat1d> ri(2);
  36.     cv::split(fd, ri);
  37.     cv::Mat1d mag;
  38.     cv::sqrt(ri[0].mul(ri[0]) + ri[1].mul(ri[1]), mag);
  39.     return mag;
  40. }
  41.  
  42. double get_peak_freq(cv::Mat1d const& spectrum, double sampling_rate, int32_t sample_count)
  43. {
  44.     cv::Point2i maxloc;
  45.     cv::minMaxLoc(spectrum, nullptr, nullptr, nullptr, &maxloc);
  46.  
  47.     return maxloc.x * (sampling_rate / sample_count);
  48. }
  49.  
  50. double test(double freq, double sampling_rate, int32_t sample_count)
  51. {
  52.     // Create time vector
  53.     cv::Mat1d t(gen_time_steps(sampling_rate, sample_count));
  54.  
  55.     // Creating sin signal with 1Hz period
  56.     cv::Mat2d y(gen_sine_wave(freq, t));
  57.  
  58.     // Compute DFT
  59.     cv::Mat2d fd;
  60.     cv::dft(y, fd);
  61.     fd = fd.colRange(0, fd.cols / 2); // Other half is mirrored
  62.  
  63.     cv::Mat1d spectrum(get_magnitudes(fd));
  64.    
  65.     return get_peak_freq(spectrum, sampling_rate, sample_count);
  66. }
  67.  
  68. int main()
  69. {
  70.     std::vector<int32_t> window_sizes{ 256, 512, 1024 }; // samples
  71.     std::vector<double> sampling_rates{ 16, 32, 64 }; // Hz
  72.     std::vector<double> freqs{ 1./16, 1./8, 1./4, 1./2, 1.0
  73.         , 1.5, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 7.5, 8.0
  74.         , 12.0, 16 - (1./4), 16 - (1./8), 16 - (1./16), 16.0 }; // Hz
  75.  
  76.     for (int32_t window_size : window_sizes) {
  77.         std::cout << "Window size = " << window_size << "\n";
  78.         for (double sampling_rate : sampling_rates) {
  79.             std::cout << "* Sampling rate = " << sampling_rate << " Hz\n";
  80.             for (double freq : freqs) {
  81.                 std::cout << "** f = " << freq << " : detected f = "
  82.                     << test(freq, sampling_rate, window_size) << " Hz\n";
  83.             }
  84.         }
  85.     }
  86.  
  87.     return 0;
  88. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement