Skip to content
Snippets Groups Projects
Commit 379c2e87 authored by Sebastian Gomez-Gonzalez's avatar Sebastian Gomez-Gonzalez
Browse files

Creating functionality to seemless running CPU or GPU implementation.

Not tested yet on the GPU
parent b1770e53
No related branches found
No related tags found
No related merge requests found
...@@ -2,28 +2,42 @@ cmake_minimum_required(VERSION 3.5) ...@@ -2,28 +2,42 @@ cmake_minimum_required(VERSION 3.5)
project(ball_tracking) project(ball_tracking)
find_package(OpenCV REQUIRED) find_package(OpenCV REQUIRED)
find_package(CUDA 8.0 REQUIRED) find_package(CUDA 8.0)
find_library(ZMQPP NAMES zmqpp)
find_path(ZMQPP_INCLUDES NAMES zmqpp/zmqpp.hpp)
option (PYLIB "Create a Python Module with interface to some of the C++ implementations" ON) if (CUDA_FOUND)
option (WITH_CUDA "Compile the library with GPU implementations" ON)
endif (CUDA_FOUND)
if (WITH_CUDA)
include_directories(${CUDA_INCLUDE_DIRS})
set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} -std=c++11 -arch=sm_30" )
cuda_add_library(cu_ball_track SHARED
src/cuda/img_proc.cu
)
set(GPU_CPP_SRC
src/cuda/tracker.cpp
)
set (GPU_BT_LIB
cu_ball_track
)
add_definitions(-DWITH_CUDA)
endif(WITH_CUDA)
include_directories(include include_directories(include
${OpenCV_INCLUDES} ${OpenCV_INCLUDES}
${CUDA_INCLUDE_DIRS})
set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} -std=c++11 -arch=sm_30" )
cuda_add_library(cu_ball_track SHARED
src/cuda/img_proc.cu
) )
add_library(ball_tracking SHARED add_library(ball_tracking SHARED
src/img_proc.cpp src/img_proc.cpp
src/utils.cpp src/utils.cpp
src/tracker.cpp src/tracker.cpp
src/cuda/tracker.cpp ${GPU_CPP_SRC}
) )
target_link_libraries(ball_tracking target_link_libraries(ball_tracking
${OpenCV_LIBS} ${OpenCV_LIBS}
cu_ball_track ${GPU_BT_LIB}
) )
#Compile with C++11 support only #Compile with C++11 support only
......
...@@ -11,14 +11,6 @@ target_link_libraries(color_approach ...@@ -11,14 +11,6 @@ target_link_libraries(color_approach
${Boost_LIBRARIES} ${Boost_LIBRARIES}
) )
add_executable(log_reg_approach
img_proc/log_reg_approach.cpp
)
target_link_libraries(log_reg_approach
ball_tracking
${Boost_LIBRARIES}
)
add_executable(ball_log_lh add_executable(ball_log_lh
img_proc/ball_log_lh.cpp img_proc/ball_log_lh.cpp
) )
...@@ -35,10 +27,21 @@ target_link_libraries(track ...@@ -35,10 +27,21 @@ target_link_libraries(track
${Boost_LIBRARIES} ${Boost_LIBRARIES}
) )
add_executable(gpu_track if (WITH_CUDA)
tracking/gpu_track.cpp add_executable(log_reg_approach
) img_proc/log_reg_approach.cpp
target_link_libraries(gpu_track )
ball_tracking target_link_libraries(log_reg_approach
${Boost_LIBRARIES} ball_tracking
) ${Boost_LIBRARIES}
)
add_executable(gpu_track
tracking/gpu_track.cpp
)
target_link_libraries(gpu_track
ball_tracking
${Boost_LIBRARIES}
)
endif (WITH_CUDA)
{
"tracker": {
"type": "cpu",
"conf": {
"ball_log_lh": {
"type": "cb_log_reg",
"conf": {
"weights": [
-4.3645153397769523,
-1.7528550846385467,
-0.94643386271480279,
-2.1172356652966022,
-1.7266645284508131,
-4.0142794641079673,
-3.8619400850106795,
1.7698900417473211,
2.2392411493959243,
1.6657076794425114,
1.9180643323474467,
-1.8974895205433868,
2.6587407284968458,
2.2491171019131664,
2.6281082938750533,
2.4812839914967717,
-2.2706336207474567,
2.5778824379463727,
1.2787179559340944,
1.9590196639347666,
-1.1268150111657678,
3.278679714617708,
2.232487133767151,
-1.6055001267916118,
3.5447611950425828,
-5.4301792573145677,
-4.7388290757015756,
-5.739125161010926
],
"gauss_smooth": {
"size": 5,
"sigma": 0
}
}
},
"blob_detection": {
"type": "cv_blob_detect",
"conf": {
"binarizer": {
"p_thresh": 0.05
},
"filterByArea": true,
"minArea": 8,
"maxArea": 500,
"filterByCircularity": true,
"minCircularity": 0.75,
"maxCircularity": 1.0
}
}
}
}
}
...@@ -107,7 +107,7 @@ int main(int argc, char** argv) { ...@@ -107,7 +107,7 @@ int main(int argc, char** argv) {
end_t = std::chrono::steady_clock::now(); end_t = std::chrono::steady_clock::now();
llh_time.push_back(std::chrono::duration_cast<std::chrono::microseconds>(end_t - start_t).count()); llh_time.push_back(std::chrono::duration_cast<std::chrono::microseconds>(end_t - start_t).count());
//2.1) Binarize //2.1) Binarize (Just for debugging purposes)
start_t = std::chrono::steady_clock::now(); start_t = std::chrono::steady_clock::now();
auto bin_img = bin(l_lh); auto bin_img = bin(l_lh);
end_t = std::chrono::steady_clock::now(); end_t = std::chrono::steady_clock::now();
...@@ -115,7 +115,7 @@ int main(int argc, char** argv) { ...@@ -115,7 +115,7 @@ int main(int argc, char** argv) {
//3) Run blob detection algorithm //3) Run blob detection algorithm
start_t = std::chrono::steady_clock::now(); start_t = std::chrono::steady_clock::now();
auto key_pts = bf(bin_img); auto key_pts = bf(l_lh);
end_t = std::chrono::steady_clock::now(); end_t = std::chrono::steady_clock::now();
blob_time.push_back(std::chrono::duration_cast<std::chrono::microseconds>(end_t - start_t).count()); blob_time.push_back(std::chrono::duration_cast<std::chrono::microseconds>(end_t - start_t).count());
......
...@@ -40,10 +40,13 @@ ...@@ -40,10 +40,13 @@
}, },
"binarizer": { "binarizer": {
"p_thresh": 0.05 "p_thresh": 0.05
}, },
"blob_detection": { "blob_detection": {
"type": "cv_blob_detect", "type": "cv_blob_detect",
"conf": { "conf": {
"binarizer": {
"p_thresh": 0.05
},
"filterByArea": true, "filterByArea": true,
"minArea": 8, "minArea": 8,
"maxArea": 500, "maxArea": 500,
......
...@@ -22,7 +22,7 @@ namespace ball_tracking { ...@@ -22,7 +22,7 @@ namespace ball_tracking {
class BallLogLikelihood { class BallLogLikelihood {
private: private:
class Impl; class Impl;
std::unique_ptr<Impl> _impl; std::shared_ptr<Impl> _impl;
public: public:
/** /**
* @brief Creates an object with given configuration parameters * @brief Creates an object with given configuration parameters
...@@ -30,6 +30,11 @@ namespace ball_tracking { ...@@ -30,6 +30,11 @@ namespace ball_tracking {
BallLogLikelihood(const nlohmann::json& params); BallLogLikelihood(const nlohmann::json& params);
~BallLogLikelihood(); ~BallLogLikelihood();
/**
* @brief Creates an empty object
*/
BallLogLikelihood();
/** /**
* @brief Produces a single channel image representing the log likelihood of each * @brief Produces a single channel image representing the log likelihood of each
* pixel being part of the ball * pixel being part of the ball
...@@ -49,11 +54,16 @@ namespace ball_tracking { ...@@ -49,11 +54,16 @@ namespace ball_tracking {
class Binarizer { class Binarizer {
private: private:
class Impl; class Impl;
std::unique_ptr<Impl> _impl; std::shared_ptr<Impl> _impl;
public: public:
Binarizer(const nlohmann::json& params); Binarizer(const nlohmann::json& params);
~Binarizer(); ~Binarizer();
/**
* @brief Creates an empty object
*/
Binarizer();
/** /**
* @brief Returns an 8 bit single channel binarized image from a given single channel * @brief Returns an 8 bit single channel binarized image from a given single channel
* real valued image. The image contains only 0 or 255 values in each pixel. * real valued image. The image contains only 0 or 255 values in each pixel.
...@@ -70,11 +80,16 @@ namespace ball_tracking { ...@@ -70,11 +80,16 @@ namespace ball_tracking {
class FindBallBlob { class FindBallBlob {
private: private:
class Impl; class Impl;
std::unique_ptr<Impl> _impl; std::shared_ptr<Impl> _impl;
public: public:
FindBallBlob(const nlohmann::json& params); FindBallBlob(const nlohmann::json& params);
~FindBallBlob(); ~FindBallBlob();
/**
* @brief Creates an empty object
*/
FindBallBlob();
/** /**
* @brief Returns all candidate locations of a ball in a single channel * @brief Returns all candidate locations of a ball in a single channel
* likelihood image. * likelihood image.
......
...@@ -25,12 +25,21 @@ namespace ball_tracking { ...@@ -25,12 +25,21 @@ namespace ball_tracking {
class BallLogLikelihood { class BallLogLikelihood {
private: private:
class Impl; class Impl;
std::unique_ptr<Impl> _impl; std::shared_ptr<Impl> _impl;
public: public:
/** /**
* @brief Creates an object with given configuration parameters * @brief Creates an object with given configuration parameters
*/ */
BallLogLikelihood(const nlohmann::json& params); BallLogLikelihood(const nlohmann::json& params);
/**
* @brief Creates an empty object.
*
* Using an object created with this default constructor will result
* in undefined behaviour.
*/
BallLogLikelihood();
~BallLogLikelihood(); ~BallLogLikelihood();
/** /**
...@@ -51,9 +60,18 @@ namespace ball_tracking { ...@@ -51,9 +60,18 @@ namespace ball_tracking {
class Binarizer { class Binarizer {
private: private:
class Impl; class Impl;
std::unique_ptr<Impl> _impl; std::shared_ptr<Impl> _impl;
public: public:
/**
* @brief Creates a binarizer with the given configuration
*/
Binarizer(const nlohmann::json& params); Binarizer(const nlohmann::json& params);
/**
* @brief Creates an empty object
*/
Binarizer();
~Binarizer(); ~Binarizer();
/** /**
...@@ -72,11 +90,16 @@ namespace ball_tracking { ...@@ -72,11 +90,16 @@ namespace ball_tracking {
class FindBallBlob { class FindBallBlob {
private: private:
class Impl; class Impl;
std::unique_ptr<Impl> _impl; std::shared_ptr<Impl> _impl;
public: public:
FindBallBlob(const nlohmann::json& params); FindBallBlob(const nlohmann::json& params);
~FindBallBlob(); ~FindBallBlob();
/**
* @brief Creates an empty object
*/
FindBallBlob();
/** /**
* @brief Returns all candidate locations of a ball in a single channel * @brief Returns all candidate locations of a ball in a single channel
* likelihood image. * likelihood image.
...@@ -87,6 +110,21 @@ namespace ball_tracking { ...@@ -87,6 +110,21 @@ namespace ball_tracking {
*/ */
std::vector<cv::KeyPoint> operator()(cv::InputArray src); std::vector<cv::KeyPoint> operator()(cv::InputArray src);
}; };
/**
* @brief Returns the object position if any from the original image
*/
class Tracker {
private:
class Impl;
std::shared_ptr<Impl> _impl;
public:
Tracker(const nlohmann::json& params);
Tracker();
~Tracker();
std::vector<cv::KeyPoint> operator()(cv::InputArray src);
};
}; };
#endif #endif
...@@ -83,7 +83,11 @@ namespace ball_tracking { ...@@ -83,7 +83,11 @@ namespace ball_tracking {
}; };
BallLogLikelihood::BallLogLikelihood(const nlohmann::json& params) { BallLogLikelihood::BallLogLikelihood(const nlohmann::json& params) {
_impl = unique_ptr<Impl>(new Impl(params)); _impl = shared_ptr<Impl>(new Impl(params));
}
BallLogLikelihood::BallLogLikelihood() {
_impl = nullptr;
} }
BallLogLikelihood::~BallLogLikelihood() = default; BallLogLikelihood::~BallLogLikelihood() = default;
...@@ -114,7 +118,11 @@ namespace ball_tracking { ...@@ -114,7 +118,11 @@ namespace ball_tracking {
}; };
Binarizer::Binarizer(const nlohmann::json& params) { Binarizer::Binarizer(const nlohmann::json& params) {
_impl = unique_ptr<Impl>(new Impl(params)); _impl = shared_ptr<Impl>(new Impl(params));
}
Binarizer::Binarizer() {
_impl = nullptr;
} }
Binarizer::~Binarizer() = default; Binarizer::~Binarizer() = default;
......
...@@ -28,7 +28,7 @@ namespace ball_tracking { ...@@ -28,7 +28,7 @@ namespace ball_tracking {
cv::Mat operator()(cv::InputArray _src) { cv::Mat operator()(cv::InputArray _src) {
Mat dst; Mat dst;
GaussianBlur(_src, dst, Size(size,size), sigma, sigma); cv::GaussianBlur(_src, dst, Size(size,size), sigma, sigma);
return dst; return dst;
} }
}; };
...@@ -82,6 +82,7 @@ namespace ball_tracking { ...@@ -82,6 +82,7 @@ namespace ball_tracking {
double thresh; double thresh;
SimpleBlobDetector::Params params; SimpleBlobDetector::Params params;
Ptr<SimpleBlobDetector> detector; Ptr<SimpleBlobDetector> detector;
Binarizer bin;
public: public:
void set_blob_params(const json& conf) { void set_blob_params(const json& conf) {
if (conf.count("filterByArea")) { if (conf.count("filterByArea")) {
...@@ -94,6 +95,7 @@ namespace ball_tracking { ...@@ -94,6 +95,7 @@ namespace ball_tracking {
params.minCircularity = conf.at("minCircularity"); params.minCircularity = conf.at("minCircularity");
params.maxCircularity = conf.at("maxCircularity"); params.maxCircularity = conf.at("maxCircularity");
} }
bin = Binarizer(conf.at("binarizer"));
} }
CV_blob_detect(const json& conf) { CV_blob_detect(const json& conf) {
...@@ -105,8 +107,9 @@ namespace ball_tracking { ...@@ -105,8 +107,9 @@ namespace ball_tracking {
#endif #endif
} }
vector<KeyPoint> operator()(cv::InputArray bin_img) { vector<KeyPoint> operator()(cv::InputArray llh) {
vector<KeyPoint> ans; vector<KeyPoint> ans;
Mat bin_img = bin(llh);
detector->detect(bin_img, ans); detector->detect(bin_img, ans);
return ans; return ans;
} }
...@@ -136,7 +139,11 @@ namespace ball_tracking { ...@@ -136,7 +139,11 @@ namespace ball_tracking {
}; };
Binarizer::Binarizer(const nlohmann::json& params) { Binarizer::Binarizer(const nlohmann::json& params) {
_impl = unique_ptr<Impl>(new Impl(params)); _impl = shared_ptr<Impl>(new Impl(params));
}
Binarizer::Binarizer() {
_impl = nullptr;
} }
Binarizer::~Binarizer() = default; Binarizer::~Binarizer() = default;
...@@ -162,7 +169,11 @@ namespace ball_tracking { ...@@ -162,7 +169,11 @@ namespace ball_tracking {
}; };
BallLogLikelihood::BallLogLikelihood(const nlohmann::json& params) { BallLogLikelihood::BallLogLikelihood(const nlohmann::json& params) {
_impl = unique_ptr<Impl>(new Impl(params)); _impl = shared_ptr<Impl>(new Impl(params));
}
BallLogLikelihood::BallLogLikelihood() {
_impl = nullptr;
} }
BallLogLikelihood::~BallLogLikelihood() = default; BallLogLikelihood::~BallLogLikelihood() = default;
...@@ -188,7 +199,11 @@ namespace ball_tracking { ...@@ -188,7 +199,11 @@ namespace ball_tracking {
}; };
FindBallBlob::FindBallBlob(const nlohmann::json& params) { FindBallBlob::FindBallBlob(const nlohmann::json& params) {
_impl = unique_ptr<Impl>(new Impl(params)); _impl = shared_ptr<Impl>(new Impl(params));
}
FindBallBlob::FindBallBlob() {
_impl = nullptr;
} }
FindBallBlob::~FindBallBlob() = default; FindBallBlob::~FindBallBlob() = default;
...@@ -198,4 +213,96 @@ namespace ball_tracking { ...@@ -198,4 +213,96 @@ namespace ball_tracking {
} }
/**
* Implementation of the tracker class
*/
namespace {
class CPUTracker {
private:
BallLogLikelihood llh;
FindBallBlob blob_detect;
public:
CPUTracker(const json& conf) {
llh = BallLogLikelihood(conf.at("ball_log_lh"));
blob_detect = FindBallBlob(conf.at("blob_detection"));
}
vector<KeyPoint> operator()(cv::InputArray img) {
Mat llh_img = llh(img);
return blob_detect(llh_img);
}
};
#ifdef WITH_CUDA
#include <ball_tracking/cuda/tracker.hpp>
#include <opencv2/core.hpp>
class GPUTracker {
private:
ball_tracking::cuda::BallLogLikelihood llh; //!< Fully implemented in GPU
FindBallBlob blob_detect; //!< For the moment only implemented in CPU
cv::cuda::Stream stream;
public:
GPUTracker(const json& conf) {
llh = ball_tracking::cuda::BallLogLikelihood(conf.at("ball_log_lh"));
blob_detect = FindBallBlob(conf.at("blob_detection"));
}
vector<KeyPoint> operator()(cv::InputArray _img) {
Mat img = _img.getMat();
GpuMat gpu_img(img, stream);
GpuMat gpu_llh_img;
llh(gpu_img, gpu_llh_img, stream);
Mat llh_img;
gpu_llh_img.download(llh_img, stream);
stream.waitForCompletion();
return blob_detect(llh_img);
}
};
#else
class GPUTracker {
public:
GPUTracker(const json& conf) {
throw new std::logic_error("Calling a GPU function on a CPU only compiled tracker");
}
vector<KeyPoint> operator()(cv::InputArray _img) {
throw new std::logic_error("Calling a GPU function on a CPU only compiled tracker");
}
};
#endif
};
class Tracker::Impl {
public:
blob_finder tracker;
Impl(const json& conf) {
string type = conf.at("type");
if (type == "cpu") {
tracker = CPUTracker(conf.at("conf"));
} else if (type == "gpu") {
tracker = GPUTracker(conf.at("gpu"));
} else {
throw std::logic_error("Type of tracker selected in the configuration is not recognized");
}
}
};
Tracker::Tracker(const nlohmann::json& params) {
_impl = shared_ptr<Impl>(new Impl(params));
}
Tracker::Tracker() {
_impl = nullptr;
}
Tracker::~Tracker() = default;
std::vector<cv::KeyPoint> Tracker::operator()(cv::InputArray src) {
return _impl->tracker(src);
}
}; };
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment