diff --git a/include/detection.hpp b/include/detection.hpp index 46930d3..a86cf7d 100644 --- a/include/detection.hpp +++ b/include/detection.hpp @@ -4,6 +4,8 @@ #include #include "opencv2/core/core.hpp" +#include "opencv2/opencv.hpp" + class Detector { public: @@ -12,3 +14,14 @@ class Detector { virtual void Detect(const cv::Mat& frame, std::vector& objects, std::vector& scores) = 0; }; + + +class CascadeDetector : public Detector { +protected: + cv::CascadeClassifier detector; + +public: + bool Init(const std::string& model_file_path) override; + void Detect(const cv::Mat& frame, std::vector& objects, + std::vector& scores) override; +}; \ No newline at end of file diff --git a/logo/cascade.xml b/logo/cascade.xml new file mode 100644 index 0000000..d847504 --- /dev/null +++ b/logo/cascade.xml @@ -0,0 +1,180 @@ + + + + BOOST + HAAR + 32 + 32 + + GAB + 9.9500000476837158e-01 + 1.0000000149011612e-01 + 9.4999999999999996e-01 + 1 + 100 + + 0 + 1 + BASIC + 4 + + + <_> + 1 + 9.9600797891616821e-01 + + <_> + + 0 -1 7 -1.7688340740278363e-03 + + 9.9600797891616821e-01 -1. + + <_> + 2 + -2.6523093692958355e-03 + + <_> + + 0 -1 1 1.8934525549411774e-02 + + -9.5247524976730347e-01 9.7171717882156372e-01 + <_> + + 0 -1 10 2.6852805167436600e-02 + + -9.7436946630477905e-01 9.5748162269592285e-01 + + <_> + 4 + -3.0785626173019409e-01 + + <_> + + 0 -1 9 4.7774590551853180e-02 + + -9.5717346668243408e-01 8.3864915370941162e-01 + <_> + + 0 -1 0 1.0246830061078072e-02 + + -9.2844742536544800e-01 8.5343450307846069e-01 + <_> + + 0 -1 2 -2.2323392331600189e-02 + + 7.4373298883438110e-01 -8.7865394353866577e-01 + <_> + + 0 -1 6 2.2783260792493820e-03 + + -9.9281847476959229e-01 6.6059595346450806e-01 + + <_> + 4 + -3.2509520649909973e-01 + + <_> + + 0 -1 3 2.2154441103339195e-03 + + -8.5714286565780640e-01 8.2352942228317261e-01 + <_> + + 0 -1 8 1.8704606220126152e-02 + + -9.6440863609313965e-01 7.2768908739089966e-01 + <_> + + 0 -1 5 -8.6188763380050659e-03 + + 6.9022244215011597e-01 -9.2877584695816040e-01 + <_> + + 0 -1 4 -3.9481376297771931e-03 + + 7.3313444852828979e-01 -8.5507124662399292e-01 + + <_> + + <_> + 4 19 9 2 -1. + <_> + 7 19 3 2 3. + 0 + <_> + + <_> + 5 16 8 8 -1. + <_> + 5 16 4 4 2. + <_> + 9 20 4 4 2. + 0 + <_> + + <_> + 6 12 6 9 -1. + <_> + 9 12 3 9 2. + 0 + <_> + + <_> + 6 18 3 1 -1. + <_> + 7 18 1 1 3. + 0 + <_> + + <_> + 6 22 6 4 -1. + <_> + 6 22 3 2 2. + <_> + 9 24 3 2 2. + 0 + <_> + + <_> + 13 16 2 9 -1. + <_> + 13 19 2 3 3. + 0 + <_> + + <_> + 13 17 3 1 -1. + <_> + 14 17 1 1 3. + 0 + <_> + + <_> + 14 15 2 1 -1. + <_> + 15 15 1 1 2. + 0 + <_> + + <_> + 17 11 4 14 -1. + <_> + 17 18 4 7 2. + 0 + <_> + + <_> + 19 12 9 9 -1. + <_> + 22 12 3 9 3. + 0 + <_> + + <_> + 22 14 8 14 -1. + <_> + 22 14 4 7 2. + <_> + 26 21 4 7 2. + 0 + diff --git a/logo/params.xml b/logo/params.xml new file mode 100644 index 0000000..cd15c34 --- /dev/null +++ b/logo/params.xml @@ -0,0 +1,19 @@ + + + + BOOST + HAAR + 32 + 32 + + GAB + 9.9500000476837158e-01 + 1.0000000149011612e-01 + 9.4999999999999996e-01 + 1 + 100 + + 0 + 1 + BASIC + diff --git a/logo/stage0.xml b/logo/stage0.xml new file mode 100644 index 0000000..e6cec3c --- /dev/null +++ b/logo/stage0.xml @@ -0,0 +1,12 @@ + + + + 1 + 9.9600797891616821e-01 + + <_> + + 0 -1 360442 -1.7688340740278363e-03 + + 9.9600797891616821e-01 -1. + diff --git a/logo/stage1.xml b/logo/stage1.xml new file mode 100644 index 0000000..b185d58 --- /dev/null +++ b/logo/stage1.xml @@ -0,0 +1,17 @@ + + + + 2 + -2.6523093692958355e-03 + + <_> + + 0 -1 166367 1.8934525549411774e-02 + + -9.5247524976730347e-01 9.7171717882156372e-01 + <_> + + 0 -1 466264 2.6852805167436600e-02 + + -9.7436946630477905e-01 9.5748162269592285e-01 + diff --git a/logo/stage2.xml b/logo/stage2.xml new file mode 100644 index 0000000..493de4c --- /dev/null +++ b/logo/stage2.xml @@ -0,0 +1,27 @@ + + + + 4 + -3.0785626173019409e-01 + + <_> + + 0 -1 432787 4.7774590551853180e-02 + + -9.5717346668243408e-01 8.3864915370941162e-01 + <_> + + 0 -1 142016 1.0246830061078072e-02 + + -9.2844742536544800e-01 8.5343450307846069e-01 + <_> + + 0 -1 188405 -2.2323392331600189e-02 + + 7.4373298883438110e-01 -8.7865394353866577e-01 + <_> + + 0 -1 343658 2.2783260792493820e-03 + + -9.9281847476959229e-01 6.6059595346450806e-01 + diff --git a/logo/stage3.xml b/logo/stage3.xml new file mode 100644 index 0000000..dc76044 --- /dev/null +++ b/logo/stage3.xml @@ -0,0 +1,27 @@ + + + + 4 + -3.2509520649909973e-01 + + <_> + + 0 -1 193289 2.2154441103339195e-03 + + -8.5714286565780640e-01 8.2352942228317261e-01 + <_> + + 0 -1 405647 1.8704606220126152e-02 + + -9.6440863609313965e-01 7.2768908739089966e-01 + <_> + + 0 -1 343163 -8.6188763380050659e-03 + + 6.9022244215011597e-01 -9.2877584695816040e-01 + <_> + + 0 -1 195738 -3.9481376297771931e-03 + + 7.3313444852828979e-01 -8.5507124662399292e-01 + diff --git a/samples/detection_demo.cpp b/samples/detection_demo.cpp new file mode 100644 index 0000000..ef32790 --- /dev/null +++ b/samples/detection_demo.cpp @@ -0,0 +1,71 @@ +#include +#include "detection.hpp" + +using namespace std; +using namespace cv; + +const char* kOptions = +"{ i image | | image to process }" +"{ v video | | video to process }" +"{ c camera | | camera to get video from }" +"{ m model | | path to detector file }" +"{ h ? help usage | | print help message }"; + +void DetectOnVideo(VideoCapture vid, CascadeDetector &detector) { + std::vector objects; + std::vector scores; + while (true) { + Mat frame; + bool successRead = vid.read(frame); + if (!successRead) break; + detector.Detect(frame, objects, scores); + for (auto obj : objects) + rectangle(frame, obj, Scalar(250, 150, 10)); + imshow("Result", frame); + if (waitKey(10) == 27) break; + } +} + + +int main(int argc, const char** argv) { + // Parse command line arguments. + CommandLineParser parser(argc, argv, kOptions); + + // If help option is given, print help message and exit. + if (parser.get("h")) { + parser.printMessage(); + return 0; + } + + CascadeDetector detector; + std::vector objects; + std::vector scores; + if (parser.has("m")) detector.Init(parser.get("m")); + + if (parser.has("i")) { + Mat img = imread(parser.get("i")); + detector.Detect(img, objects, scores); + for (int i = 0; i < objects.size(); ++i){ + namedWindow("Result"); + rectangle(img, objects[i], Scalar(250, 150, 10)); + imshow("Result", img); + } + } + else if (parser.has("v")) { + VideoCapture video(parser.get("v")); + DetectOnVideo(video, detector); + video.release(); + } + else if (parser.has("c")) { + + VideoCapture cap(0); + if (!cap.isOpened()) + return -1; + DetectOnVideo(cap, detector); + cap.release(); + } + + waitKey(0); + + return 0; +} \ No newline at end of file diff --git a/src/detection.cpp b/src/detection.cpp index 15e7fd1..c61f99e 100644 --- a/src/detection.cpp +++ b/src/detection.cpp @@ -7,7 +7,29 @@ using std::shared_ptr; using namespace cv; shared_ptr Detector::CreateDetector(const string& name) { - std::cerr << "Failed to create detector with name '" << name << "'" + if (name == "cascade") + return std::make_shared(); + + std::cerr << "Failed to create detector with name '" << name << "'" << std::endl; - return nullptr; + return nullptr; } + +bool CascadeDetector::Init(const std::string& model_file_path) { + detector.load(model_file_path); + return detector.empty(); +} + +void CascadeDetector::Detect(const cv::Mat& frame, std::vector& objects, + std::vector& scores) { + objects.clear(); + if (frame.empty()) throw "ERROR"; + if (detector.empty()) return; + std::vector tmp; + detector.detectMultiScale(frame, objects, tmp); + scores.clear(); + scores.resize(tmp.size()); + std::copy(tmp.begin(), tmp.end(), scores.begin()); +} + +