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)
project(ball_tracking)
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
${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
src/img_proc.cpp
src/utils.cpp
src/tracker.cpp
src/cuda/tracker.cpp
${GPU_CPP_SRC}
)
target_link_libraries(ball_tracking
${OpenCV_LIBS}
cu_ball_track
${GPU_BT_LIB}
)
#Compile with C++11 support only
......
......@@ -11,14 +11,6 @@ target_link_libraries(color_approach
${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
img_proc/ball_log_lh.cpp
)
......@@ -35,10 +27,21 @@ target_link_libraries(track
${Boost_LIBRARIES}
)
add_executable(gpu_track
tracking/gpu_track.cpp
)
target_link_libraries(gpu_track
ball_tracking
${Boost_LIBRARIES}
)
if (WITH_CUDA)
add_executable(log_reg_approach
img_proc/log_reg_approach.cpp
)
target_link_libraries(log_reg_approach
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) {
end_t = std::chrono::steady_clock::now();
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();
auto bin_img = bin(l_lh);
end_t = std::chrono::steady_clock::now();
......@@ -115,7 +115,7 @@ int main(int argc, char** argv) {
//3) Run blob detection algorithm
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();
blob_time.push_back(std::chrono::duration_cast<std::chrono::microseconds>(end_t - start_t).count());
......
......@@ -40,10 +40,13 @@
},
"binarizer": {
"p_thresh": 0.05
},
},
"blob_detection": {
"type": "cv_blob_detect",
"conf": {
"binarizer": {
"p_thresh": 0.05
},
"filterByArea": true,
"minArea": 8,
"maxArea": 500,
......
......@@ -22,7 +22,7 @@ namespace ball_tracking {
class BallLogLikelihood {
private:
class Impl;
std::unique_ptr<Impl> _impl;
std::shared_ptr<Impl> _impl;
public:
/**
* @brief Creates an object with given configuration parameters
......@@ -30,6 +30,11 @@ namespace ball_tracking {
BallLogLikelihood(const nlohmann::json& params);
~BallLogLikelihood();
/**
* @brief Creates an empty object
*/
BallLogLikelihood();
/**
* @brief Produces a single channel image representing the log likelihood of each
* pixel being part of the ball
......@@ -49,11 +54,16 @@ namespace ball_tracking {
class Binarizer {
private:
class Impl;
std::unique_ptr<Impl> _impl;
std::shared_ptr<Impl> _impl;
public:
Binarizer(const nlohmann::json& params);
~Binarizer();
/**
* @brief Creates an empty object
*/
Binarizer();
/**
* @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.
......@@ -70,11 +80,16 @@ namespace ball_tracking {
class FindBallBlob {
private:
class Impl;
std::unique_ptr<Impl> _impl;
std::shared_ptr<Impl> _impl;
public:
FindBallBlob(const nlohmann::json& params);
~FindBallBlob();
/**
* @brief Creates an empty object
*/
FindBallBlob();
/**
* @brief Returns all candidate locations of a ball in a single channel
* likelihood image.
......
......@@ -25,12 +25,21 @@ namespace ball_tracking {
class BallLogLikelihood {
private:
class Impl;
std::unique_ptr<Impl> _impl;
std::shared_ptr<Impl> _impl;
public:
/**
* @brief Creates an object with given configuration parameters
*/
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();
/**
......@@ -51,9 +60,18 @@ namespace ball_tracking {
class Binarizer {
private:
class Impl;
std::unique_ptr<Impl> _impl;
std::shared_ptr<Impl> _impl;
public:
/**
* @brief Creates a binarizer with the given configuration
*/
Binarizer(const nlohmann::json& params);
/**
* @brief Creates an empty object
*/
Binarizer();
~Binarizer();
/**
......@@ -72,11 +90,16 @@ namespace ball_tracking {
class FindBallBlob {
private:
class Impl;
std::unique_ptr<Impl> _impl;
std::shared_ptr<Impl> _impl;
public:
FindBallBlob(const nlohmann::json& params);
~FindBallBlob();
/**
* @brief Creates an empty object
*/
FindBallBlob();
/**
* @brief Returns all candidate locations of a ball in a single channel
* likelihood image.
......@@ -87,6 +110,21 @@ namespace ball_tracking {
*/
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
......@@ -83,7 +83,11 @@ namespace ball_tracking {
};
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;
......@@ -114,7 +118,11 @@ namespace ball_tracking {
};
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;
......
......@@ -28,7 +28,7 @@ namespace ball_tracking {
cv::Mat operator()(cv::InputArray _src) {
Mat dst;
GaussianBlur(_src, dst, Size(size,size), sigma, sigma);
cv::GaussianBlur(_src, dst, Size(size,size), sigma, sigma);
return dst;
}
};
......@@ -82,6 +82,7 @@ namespace ball_tracking {
double thresh;
SimpleBlobDetector::Params params;
Ptr<SimpleBlobDetector> detector;
Binarizer bin;
public:
void set_blob_params(const json& conf) {
if (conf.count("filterByArea")) {
......@@ -94,6 +95,7 @@ namespace ball_tracking {
params.minCircularity = conf.at("minCircularity");
params.maxCircularity = conf.at("maxCircularity");
}
bin = Binarizer(conf.at("binarizer"));
}
CV_blob_detect(const json& conf) {
......@@ -105,8 +107,9 @@ namespace ball_tracking {
#endif
}
vector<KeyPoint> operator()(cv::InputArray bin_img) {
vector<KeyPoint> operator()(cv::InputArray llh) {
vector<KeyPoint> ans;
Mat bin_img = bin(llh);
detector->detect(bin_img, ans);
return ans;
}
......@@ -136,7 +139,11 @@ namespace ball_tracking {
};
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;
......@@ -162,7 +169,11 @@ namespace ball_tracking {
};
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;
......@@ -188,7 +199,11 @@ namespace ball_tracking {
};
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;
......@@ -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