diff --git a/modules/objdetect/doc/soft_cascade.rst b/modules/objdetect/doc/soft_cascade.rst index 0ba7566012..ac537b3a81 100644 --- a/modules/objdetect/doc/soft_cascade.rst +++ b/modules/objdetect/doc/soft_cascade.rst @@ -39,6 +39,7 @@ Implementation of soft (stageless) cascaded detector. :: cv::AlgorithmInfo* info() const; virtual bool load(const FileNode& fn); virtual void detect(InputArray image, InputArray rois, std::vector& objects) const; + virtual void detect(InputArray image, InputArray rois, OutputArray rects, OutputArray confs) const; }; @@ -80,10 +81,16 @@ SCascade::detect -------------------------- Apply cascade to an input frame and return the vector of Decection objcts. -.. ocv:function:: bool SCascade::detect(InputArray image, InputArray rois, std::vector& objects) const +.. ocv:function:: void SCascade::detect(InputArray image, InputArray rois, std::vector& objects) const + +.. ocv:function:: void SCascade::detect(InputArray image, InputArray rois, OutputArray rects, OutputArray confs) const :param image: a frame on which detector will be applied. :param rois: a vector of regions of interest. Only the objects that fall into one of the regions will be returned. - :param objects: an output array of Detections. \ No newline at end of file + :param objects: an output array of Detections. + + :param rects: an output array of bounding rectangles for detected objects. + + :param confs: an output array of confidence for detected objects. i-th bounding rectangle corresponds i-th configence. \ No newline at end of file diff --git a/modules/objdetect/include/opencv2/objdetect/objdetect.hpp b/modules/objdetect/include/opencv2/objdetect/objdetect.hpp index 98c4f0a79e..a78bef56f1 100644 --- a/modules/objdetect/include/opencv2/objdetect/objdetect.hpp +++ b/modules/objdetect/include/opencv2/objdetect/objdetect.hpp @@ -490,7 +490,7 @@ protected: // Implementation of soft (stageless) cascaded detector. -class CV_EXPORTS SCascade : public Algorithm +class CV_EXPORTS_W SCascade : public Algorithm { public: @@ -539,24 +539,27 @@ public: // Param minScale is a maximum scale relative to the original size of the image on which cascade will be applyed. // Param scales is a number of scales from minScale to maxScale. // Param rejfactor is used for NMS. - SCascade(const double minScale = 0.4, const double maxScale = 5., const int scales = 55, const int rejfactor = 1); + CV_WRAP SCascade(const double minScale = 0.4, const double maxScale = 5., const int scales = 55, const int rejfactor = 1); - virtual ~SCascade(); + CV_WRAP virtual ~SCascade(); cv::AlgorithmInfo* info() const; // Load cascade from FileNode. // Param fn is a root node for cascade. Should be . - virtual bool load(const FileNode& fn); + CV_WRAP virtual bool load(const FileNode& fn); // Load cascade config. - virtual void read(const FileNode& fn); + CV_WRAP virtual void read(const FileNode& fn); // Return the vector of Decection objcts. // Param image is a frame on which detector will be applied. // Param rois is a vector of regions of interest. Only the objects that fall into one of the regions will be returned. // Param objects is an output array of Detections virtual void detect(InputArray image, InputArray rois, std::vector& objects) const; + // Param rects is an output array of bounding rectangles for detected objects. + // Param confs is an output array of confidence for detected objects. i-th bounding rectangle corresponds i-th configence. + CV_WRAP virtual void detect(InputArray image, InputArray rois, OutputArray rects, OutputArray confs) const; private: void detectNoRoi(const Mat& image, std::vector& objects) const; diff --git a/modules/objdetect/src/softcascade.cpp b/modules/objdetect/src/softcascade.cpp index bfda83426a..e3bcdfe67a 100644 --- a/modules/objdetect/src/softcascade.cpp +++ b/modules/objdetect/src/softcascade.cpp @@ -500,4 +500,27 @@ void cv::SCascade::detect(cv::InputArray _image, cv::InputArray _rois, std::vect } } } +} + +void cv::SCascade::detect(InputArray _image, InputArray _rois, OutputArray _rects, OutputArray _confs) const +{ + std::vector objects; + detect( _image, _rois, objects); + + _rects.create(1, objects.size(), CV_32SC4); + cv::Mat_ rects = (cv::Mat_)_rects.getMat(); + cv::Rect* rectPtr = rects.ptr(0); + + _confs.create(1, objects.size(), CV_32F); + cv::Mat confs = _confs.getMat(); + float* confPtr = rects.ptr(0); + + typedef std::vector::const_iterator IDet; + + int i = 0; + for (IDet it = objects.begin(); it != objects.end(); ++it, ++i) + { + rectPtr[i] = (*it).bb; + confPtr[i] = (*it).confidence; + } } \ No newline at end of file diff --git a/modules/objdetect/test/test_softcascade.cpp b/modules/objdetect/test/test_softcascade.cpp index d33d5892bf..b5632400a5 100644 --- a/modules/objdetect/test/test_softcascade.cpp +++ b/modules/objdetect/test/test_softcascade.cpp @@ -66,34 +66,26 @@ TEST(SCascade, detect) std::vector objects; cascade.detect(colored, cv::noArray(), objects); - - // cv::Mat out = colored.clone(); - // int level = 0, total = 0; - // int levelWidth = objects[0].bb.width; - - // for(int i = 0 ; i < (int)objects.size(); ++i) - // { - // if (objects[i].bb.width != levelWidth) - // { - // std::cout << "Level: " << level << " total " << total << std::endl; - // cv::imshow("out", out); - // cv::waitKey(0); - // out = colored.clone(); - // levelWidth = objects[i].bb.width; - // total = 0; - // level++; - // } - // cv::rectangle(out, objects[i].bb, cv::Scalar(255, 0, 0, 255), 1); - // std::cout << "detection: " << objects[i].bb.x - // << " " << objects[i].bb.y - // << " " << objects[i].bb.width - // << " " << objects[i].bb.height << std::endl; - // total++; - // } - // std::cout << "detected: " << (int)objects.size() << std::endl; ASSERT_EQ((int)objects.size(), 3498); } +TEST(SCascade, detectSeparate) +{ + typedef cv::SCascade::Detection Detection; + std::string xml = cvtest::TS::ptr()->get_data_path() + "cascadeandhog/sc_cvpr_2012_to_opencv.xml"; + cv::SCascade cascade; + cv::FileStorage fs(xml, cv::FileStorage::READ); + ASSERT_TRUE(cascade.load(fs.getFirstTopLevelNode())); + + cv::Mat colored = cv::imread(cvtest::TS::ptr()->get_data_path() + "cascadeandhog/bahnhof/image_00000000_0.png"); + ASSERT_FALSE(colored.empty()); + + cv::Mat rects, confs; + + cascade.detect(colored, cv::noArray(), rects, confs); + ASSERT_EQ(confs.cols, 3498); +} + TEST(SCascade, detectRoi) { typedef cv::SCascade::Detection Detection; @@ -110,31 +102,6 @@ TEST(SCascade, detectRoi) rois.push_back(cv::Rect(0, 0, 640, 480)); cascade.detect(colored, rois, objects); - - // cv::Mat out = colored.clone(); - // int level = 0, total = 0; - // int levelWidth = objects[0].bb.width; - - // for(int i = 0 ; i < (int)objects.size(); ++i) - // { - // if (objects[i].bb.width != levelWidth) - // { - // std::cout << "Level: " << level << " total " << total << std::endl; - // cv::imshow("out", out); - // cv::waitKey(0); - // out = colored.clone(); - // levelWidth = objects[i].bb.width; - // total = 0; - // level++; - // } - // cv::rectangle(out, objects[i].bb, cv::Scalar(255, 0, 0, 255), 1); - // std::cout << "detection: " << objects[i].bb.x - // << " " << objects[i].bb.y - // << " " << objects[i].bb.width - // << " " << objects[i].bb.height << std::endl; - // total++; - // } - // std::cout << "detected: " << (int)objects.size() << std::endl; ASSERT_EQ((int)objects.size(), 3498); }