set(KCF_LIB_SRC kcf.cpp kcf.h complexmat.hpp fft.cpp)
SET(FFT "OpenCV" CACHE STRING "Select FFT implementation")
-SET_PROPERTY(CACHE FFT PROPERTY STRINGS OpenCV OpenCV_cuFFT fftw cuFFTW)
+SET_PROPERTY(CACHE FFT PROPERTY STRINGS OpenCV OpenCV_cuFFT fftw cuFFTW cuFFT)
MESSAGE(STATUS "FFT implementation: ${FFT}")
option(OPENMP "Use OpenMP library. Works with FFTW and OpenCV implementation." OFF)
list(APPEND KCF_LIB_SRC fft_fftw.cpp)
add_definitions(-DFFTW -DCUFFTW)
set(use_cuda ON)
+ELSEIF(FFT STREQUAL "cuFFT")
+ list(APPEND KCF_LIB_SRC fftw_cufft.cpp)
+ add_definitions(-DCUFFT)
+ set(use_cuda ON)
ELSE()
MESSAGE(FATAL_ERROR "Invalid FFT implementation selected")
ENDIF()
target_link_libraries(kcf ${CUDA_cufft_LIBRARY} ${CUDA_cufftw_LIBRARY})
ENDIF() #cuFFTW
+IF(FFT STREQUAL "cuFFT")
+ target_link_libraries(kcf ${CUDA_cufft_LIBRARY})
+ENDIF()
+
IF(PROFILING)
target_link_libraries(kcf pfm)
ENDIF()
cv::Mat channel_to_cv_mat(int channel_id) const
{
cv::Mat result(rows, cols, CV_32FC2);
- int data_id = 0;
for (int y = 0; y < rows; ++y) {
std::complex<T> * row_ptr = result.ptr<std::complex<T>>(y);
for (int x = 0; x < cols; ++x){
--- /dev/null
+#include "fft_cufft.h"
+
+void init(unsigned width, unsigned height, unsigned num_of_feats, unsigned num_of_scales)
+{
+ m_width = width;
+ m_height = height;
+ m_num_of_feats = num_of_feats;
+ m_num_of_scales = num_of_scales;
+ std::cout << "FFT: cuFFT" << std::endl;
+}
+
+void cuFFT::set_window(const cv::Mat &window)
+{
+ m_window = window;
+}
+
+ComplexMat cuFFT::forward(const cv::Mat &input)
+{
+ cv::Mat complex_result;
+ cv::dft(input, complex_result, cv::DFT_COMPLEX_OUTPUT);
+ return ComplexMat(complex_result);
+}
+
+ComplexMat cuFFT::forward_window(const std::vector<cv::Mat> &input)
+{
+ int n_channels = input.size();
+ ComplexMat result(input[0].rows, input[0].cols, n_channels);
+
+ for (int i = 0; i < n_channels; ++i) {
+ cv::Mat complex_result;
+ cv::dft(input[i].mul(m_window), complex_result, cv::DFT_COMPLEX_OUTPUT);
+ result.set_channel(i, complex_result);
+ }
+ return result;
+}
+
+cv::Mat cuFFT::inverse(const ComplexMat &inputf)
+{
+ cv::Mat real_result;
+ if (inputf.n_channels == 1) {
+ cv::dft(inputf.to_cv_mat(), real_result, cv::DFT_INVERSE | cv::DFT_REAL_OUTPUT | cv::DFT_SCALE);
+ } else {
+ std::vector<cv::Mat> mat_channels = inputf.to_cv_mat_vector();
+ std::vector<cv::Mat> ifft_mats(inputf.n_channels);
+ for (int i = 0; i < inputf.n_channels; ++i) {
+ cv::dft(mat_channels[i], ifft_mats[i], cv::DFT_INVERSE | cv::DFT_REAL_OUTPUT | cv::DFT_SCALE);
+ }
+ cv::merge(ifft_mats, real_result);
+ }
+ return real_result;
+}
+
+cuFFT::~cuFFT()
+{
+
+}
--- /dev/null
+#ifndef FFT_CUDA_H
+#define FFT_CUDA_H
+
+#include "fft.h"
+
+#include <cufft.h>
+
+class cuFFT : public Fft
+{
+public:
+ void init(unsigned width, unsigned height, unsigned num_of_feats, unsigned num_of_scales) override;
+ void set_window(const cv::Mat &window) override;
+ ComplexMat forward(const cv::Mat &input) override;
+ ComplexMat forward_window(const std::vector<cv::Mat> &input) override;
+ cv::Mat inverse(const ComplexMat &inputf) override;
+ ~cuFFT() override;
+private:
+ cv::Mat m_window;
+ unsigned m_width, m_height, m_num_of_feats,m_num_of_scales;
+};
+
+#endif // FFT_CUDA_H
-
#include "fft_opencv.h"
void init(unsigned width, unsigned height, unsigned num_of_feats, unsigned num_of_scales)