diff --git a/include/detection.hpp b/include/detection.hpp index 46930d3..afa107f 100644 --- a/include/detection.hpp +++ b/include/detection.hpp @@ -2,8 +2,8 @@ #include #include - #include "opencv2/core/core.hpp" +#include "opencv2/objdetect.hpp" class Detector { public: @@ -12,3 +12,12 @@ class Detector { virtual void Detect(const cv::Mat& frame, std::vector& objects, std::vector& scores) = 0; }; + +class CascadeDetector : public Detector +{ + public: + cv::CascadeClassifier ccdetector; + virtual bool Init(const std::string& model_file_path); + virtual void Detect(const cv::Mat& frame, std::vector& objects, + std::vector& scores); +}; \ No newline at end of file diff --git a/samples/detection_demo.cpp b/samples/detection_demo.cpp new file mode 100644 index 0000000..e012476 --- /dev/null +++ b/samples/detection_demo.cpp @@ -0,0 +1,122 @@ +#include +#include + +#include "opencv2/core/core.hpp" +#include "opencv2/opencv.hpp" + +#include "detection.hpp" + +using namespace std; +using namespace cv; + +const char* kAbout = + "detection app"; + +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 }"; + +int main(int argc, const char** argv) { + // Parse command line arguments. + CommandLineParser parser(argc, argv, kOptions); + parser.about(kAbout); + + // If help option is given, print help message and exit. + if (parser.get("help")) { + parser.printMessage(); + return 0; + } + + // init + std::string vidName, imgName, detectName; + Mat frame; + CascadeDetector obj; + std::vector logos; + std::vector scores; + VideoCapture capture; + // + + if (parser.has("m")) + { + detectName = parser.get("m"); + cout << detectName << endl; + obj.Init(detectName); + } + + if (parser.has("i")) + { + imgName = parser.get("i"); + frame = imread(imgName); + imshow("Detection", frame); + obj.Detect(frame, logos, scores); + if (scores.size() > 0) + for (int i = 0; i < logos.size(); i++) + { + rectangle(frame, logos[i], Scalar(255, 0, 0)); + imshow("Detection", frame); + } + else + std::cout << "objects haven`t been detected"; + } + else + { + if (parser.has("v")) + { + vidName = parser.get("v"); + + bool flag = capture.open(vidName); + + if (flag) + { + flag = capture.read(frame); + while (true) + { + if (frame.empty()) + { + cout << " --(!) No captured frame -- Break!"; + break; + } + //Apply the classifier to the frame + obj.Detect(frame, logos, scores); + if (scores.size()> 0) + for(int i = 0; i < logos.size(); i++) + rectangle(frame, logos[i], Scalar(255, 0, 0)); + imshow("Detection", frame); + capture >> frame; + int c = cv::waitKey(100); + if ((char)c == 27) break; // escape + } + capture.release(); + } + else + cout << "--(!)Error opening video capture" << endl ; + + } + else + if (parser.has("c")) + { + capture.open(0); + if (!capture.isOpened()) + return 0; + capture.read(frame); + for (;;) + { + obj.Detect(frame, logos, scores); + if (scores.size() > 0) + for (int i = 0; i < logos.size(); i++) + rectangle(frame, logos[i], Scalar(255, 0, 0)); + capture >> frame; + if (frame.empty()) break; // end of video stream + imshow("Web", frame); + if (waitKey(10) == 27) break; // stop capturing by pressing ESC + } + capture.release(); + } + } + cv::waitKey(0); + + return 0; +} diff --git a/samples/devtools_demo.cpp b/samples/devtools_demo.cpp deleted file mode 100644 index 8c40769..0000000 --- a/samples/devtools_demo.cpp +++ /dev/null @@ -1,64 +0,0 @@ -#include -#include - -#include "opencv2/core.hpp" -#include "opencv2/highgui.hpp" - -#include "workaround.hpp" - -using namespace std; -using namespace cv; - -const char* kAbout = "Application for practice #1."; - -const char* kOptions = - "{ @image | | image to process }" - "{ t | 128 | threshold }" - "{ h ? help usage | | print help message }"; - -int main(int argc, const char** argv) { - // Parse command line arguments. - CommandLineParser parser(argc, argv, kOptions); - parser.about(kAbout); - - // If help option is given, print help message and exit. - if (parser.has("help")) { - parser.printMessage(); - return 0; - } - - // Read image. - Mat src = imread(parser.get(0), CV_LOAD_IMAGE_GRAYSCALE); - if (src.empty()) { - cout << "Failed to open image file '" + parser.get(0) + "'." - << endl; - return 0; - } - - // Show source image. - const string kSrcWindowName = "Source image"; - const int kWaitKeyDelay = 1; - namedWindow(kSrcWindowName, WINDOW_NORMAL); - resizeWindow(kSrcWindowName, 640, 480); - imshow(kSrcWindowName, src); - waitKey(kWaitKeyDelay); - - // Threshold data. - MatrixProcessor processor; - const int threshold = parser.get("t"); - try { - processor.Threshold(src.data, src.cols, src.rows, threshold); - } catch (const std::exception& ex) { - cout << ex.what() << endl; - return 0; - } - - // Show destination image. - const string kDstWindowName = "Destination image"; - namedWindow(kDstWindowName, WINDOW_NORMAL); - resizeWindow(kDstWindowName, 640, 480); - imshow(kDstWindowName, src); - waitKey(); - - return 0; -} diff --git a/samples/template_demo.cpp b/samples/template_demo.cpp deleted file mode 100644 index 3b9eb74..0000000 --- a/samples/template_demo.cpp +++ /dev/null @@ -1,33 +0,0 @@ -#include -#include - -#include "opencv2/core.hpp" - -using namespace std; -using namespace cv; - -const char* kAbout = - "This is an empty application that can be treated as a template for your " - "own doing-something-cool applications."; - -const char* kOptions = - "{ v video | | video to process }" - "{ h ? help usage | | print help message }"; - - -int main(int argc, const char** argv) { - // Parse command line arguments. - CommandLineParser parser(argc, argv, kOptions); - parser.about(kAbout); - - // If help option is given, print help message and exit. - if (parser.get("help")) { - parser.printMessage(); - return 0; - } - - // Do something cool. - cout << "This is empty template sample." << endl; - - return 0; -} diff --git a/src/detection.cpp b/src/detection.cpp index 15e7fd1..855ae0c 100644 --- a/src/detection.cpp +++ b/src/detection.cpp @@ -1,13 +1,40 @@ #include "detection.hpp" -#include - using std::string; using std::shared_ptr; using namespace cv; -shared_ptr Detector::CreateDetector(const string& name) { - std::cerr << "Failed to create detector with name '" << name << "'" - << std::endl; - return nullptr; +shared_ptr Detector::CreateDetector(const string& name) +{ + if (name == "cascade") + { + return std::make_shared(); + } + else + return nullptr; + +} + +bool CascadeDetector::Init(const std::string & model_file_path) +{ + bool flag = false; + if (ccdetector.load(model_file_path)) + flag = true; + return flag; +} + +void CascadeDetector::Detect(const cv::Mat & frame, std::vector& ccdetectorects, + std::vector& scores) +{ + std::vector numDetections; + + if (ccdetector.empty()) return ; + if (frame.empty()) throw "Matrix is empty"; + + //ccdetectorects.clear(); + + ccdetector.detectMultiScale(frame, ccdetectorects, numDetections); + + scores.assign(numDetections.begin(), numDetections.end()); + } diff --git a/training_logo/cascade.xml b/training_logo/cascade.xml new file mode 100644 index 0000000..c426d6d --- /dev/null +++ b/training_logo/cascade.xml @@ -0,0 +1,186 @@ + + + + BOOST + HAAR + 32 + 32 + + GAB + 9.9500000476837158e-01 + 1.0000000149011612e-01 + 9.4999999999999996e-01 + 1 + 100 + + 0 + 1 + BASIC + 4 + + + <_> + 1 + 9.7528421878814697e-01 + + <_> + + 0 -1 10 4.0812580846250057e-03 + + -9.9797672033309937e-01 9.7528421878814697e-01 + + <_> + 2 + -7.0796445012092590e-02 + + <_> + + 0 -1 8 -3.7780940532684326e-02 + + 9.3385213613510132e-01 -9.8765432834625244e-01 + <_> + + 0 -1 7 2.7387058362364769e-03 + + -9.4651961326599121e-01 9.1685789823532104e-01 + + <_> + 4 + -1.6588573157787323e-01 + + <_> + + 0 -1 4 3.4338846802711487e-02 + + -9.0086209774017334e-01 7.7985072135925293e-01 + <_> + + 0 -1 9 -1.1945048347115517e-02 + + 8.0718630552291870e-01 -8.6200785636901855e-01 + <_> + + 0 -1 11 -3.9666537195444107e-03 + + 8.0437922477722168e-01 -8.1469124555587769e-01 + <_> + + 0 -1 2 -9.5642581582069397e-03 + + 7.4248123168945313e-01 -8.1557685136795044e-01 + + <_> + 5 + -5.8510094881057739e-02 + + <_> + + 0 -1 6 7.1976799517869949e-03 + + -8.5774058103561401e-01 7.8544062376022339e-01 + <_> + + 0 -1 1 1.7477976158261299e-02 + + -8.3842450380325317e-01 6.1052769422531128e-01 + <_> + + 0 -1 3 -5.3416676819324493e-03 + + 4.8253062367439270e-01 -9.9687421321868896e-01 + <_> + + 0 -1 0 1.4424304477870464e-02 + + -7.6333725452423096e-01 7.3217594623565674e-01 + <_> + + 0 -1 5 -5.0397003069519997e-03 + + 4.6950939297676086e-01 -9.3885457515716553e-01 + + <_> + + <_> + 1 10 6 13 -1. + <_> + 3 10 2 13 3. + 0 + <_> + + <_> + 2 20 24 3 -1. + <_> + 10 20 8 3 3. + 0 + <_> + + <_> + 6 13 6 6 -1. + <_> + 8 13 2 6 3. + 0 + <_> + + <_> + 7 11 10 8 -1. + <_> + 12 11 5 8 2. + 0 + <_> + + <_> + 12 6 10 9 -1. + <_> + 12 9 10 3 3. + 0 + <_> + + <_> + 12 9 18 2 -1. + <_> + 21 9 9 2 2. + 0 + <_> + + <_> + 12 15 3 2 -1. + <_> + 13 15 1 2 3. + 0 + <_> + + <_> + 12 16 3 1 -1. + <_> + 13 16 1 1 3. + 0 + <_> + + <_> + 14 9 5 15 -1. + <_> + 14 14 5 5 3. + 0 + <_> + + <_> + 14 20 5 6 -1. + <_> + 14 23 5 3 2. + 0 + <_> + + <_> + 15 15 3 2 -1. + <_> + 16 15 1 2 3. + 0 + <_> + + <_> + 15 17 2 3 -1. + <_> + 15 18 2 1 3. + 0 + diff --git a/training_logo/params.xml b/training_logo/params.xml new file mode 100644 index 0000000..cd15c34 --- /dev/null +++ b/training_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/training_logo/stage0.xml b/training_logo/stage0.xml new file mode 100644 index 0000000..76acb3a --- /dev/null +++ b/training_logo/stage0.xml @@ -0,0 +1,12 @@ + + + + 1 + 9.7528421878814697e-01 + + <_> + + 0 -1 377013 4.0812580846250057e-03 + + -9.9797672033309937e-01 9.7528421878814697e-01 + diff --git a/training_logo/stage1.xml b/training_logo/stage1.xml new file mode 100644 index 0000000..9b1b1fe --- /dev/null +++ b/training_logo/stage1.xml @@ -0,0 +1,17 @@ + + + + 2 + -7.0796445012092590e-02 + + <_> + + 0 -1 356598 -3.7780940532684326e-02 + + 9.3385213613510132e-01 -9.8765432834625244e-01 + <_> + + 0 -1 324572 2.7387058362364769e-03 + + -9.4651961326599121e-01 9.1685789823532104e-01 + diff --git a/training_logo/stage2.xml b/training_logo/stage2.xml new file mode 100644 index 0000000..b9d59f4 --- /dev/null +++ b/training_logo/stage2.xml @@ -0,0 +1,27 @@ + + + + 4 + -1.6588573157787323e-01 + + <_> + + 0 -1 317326 3.4338846802711487e-02 + + -9.0086209774017334e-01 7.7985072135925293e-01 + <_> + + 0 -1 363124 -1.1945048347115517e-02 + + 8.0718630552291870e-01 -8.6200785636901855e-01 + <_> + + 0 -1 378057 -3.9666537195444107e-03 + + 8.0437922477722168e-01 -8.1469124555587769e-01 + <_> + + 0 -1 189290 -9.5642581582069397e-03 + + 7.4248123168945313e-01 -8.1557685136795044e-01 + diff --git a/training_logo/stage3.xml b/training_logo/stage3.xml new file mode 100644 index 0000000..0600f91 --- /dev/null +++ b/training_logo/stage3.xml @@ -0,0 +1,32 @@ + + + + 5 + -5.8510094881057739e-02 + + <_> + + 0 -1 323965 7.1976799517869949e-03 + + -8.5774058103561401e-01 7.8544062376022339e-01 + <_> + + 0 -1 87119 1.7477976158261299e-02 + + -8.3842450380325317e-01 6.1052769422531128e-01 + <_> + + 0 -1 212211 -5.3416676819324493e-03 + + 4.8253062367439270e-01 -9.9687421321868896e-01 + <_> + + 0 -1 47236 1.4424304477870464e-02 + + -7.6333725452423096e-01 7.3217594623565674e-01 + <_> + + 0 -1 319968 -5.0397003069519997e-03 + + 4.6950939297676086e-01 -9.3885457515716553e-01 +