From 02646427fb04e80bb56bfb25e9aa88e7d4da364e Mon Sep 17 00:00:00 2001 From: LeonidBeynenson Date: Thu, 1 Nov 2012 19:31:45 +0400 Subject: [PATCH 01/91] Fixed arguments of the function calcOpticalFlowSF. --- .../video/include/opencv2/video/tracking.hpp | 12 +++++----- modules/video/src/simpleflow.cpp | 23 +++++++++++-------- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/modules/video/include/opencv2/video/tracking.hpp b/modules/video/include/opencv2/video/tracking.hpp index deef20b42..be9407aca 100644 --- a/modules/video/include/opencv2/video/tracking.hpp +++ b/modules/video/include/opencv2/video/tracking.hpp @@ -328,16 +328,16 @@ CV_EXPORTS_W Mat estimateRigidTransform( InputArray src, InputArray dst, bool fullAffine); //! computes dense optical flow using Simple Flow algorithm -CV_EXPORTS_W void calcOpticalFlowSF(Mat& from, - Mat& to, - Mat& flow, +CV_EXPORTS_W void calcOpticalFlowSF(InputArray from, + InputArray to, + OutputArray flow, int layers, int averaging_block_size, int max_flow); -CV_EXPORTS_W void calcOpticalFlowSF(Mat& from, - Mat& to, - Mat& flow, +CV_EXPORTS_W void calcOpticalFlowSF(InputArray from, + InputArray to, + OutputArray flow, int layers, int averaging_block_size, int max_flow, diff --git a/modules/video/src/simpleflow.cpp b/modules/video/src/simpleflow.cpp index 1de8084c5..81886eb2c 100644 --- a/modules/video/src/simpleflow.cpp +++ b/modules/video/src/simpleflow.cpp @@ -447,7 +447,7 @@ static void extrapolateFlow(Mat& flow, } } -static void buildPyramidWithResizeMethod(Mat& src, +static void buildPyramidWithResizeMethod(const Mat& src, vector& pyramid, int layers, int interpolation_type) { @@ -464,9 +464,9 @@ static void buildPyramidWithResizeMethod(Mat& src, } } -CV_EXPORTS_W void calcOpticalFlowSF(Mat& from, - Mat& to, - Mat& resulted_flow, +CV_EXPORTS_W void calcOpticalFlowSF(InputArray _from, + InputArray _to, + OutputArray _resulted_flow, int layers, int averaging_radius, int max_flow, @@ -479,7 +479,11 @@ CV_EXPORTS_W void calcOpticalFlowSF(Mat& from, int upscale_averaging_radius, double upscale_sigma_dist, double upscale_sigma_color, - double speed_up_thr) { + double speed_up_thr) +{ + Mat from = _from.getMat(); + Mat to = _to.getMat(); + vector pyr_from_images; vector pyr_to_images; @@ -632,14 +636,15 @@ CV_EXPORTS_W void calcOpticalFlowSF(Mat& from, GaussianBlur(flow, flow, Size(3, 3), 5); - resulted_flow = Mat(flow.size(), CV_32FC2); + _resulted_flow.create(flow.size(), CV_32FC2); + Mat resulted_flow = _resulted_flow.getMat(); int from_to[] = {0,1 , 1,0}; mixChannels(&flow, 1, &resulted_flow, 1, from_to, 2); } -CV_EXPORTS_W void calcOpticalFlowSF(Mat& from, - Mat& to, - Mat& flow, +CV_EXPORTS_W void calcOpticalFlowSF(InputArray from, + InputArray to, + OutputArray flow, int layers, int averaging_block_size, int max_flow) { From 108fd169f7e253de7435437293c726f4ae195c5f Mon Sep 17 00:00:00 2001 From: "marina.kolpakova" Date: Tue, 28 Aug 2012 17:42:15 +0400 Subject: [PATCH 02/91] dummy soft cascade --- .../include/opencv2/objdetect/objdetect.hpp | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/modules/objdetect/include/opencv2/objdetect/objdetect.hpp b/modules/objdetect/include/opencv2/objdetect/objdetect.hpp index c9f740764..fbcc6ba5c 100644 --- a/modules/objdetect/include/opencv2/objdetect/objdetect.hpp +++ b/modules/objdetect/include/opencv2/objdetect/objdetect.hpp @@ -411,7 +411,7 @@ protected: enum { DO_CANNY_PRUNING = 1, SCALE_IMAGE = 2, FIND_BIGGEST_OBJECT = 4, DO_ROUGH_SEARCH = 8 }; - friend class CascadeClassifierInvoker; + friend struct CascadeClassifierInvoker; template friend int predictOrdered( CascadeClassifier& cascade, Ptr &featureEvaluator, double& weight); @@ -488,6 +488,28 @@ protected: Ptr maskGenerator; }; +// ======================== soft cascade version ===================== // + +class CV_EXPORTS SoftCascade +{ +public: + SoftCascade(); + SoftCascade( const string& filename ); + virtual ~SoftCascade(); + bool load( const string& filename ); + + virtual void detectMultiScale(const Mat& image, const std::vector& rois, std::vector& objects, double factor = 1.05, int step = 4, int rejectfactor = 1); + +protected: + virtual void detectForOctave(int octave); + // virtual bool detectSingleScale( const Mat& image, int stripCount, Size processingRectSize, + // int stripSize, int yStep, double factor, vector& candidates, + // vector& rejectLevels, vector& levelWeights, bool outputRejectLevels=false); + enum { BOOST = 0 }; +private: + struct Filds; + Filds* filds; +}; //////////////// HOG (Histogram-of-Oriented-Gradients) Descriptor and Object Detector ////////////// From 9966d7feba7a3f35196f99e1a4263841cdac634d Mon Sep 17 00:00:00 2001 From: "marina.kolpakova" Date: Tue, 28 Aug 2012 20:01:40 +0400 Subject: [PATCH 03/91] add structures for cascade representation --- .../include/opencv2/objdetect/objdetect.hpp | 12 +++ modules/objdetect/src/softcascade.cpp | 74 +++++++++++++++++++ modules/objdetect/test/test_softcascade.cpp | 47 ++++++++++++ 3 files changed, 133 insertions(+) create mode 100644 modules/objdetect/src/softcascade.cpp create mode 100644 modules/objdetect/test/test_softcascade.cpp diff --git a/modules/objdetect/include/opencv2/objdetect/objdetect.hpp b/modules/objdetect/include/opencv2/objdetect/objdetect.hpp index fbcc6ba5c..690d63bbc 100644 --- a/modules/objdetect/include/opencv2/objdetect/objdetect.hpp +++ b/modules/objdetect/include/opencv2/objdetect/objdetect.hpp @@ -506,7 +506,19 @@ protected: // int stripSize, int yStep, double factor, vector& candidates, // vector& rejectLevels, vector& levelWeights, bool outputRejectLevels=false); enum { BOOST = 0 }; + private: + struct Feature + { + cv::Rect rect; + int channel; + }; + + stuct Stamp + { + + }; + struct Filds; Filds* filds; }; diff --git a/modules/objdetect/src/softcascade.cpp b/modules/objdetect/src/softcascade.cpp new file mode 100644 index 000000000..1d2604c1b --- /dev/null +++ b/modules/objdetect/src/softcascade.cpp @@ -0,0 +1,74 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2008-2011, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +//M*/ + +struct Filds +{ + // cv::Mat luv; + // std::vector bins; + // cv::Mat magnitude; + // double scaleFactor; + // int windowStep; +}; + + +SoftCascade::SoftCascade() : filds(0) {} + +SoftCascade::SoftCascade( const string& filename ) +{ + filds = new filds; + load(filename); +} +virtual SoftCascade::~SoftCascade() +{ + delete filds; +} + +bool SoftCascade::load( const string& filename ) +{ + return true; +} + +virtual void SoftCascade::detectMultiScale(const Mat& image, const std::vector& rois, std::vector& objects, + const double factor = 1.05, const int step = 4, const int rejectfactor = 1) +{} + +virtual void SoftCascade::detectForOctave(const int octave) +{} \ No newline at end of file diff --git a/modules/objdetect/test/test_softcascade.cpp b/modules/objdetect/test/test_softcascade.cpp new file mode 100644 index 000000000..fc7baaad2 --- /dev/null +++ b/modules/objdetect/test/test_softcascade.cpp @@ -0,0 +1,47 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2008-2011, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +//M*/ + +#include "test_precomp.hpp" + +TEST(SoftCascade, HOG) +{ + +} \ No newline at end of file From cd301e530fbed9ef00cf15e78e0b1a20145e7aa5 Mon Sep 17 00:00:00 2001 From: "marina.kolpakova" Date: Thu, 30 Aug 2012 19:48:12 +0400 Subject: [PATCH 04/91] minor in train application --- apps/traincascade/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/traincascade/CMakeLists.txt b/apps/traincascade/CMakeLists.txt index 350200fc4..b92beb69b 100644 --- a/apps/traincascade/CMakeLists.txt +++ b/apps/traincascade/CMakeLists.txt @@ -2,7 +2,7 @@ if(IOS OR ANDROID) return() endif() -SET(OPENCV_TRAINCASCADE_DEPS opencv_core opencv_ml opencv_imgproc opencv_objdetect opencv_highgui opencv_calib3d opencv_video opencv_features2d opencv_flann opencv_legacy) +set(OPENCV_TRAINCASCADE_DEPS opencv_core opencv_ml opencv_imgproc opencv_objdetect opencv_highgui opencv_calib3d opencv_video opencv_features2d opencv_flann opencv_legacy) ocv_check_dependencies(${OPENCV_TRAINCASCADE_DEPS}) if(NOT OCV_DEPENDENCIES_FOUND) From fb113e5ce42079e4bc3bd741ec5c402acc7f1e92 Mon Sep 17 00:00:00 2001 From: "marina.kolpakova" Date: Thu, 30 Aug 2012 19:48:59 +0400 Subject: [PATCH 05/91] scale pyramid calculations --- .../include/opencv2/objdetect/objdetect.hpp | 3 +- modules/objdetect/src/softcascade.cpp | 137 ++++++++++++++++-- 2 files changed, 130 insertions(+), 10 deletions(-) diff --git a/modules/objdetect/include/opencv2/objdetect/objdetect.hpp b/modules/objdetect/include/opencv2/objdetect/objdetect.hpp index 690d63bbc..c528c8c40 100644 --- a/modules/objdetect/include/opencv2/objdetect/objdetect.hpp +++ b/modules/objdetect/include/opencv2/objdetect/objdetect.hpp @@ -506,6 +506,7 @@ protected: // int stripSize, int yStep, double factor, vector& candidates, // vector& rejectLevels, vector& levelWeights, bool outputRejectLevels=false); enum { BOOST = 0 }; + enum { FRAME_WIDTH = 640, FRAME_HEIGHT = 480, TOTAL_SCALES = 55, CLASSIFIERS = 5}; private: struct Feature @@ -514,7 +515,7 @@ private: int channel; }; - stuct Stamp + struct Stamp { }; diff --git a/modules/objdetect/src/softcascade.cpp b/modules/objdetect/src/softcascade.cpp index 1d2604c1b..61a1197a7 100644 --- a/modules/objdetect/src/softcascade.cpp +++ b/modules/objdetect/src/softcascade.cpp @@ -39,8 +39,15 @@ // the use of this software, even if advised of the possibility of such damage. //M*/ -struct Filds +#include +#include + +#include + + +struct cv::SoftCascade::Filds { + std::vector octaves; // cv::Mat luv; // std::vector bins; // cv::Mat magnitude; @@ -48,27 +55,139 @@ struct Filds // int windowStep; }; +namespace { -SoftCascade::SoftCascade() : filds(0) {} +struct Cascade { + int logOctave; + float octave; + cv::Size objSize; +}; -SoftCascade::SoftCascade( const string& filename ) +struct Level { + int index; + float factor; + float logFactor; + int width; + int height; + float octave; + cv::Size objSize; + + Level(int i,float f, float lf, int w, int h) : index(i), factor(f), logFactor(lf), width(w), height(h), octave(0.f) {} + + void assign(float o, int detW, int detH) + { + octave = o; + objSize = cv::Size(cv::saturate_cast(detW * o), cv::saturate_cast(detH * o)); + } + + float relScale() {return (factor / octave); } +}; + // compute levels of full pyramid + void pyrLevels(int frameW, int frameH, int detW, int detH, int scales, float minScale, float maxScale, std::vector levels) + { + CV_Assert(scales > 1); + levels.clear(); + float logFactor = (log(maxScale) - log(minScale)) / (scales -1); + + float scale = minScale; + for (int sc = 0; sc < scales; ++sc) + { + Level level(sc, scale, log(scale) + logFactor, std::max(0.0f, frameW - (detW * scale)), std::max(0.0f, frameH - (detH * scale))); + if (!level.width || !level.height) + break; + else + levels.push_back(level); + + if (fabs(scale - maxScale) < FLT_EPSILON) break; + scale = std::min(maxScale, expf(log(scale) + logFactor)); + } + + } + + // according to R. Benenson, M. Mathias, R. Timofte and L. Van Gool paper + struct CascadeIntrinsics { + static const float lambda = 1.099f/ 0.301029996f, a = 0.89f; + static const float intrinsics[10][4]; + + static float getFor(int chennel, int scaling, int ab) + { + CV_Assert(chennel < 10 && scaling < 2 && ab < 2); + return intrinsics[chennel][(scaling << 1) + ab]; + } + + }; + + const float CascadeIntrinsics::intrinsics[10][4] = + { //da, db, ua, ub + // hog-like orientation bins + {a, lambda, 1, 2}, + {a, lambda, 1, 2}, + {a, lambda, 1, 2}, + {a, lambda, 1, 2}, + {a, lambda, 1, 2}, + {a, lambda, 1, 2}, + // gradient magnitude + {a, lambda / log(2), 1, 2}, + // luv -color chennels + {1, 2, 1, 2}, + {1, 2, 1, 2}, + {1, 2, 1, 2} + }; +} + + + + +cv::SoftCascade::SoftCascade() : filds(0) {} + +cv::SoftCascade::SoftCascade( const string& filename ) { - filds = new filds; + filds = new Filds; load(filename); } -virtual SoftCascade::~SoftCascade() +cv::SoftCascade::~SoftCascade() { delete filds; } -bool SoftCascade::load( const string& filename ) +bool cv::SoftCascade::load( const string& filename ) { + // temp fixture + Filds& flds = *filds; + flds.octaves.push_back(0.5f); + flds.octaves.push_back(1.0f); + flds.octaves.push_back(2.0f); + flds.octaves.push_back(4.0f); + flds.octaves.push_back(8.0f); + + // scales calculations + int origObjectW = 64; + int origObjectH = 128; + float maxScale = 5.f, minScale = 0.4f; + std::vector levels; + + pyrLevels(FRAME_WIDTH, FRAME_HEIGHT, origObjectW, origObjectH, TOTAL_SCALES, minScale, maxScale,levels); + + for (std::vector::iterator level = levels.begin(); level < levels.end(); ++level) + { + float minAbsLog = FLT_MAX; + for (std::vector::iterator oct = flds.octaves.begin(); oct < flds.octaves.end(); ++oct) + { + float logOctave = log(*oct); + float logAbsScale = fabs((*level).logFactor - logOctave); + + if(logAbsScale < minAbsLog) + (*level).assign(*oct, origObjectW, origObjectH); + + } + } + return true; } -virtual void SoftCascade::detectMultiScale(const Mat& image, const std::vector& rois, std::vector& objects, - const double factor = 1.05, const int step = 4, const int rejectfactor = 1) +void cv::SoftCascade::detectMultiScale(const Mat& image, const std::vector& rois, std::vector& objects, + const double factor, const int step, const int rejectfactor) {} -virtual void SoftCascade::detectForOctave(const int octave) +void cv::SoftCascade::detectForOctave(const int octave) {} \ No newline at end of file From 7290d8576d11330f38f38b44bbd559db923dae39 Mon Sep 17 00:00:00 2001 From: "marina.kolpakova" Date: Thu, 30 Aug 2012 20:24:45 +0400 Subject: [PATCH 06/91] add ICF feature --- modules/objdetect/src/softcascade.cpp | 41 ++++++++++++++++++++------- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/modules/objdetect/src/softcascade.cpp b/modules/objdetect/src/softcascade.cpp index 61a1197a7..b79ec2bf3 100644 --- a/modules/objdetect/src/softcascade.cpp +++ b/modules/objdetect/src/softcascade.cpp @@ -106,13 +106,18 @@ struct Level { // according to R. Benenson, M. Mathias, R. Timofte and L. Van Gool paper struct CascadeIntrinsics { - static const float lambda = 1.099f/ 0.301029996f, a = 0.89f; + static const float lambda = 1.099f, a = 0.89f; static const float intrinsics[10][4]; - static float getFor(int chennel, int scaling, int ab) + static float getFor(int chennel, float scaling) { - CV_Assert(chennel < 10 && scaling < 2 && ab < 2); - return intrinsics[chennel][(scaling << 1) + ab]; + CV_Assert(chennel < 10); + + if ((scaling - 1.f) < FLT_EPSILON) + return 1.f; + + int ud = (int)(scaling < 1.f); + return intrinsics[chennel][(ud << 1)] * pow(scaling, intrinsics[chennel][(ud << 1) + 1]); } }; @@ -120,12 +125,12 @@ struct Level { const float CascadeIntrinsics::intrinsics[10][4] = { //da, db, ua, ub // hog-like orientation bins - {a, lambda, 1, 2}, - {a, lambda, 1, 2}, - {a, lambda, 1, 2}, - {a, lambda, 1, 2}, - {a, lambda, 1, 2}, - {a, lambda, 1, 2}, + {a, lambda / log(2), 1, 2}, + {a, lambda / log(2), 1, 2}, + {a, lambda / log(2), 1, 2}, + {a, lambda / log(2), 1, 2}, + {a, lambda / log(2), 1, 2}, + {a, lambda / log(2), 1, 2}, // gradient magnitude {a, lambda / log(2), 1, 2}, // luv -color chennels @@ -133,6 +138,22 @@ struct Level { {1, 2, 1, 2}, {1, 2, 1, 2} }; + + struct Feature + { + cv::Rect rect; + int channel; + float threshold; + + Feature(int x, int y, int w, int h, int c, float t) : rect(cv::Rect(x, y, w, h)), channel(c), threshold(t) {} + Feature(cv::Rect r, int c, float t) : rect(r), channel(c), threshold(t) {} + + Feature rescale(float relScale) + { + cv::Rect r(cvRound(rect.x * relScale), cvRound(rect.y * relScale), cvRound(rect.width * relScale), cvRound(rect.height * relScale)); + return Feature( r, channel, threshold * CascadeIntrinsics::getFor(channel, relScale)); + } + }; } From fe2c38be8007c675dd4fe5d81e2236bd71d7ae04 Mon Sep 17 00:00:00 2001 From: "marina.kolpakova" Date: Tue, 4 Sep 2012 13:52:07 +0400 Subject: [PATCH 07/91] add method to fill soft cascade --- .../include/opencv2/objdetect/objdetect.hpp | 14 +++- modules/objdetect/src/softcascade.cpp | 73 ++++++++++++++++--- 2 files changed, 75 insertions(+), 12 deletions(-) diff --git a/modules/objdetect/include/opencv2/objdetect/objdetect.hpp b/modules/objdetect/include/opencv2/objdetect/objdetect.hpp index c528c8c40..04accc3bc 100644 --- a/modules/objdetect/include/opencv2/objdetect/objdetect.hpp +++ b/modules/objdetect/include/opencv2/objdetect/objdetect.hpp @@ -494,9 +494,9 @@ class CV_EXPORTS SoftCascade { public: SoftCascade(); - SoftCascade( const string& filename ); + SoftCascade( const string& filename, const float minScale = 0.4f, const float maxScale = 5.f); virtual ~SoftCascade(); - bool load( const string& filename ); + bool load( const string& filename, const float minScale = 0.4f, const float maxScale = 5.f); virtual void detectMultiScale(const Mat& image, const std::vector& rois, std::vector& objects, double factor = 1.05, int step = 4, int rejectfactor = 1); @@ -506,7 +506,15 @@ protected: // int stripSize, int yStep, double factor, vector& candidates, // vector& rejectLevels, vector& levelWeights, bool outputRejectLevels=false); enum { BOOST = 0 }; - enum { FRAME_WIDTH = 640, FRAME_HEIGHT = 480, TOTAL_SCALES = 55, CLASSIFIERS = 5}; + enum + { + FRAME_WIDTH = 640, + FRAME_HEIGHT = 480, + TOTAL_SCALES = 55, + CLASSIFIERS = 5, + ORIG_OBJECT_WIDTH = 64, + ORIG_OBJECT_HEIGHT = 128 + }; private: struct Feature diff --git a/modules/objdetect/src/softcascade.cpp b/modules/objdetect/src/softcascade.cpp index b79ec2bf3..8463180ca 100644 --- a/modules/objdetect/src/softcascade.cpp +++ b/modules/objdetect/src/softcascade.cpp @@ -41,9 +41,10 @@ #include #include +#include #include - +#include struct cv::SoftCascade::Filds { @@ -53,6 +54,50 @@ struct cv::SoftCascade::Filds // cv::Mat magnitude; // double scaleFactor; // int windowStep; + float minScale; + float maxScale; + int noctaves; + + bool fill(const FileNode &root, const float mins, const float maxs) + { + minScale = mins; + maxScale = maxs; + + const char *SC_STAGE_TYPE = "stageType"; + const char *SC_FEATURE_TYPE = "featureType"; + const char *SC_BOOST = "BOOST"; + const char *SC_ICF = "ICF"; + const char *SC_NUM_OCTAVES = "octavesNum"; + const char* SC_CASCADES = "cascades"; + const char *SC_HEIGHT = "height"; + const char *SC_WIDTH = "width"; + const char *SC_MAX_DEPTH = "maxDepth"; + const char *SC_STAGES = "stages"; + const char *SC_STAGE_THRESHOLD = "stageThreshold"; + + // only boost supported + std::string stageTypeStr = (string)root[SC_STAGE_TYPE]; + CV_Assert(stageTypeStr == SC_BOOST); + + // only HOG-like integral channel features cupported + string featureTypeStr = (string)root[SC_FEATURE_TYPE]; + CV_Assert(featureTypeStr == SC_ICF); + + noctaves = (int)root[SC_NUM_OCTAVES]; + CV_Assert(noctaves > 0); + + // const char *SC_WEAK_CLASSIFIERS = "weakClassifiers"; + // const char *SC_INTERNAL_NODES = "internalNodes"; + // const char *SC_LEAF_VALUES = "leafValues"; + // const char *SC_FEATURES = "features"; + // const char *SC_RECT = "rect"; + + // const char *SC_STAGE_PARAMS = "stageParams"; + // const char *SC_FEATURE_PARAMS = "featureParams"; + // const char *SC_MAX_CAT_COUNT = "maxCatCount"; + + return true; + } }; namespace { @@ -161,18 +206,28 @@ struct Level { cv::SoftCascade::SoftCascade() : filds(0) {} -cv::SoftCascade::SoftCascade( const string& filename ) +cv::SoftCascade::SoftCascade( const string& filename, const float minScale, const float maxScale) { filds = new Filds; - load(filename); + load(filename, minScale, maxScale); } cv::SoftCascade::~SoftCascade() { delete filds; } -bool cv::SoftCascade::load( const string& filename ) +bool cv::SoftCascade::load( const string& filename, const float minScale, const float maxScale) { + delete filds; + filds = 0; + + cv::FileStorage fs(filename, FileStorage::READ); + if (!fs.isOpened()) return false; + + filds = new Filds; + if (!(*filds).fill(fs.getFirstTopLevelNode(), minScale, maxScale)) return false; + + //////////////// // temp fixture Filds& flds = *filds; flds.octaves.push_back(0.5f); @@ -182,12 +237,9 @@ bool cv::SoftCascade::load( const string& filename ) flds.octaves.push_back(8.0f); // scales calculations - int origObjectW = 64; - int origObjectH = 128; - float maxScale = 5.f, minScale = 0.4f; std::vector levels; - pyrLevels(FRAME_WIDTH, FRAME_HEIGHT, origObjectW, origObjectH, TOTAL_SCALES, minScale, maxScale,levels); + pyrLevels(FRAME_WIDTH, FRAME_HEIGHT, ORIG_OBJECT_WIDTH, ORIG_OBJECT_HEIGHT, TOTAL_SCALES, minScale, maxScale, levels); for (std::vector::iterator level = levels.begin(); level < levels.end(); ++level) { @@ -198,11 +250,14 @@ bool cv::SoftCascade::load( const string& filename ) float logAbsScale = fabs((*level).logFactor - logOctave); if(logAbsScale < minAbsLog) - (*level).assign(*oct, origObjectW, origObjectH); + (*level).assign(*oct, ORIG_OBJECT_WIDTH, ORIG_OBJECT_HEIGHT); } } + // load cascade from xml + // read(const FileNode &root) + return true; } From a54d456ad0aa06e3f4f01f417dfad0451118b8fb Mon Sep 17 00:00:00 2001 From: "marina.kolpakova" Date: Tue, 4 Sep 2012 18:03:10 +0400 Subject: [PATCH 08/91] parse soft cascade from xml --- .../include/opencv2/objdetect/objdetect.hpp | 11 - modules/objdetect/src/softcascade.cpp | 343 +++++++++++------- modules/objdetect/test/test_softcascade.cpp | 5 +- 3 files changed, 222 insertions(+), 137 deletions(-) diff --git a/modules/objdetect/include/opencv2/objdetect/objdetect.hpp b/modules/objdetect/include/opencv2/objdetect/objdetect.hpp index 04accc3bc..9bdc91462 100644 --- a/modules/objdetect/include/opencv2/objdetect/objdetect.hpp +++ b/modules/objdetect/include/opencv2/objdetect/objdetect.hpp @@ -517,17 +517,6 @@ protected: }; private: - struct Feature - { - cv::Rect rect; - int channel; - }; - - struct Stamp - { - - }; - struct Filds; Filds* filds; }; diff --git a/modules/objdetect/src/softcascade.cpp b/modules/objdetect/src/softcascade.cpp index 8463180ca..dae352c56 100644 --- a/modules/objdetect/src/softcascade.cpp +++ b/modules/objdetect/src/softcascade.cpp @@ -45,35 +45,94 @@ #include #include +#include + +namespace { + + static const char* SC_OCT_SCALE = "scale"; + static const char* SC_OCT_STAGES = "stageNum"; + + struct Octave + { + float scale; + int stages; + + Octave(){} + Octave(const cv::FileNode& fn) : scale((float)fn[SC_OCT_SCALE]), stages((int)fn[SC_OCT_STAGES]) + {printf("octave: %f %d\n", scale, stages);} + }; + + static const char *SC_STAGE_THRESHOLD = "stageThreshold"; + static const char *SC_STAGE_WEIGHT = "weight"; + + struct Stage + { + float threshold; + float weight; + + Stage(){} + Stage(const cv::FileNode& fn) : threshold((float)fn[SC_STAGE_THRESHOLD]), weight((float)fn[SC_STAGE_WEIGHT]) + {printf(" stage: %f %f\n",threshold, weight);} + }; + + static const char *SC_F_THRESHOLD = "threshold"; + static const char *SC_F_DIRECTION = "direction"; + static const char *SC_F_CHANNEL = "chennel"; + static const char *SC_F_RECT = "rect"; + + struct Feature + { + float threshold; + int direction; + int chennel; + cv::Rect rect; + + Feature() {} + Feature(const cv::FileNode& fn) + : threshold((float)fn[SC_F_THRESHOLD]), direction((int)fn[SC_F_DIRECTION]), + chennel((int)fn[SC_F_CHANNEL]) + { + cv::FileNode rn = fn[SC_F_RECT]; + cv::FileNodeIterator r_it = rn.begin(); + rect = cv::Rect(*(r_it++), *(r_it++), *(r_it++), *(r_it++)); + printf(" feature: %f %d %d [%d %d %d %d]\n",threshold, direction, chennel, rect.x, rect.y, rect.width, rect.height);} + }; +} struct cv::SoftCascade::Filds { - std::vector octaves; - // cv::Mat luv; - // std::vector bins; - // cv::Mat magnitude; - // double scaleFactor; - // int windowStep; float minScale; float maxScale; + + int origObjWidth; + int origObjHeight; + int noctaves; + std::vector octaves; + std::vector stages; + std::vector features; + bool fill(const FileNode &root, const float mins, const float maxs) { minScale = mins; maxScale = maxs; + // cascade properties const char *SC_STAGE_TYPE = "stageType"; - const char *SC_FEATURE_TYPE = "featureType"; const char *SC_BOOST = "BOOST"; + const char *SC_FEATURE_TYPE = "featureType"; const char *SC_ICF = "ICF"; + const char *SC_TREE_TYPE = "stageTreeType"; + const char *SC_STAGE_TH2 = "TH2"; const char *SC_NUM_OCTAVES = "octavesNum"; - const char* SC_CASCADES = "cascades"; - const char *SC_HEIGHT = "height"; - const char *SC_WIDTH = "width"; - const char *SC_MAX_DEPTH = "maxDepth"; + const char *SC_ORIG_W = "origObjWidth"; + const char *SC_ORIG_H = "origObjHeight"; + + const char* SC_OCTAVES = "octaves"; const char *SC_STAGES = "stages"; - const char *SC_STAGE_THRESHOLD = "stageThreshold"; + const char *SC_FEATURES = "features"; + // only boost supported std::string stageTypeStr = (string)root[SC_STAGE_TYPE]; @@ -83,123 +142,157 @@ struct cv::SoftCascade::Filds string featureTypeStr = (string)root[SC_FEATURE_TYPE]; CV_Assert(featureTypeStr == SC_ICF); + // only trees of height 2 + string stageTreeTypeStr = (string)root[SC_TREE_TYPE]; + CV_Assert(stageTreeTypeStr == SC_STAGE_TH2); + + // not empty noctaves = (int)root[SC_NUM_OCTAVES]; CV_Assert(noctaves > 0); - // const char *SC_WEAK_CLASSIFIERS = "weakClassifiers"; - // const char *SC_INTERNAL_NODES = "internalNodes"; - // const char *SC_LEAF_VALUES = "leafValues"; - // const char *SC_FEATURES = "features"; - // const char *SC_RECT = "rect"; + origObjWidth = (int)root[SC_ORIG_W]; + CV_Assert(origObjWidth == SoftCascade::ORIG_OBJECT_WIDTH); - // const char *SC_STAGE_PARAMS = "stageParams"; - // const char *SC_FEATURE_PARAMS = "featureParams"; - // const char *SC_MAX_CAT_COUNT = "maxCatCount"; + origObjHeight = (int)root[SC_ORIG_H]; + CV_Assert(origObjHeight == SoftCascade::ORIG_OBJECT_HEIGHT); + // for each octave (~ one cascade in classic OpenCV xml) + FileNode fn = root[SC_OCTAVES]; + if (fn.empty()) return false; + + octaves.reserve(noctaves); + FileNodeIterator it = fn.begin(), it_end = fn.end(); + for (; it != it_end; ++it) + { + FileNode fns = *it; + Octave octave = Octave(fns); + CV_Assert(octave.stages > 0); + octaves.push_back(octave); + stages.reserve(stages.size() + octave.stages); + + fns = fns[SC_STAGES]; + if (fn.empty()) return false; + + // for each stage (~ decision tree with H = 2) + FileNodeIterator st = fns.begin(), st_end = fns.end(); + for (; st != st_end; ++st ) + { + fns = *st; + stages.push_back(Stage(fns)); + + fns = fns[SC_FEATURES]; + // for each feature for tree. features stored in order {root, left, right} + FileNodeIterator ftr = fns.begin(), ft_end = fns.end(); + for (; ftr != ft_end; ++ftr) + { + features.push_back(Feature(*ftr)); + } + } + } return true; } }; -namespace { +// namespace { -struct Cascade { - int logOctave; - float octave; - cv::Size objSize; -}; +// struct Cascade { +// int logOctave; +// float octave; +// cv::Size objSize; +// }; -struct Level { - int index; - float factor; - float logFactor; - int width; - int height; - float octave; - cv::Size objSize; +// struct Level { +// int index; +// float factor; +// float logFactor; +// int width; +// int height; +// float octave; +// cv::Size objSize; - Level(int i,float f, float lf, int w, int h) : index(i), factor(f), logFactor(lf), width(w), height(h), octave(0.f) {} +// Level(int i,float f, float lf, int w, int h) : index(i), factor(f), logFactor(lf), width(w), height(h), octave(0.f) {} - void assign(float o, int detW, int detH) - { - octave = o; - objSize = cv::Size(cv::saturate_cast(detW * o), cv::saturate_cast(detH * o)); - } +// void assign(float o, int detW, int detH) +// { +// octave = o; +// objSize = cv::Size(cv::saturate_cast(detW * o), cv::saturate_cast(detH * o)); +// } - float relScale() {return (factor / octave); } -}; - // compute levels of full pyramid - void pyrLevels(int frameW, int frameH, int detW, int detH, int scales, float minScale, float maxScale, std::vector levels) - { - CV_Assert(scales > 1); - levels.clear(); - float logFactor = (log(maxScale) - log(minScale)) / (scales -1); +// float relScale() {return (factor / octave); } +// }; +// // compute levels of full pyramid +// void pyrLevels(int frameW, int frameH, int detW, int detH, int scales, float minScale, float maxScale, std::vector levels) +// { +// CV_Assert(scales > 1); +// levels.clear(); +// float logFactor = (log(maxScale) - log(minScale)) / (scales -1); - float scale = minScale; - for (int sc = 0; sc < scales; ++sc) - { - Level level(sc, scale, log(scale) + logFactor, std::max(0.0f, frameW - (detW * scale)), std::max(0.0f, frameH - (detH * scale))); - if (!level.width || !level.height) - break; - else - levels.push_back(level); +// float scale = minScale; +// for (int sc = 0; sc < scales; ++sc) +// { +// Level level(sc, scale, log(scale) + logFactor, std::max(0.0f, frameW - (detW * scale)), std::max(0.0f, frameH - (detH * scale))); +// if (!level.width || !level.height) +// break; +// else +// levels.push_back(level); - if (fabs(scale - maxScale) < FLT_EPSILON) break; - scale = std::min(maxScale, expf(log(scale) + logFactor)); - } +// if (fabs(scale - maxScale) < FLT_EPSILON) break; +// scale = std::min(maxScale, expf(log(scale) + logFactor)); +// } - } +// } - // according to R. Benenson, M. Mathias, R. Timofte and L. Van Gool paper - struct CascadeIntrinsics { - static const float lambda = 1.099f, a = 0.89f; - static const float intrinsics[10][4]; +// // according to R. Benenson, M. Mathias, R. Timofte and L. Van Gool paper +// struct CascadeIntrinsics { +// static const float lambda = 1.099f, a = 0.89f; +// static const float intrinsics[10][4]; - static float getFor(int chennel, float scaling) - { - CV_Assert(chennel < 10); +// static float getFor(int chennel, float scaling) +// { +// CV_Assert(chennel < 10); - if ((scaling - 1.f) < FLT_EPSILON) - return 1.f; +// if ((scaling - 1.f) < FLT_EPSILON) +// return 1.f; - int ud = (int)(scaling < 1.f); - return intrinsics[chennel][(ud << 1)] * pow(scaling, intrinsics[chennel][(ud << 1) + 1]); - } +// int ud = (int)(scaling < 1.f); +// return intrinsics[chennel][(ud << 1)] * pow(scaling, intrinsics[chennel][(ud << 1) + 1]); +// } - }; +// }; - const float CascadeIntrinsics::intrinsics[10][4] = - { //da, db, ua, ub - // hog-like orientation bins - {a, lambda / log(2), 1, 2}, - {a, lambda / log(2), 1, 2}, - {a, lambda / log(2), 1, 2}, - {a, lambda / log(2), 1, 2}, - {a, lambda / log(2), 1, 2}, - {a, lambda / log(2), 1, 2}, - // gradient magnitude - {a, lambda / log(2), 1, 2}, - // luv -color chennels - {1, 2, 1, 2}, - {1, 2, 1, 2}, - {1, 2, 1, 2} - }; +// const float CascadeIntrinsics::intrinsics[10][4] = +// { //da, db, ua, ub +// // hog-like orientation bins +// {a, lambda / log(2), 1, 2}, +// {a, lambda / log(2), 1, 2}, +// {a, lambda / log(2), 1, 2}, +// {a, lambda / log(2), 1, 2}, +// {a, lambda / log(2), 1, 2}, +// {a, lambda / log(2), 1, 2}, +// // gradient magnitude +// {a, lambda / log(2), 1, 2}, +// // luv -color chennels +// {1, 2, 1, 2}, +// {1, 2, 1, 2}, +// {1, 2, 1, 2} +// }; - struct Feature - { - cv::Rect rect; - int channel; - float threshold; +// struct Feature +// { +// cv::Rect rect; +// int channel; +// float threshold; - Feature(int x, int y, int w, int h, int c, float t) : rect(cv::Rect(x, y, w, h)), channel(c), threshold(t) {} - Feature(cv::Rect r, int c, float t) : rect(r), channel(c), threshold(t) {} +// Feature(int x, int y, int w, int h, int c, float t) : rect(cv::Rect(x, y, w, h)), channel(c), threshold(t) {} +// Feature(cv::Rect r, int c, float t) : rect(r), channel(c), threshold(t) {} - Feature rescale(float relScale) - { - cv::Rect r(cvRound(rect.x * relScale), cvRound(rect.y * relScale), cvRound(rect.width * relScale), cvRound(rect.height * relScale)); - return Feature( r, channel, threshold * CascadeIntrinsics::getFor(channel, relScale)); - } - }; -} +// Feature rescale(float relScale) +// { +// cv::Rect r(cvRound(rect.x * relScale), cvRound(rect.y * relScale), cvRound(rect.width * relScale), cvRound(rect.height * relScale)); +// return Feature( r, channel, threshold * CascadeIntrinsics::getFor(channel, relScale)); +// } +// }; +// } @@ -227,33 +320,33 @@ bool cv::SoftCascade::load( const string& filename, const float minScale, const filds = new Filds; if (!(*filds).fill(fs.getFirstTopLevelNode(), minScale, maxScale)) return false; - //////////////// - // temp fixture - Filds& flds = *filds; - flds.octaves.push_back(0.5f); - flds.octaves.push_back(1.0f); - flds.octaves.push_back(2.0f); - flds.octaves.push_back(4.0f); - flds.octaves.push_back(8.0f); + // //////////////// + // // temp fixture + // Filds& flds = *filds; + // flds.octaves.push_back(0.5f); + // flds.octaves.push_back(1.0f); + // flds.octaves.push_back(2.0f); + // flds.octaves.push_back(4.0f); + // flds.octaves.push_back(8.0f); - // scales calculations - std::vector levels; + // // scales calculations + // std::vector levels; - pyrLevels(FRAME_WIDTH, FRAME_HEIGHT, ORIG_OBJECT_WIDTH, ORIG_OBJECT_HEIGHT, TOTAL_SCALES, minScale, maxScale, levels); + // pyrLevels(FRAME_WIDTH, FRAME_HEIGHT, ORIG_OBJECT_WIDTH, ORIG_OBJECT_HEIGHT, TOTAL_SCALES, minScale, maxScale, levels); - for (std::vector::iterator level = levels.begin(); level < levels.end(); ++level) - { - float minAbsLog = FLT_MAX; - for (std::vector::iterator oct = flds.octaves.begin(); oct < flds.octaves.end(); ++oct) - { - float logOctave = log(*oct); - float logAbsScale = fabs((*level).logFactor - logOctave); + // for (std::vector::iterator level = levels.begin(); level < levels.end(); ++level) + // { + // float minAbsLog = FLT_MAX; + // for (std::vector::iterator oct = flds.octaves.begin(); oct < flds.octaves.end(); ++oct) + // { + // float logOctave = log(*oct); + // float logAbsScale = fabs((*level).logFactor - logOctave); - if(logAbsScale < minAbsLog) - (*level).assign(*oct, ORIG_OBJECT_WIDTH, ORIG_OBJECT_HEIGHT); + // if(logAbsScale < minAbsLog) + // (*level).assign(*oct, ORIG_OBJECT_WIDTH, ORIG_OBJECT_HEIGHT); - } - } + // } + // } // load cascade from xml // read(const FileNode &root) diff --git a/modules/objdetect/test/test_softcascade.cpp b/modules/objdetect/test/test_softcascade.cpp index fc7baaad2..a7b8548de 100644 --- a/modules/objdetect/test/test_softcascade.cpp +++ b/modules/objdetect/test/test_softcascade.cpp @@ -41,7 +41,10 @@ #include "test_precomp.hpp" -TEST(SoftCascade, HOG) +TEST(SoftCascade, readCascade) { + std::string xml = "/home/kellan/icf-template.xml"; + cv::SoftCascade cascade; + ASSERT_TRUE(cascade.load(xml)); } \ No newline at end of file From f01c5d9033944c7c766eed60fc1468a5ee78e097 Mon Sep 17 00:00:00 2001 From: "marina.kolpakova" Date: Tue, 4 Sep 2012 19:08:52 +0400 Subject: [PATCH 09/91] compute scales pyramid --- modules/objdetect/src/softcascade.cpp | 250 ++++++++++++-------------- 1 file changed, 110 insertions(+), 140 deletions(-) diff --git a/modules/objdetect/src/softcascade.cpp b/modules/objdetect/src/softcascade.cpp index dae352c56..065fb0d8b 100644 --- a/modules/objdetect/src/softcascade.cpp +++ b/modules/objdetect/src/softcascade.cpp @@ -75,27 +75,93 @@ namespace { {printf(" stage: %f %f\n",threshold, weight);} }; + // according to R. Benenson, M. Mathias, R. Timofte and L. Van Gool paper + struct CascadeIntrinsics + { + static const float lambda = 1.099f, a = 0.89f; + static const float intrinsics[10][4]; + + static float getFor(int channel, float scaling) + { + CV_Assert(channel < 10); + + if ((scaling - 1.f) < FLT_EPSILON) + return 1.f; + + int ud = (int)(scaling < 1.f); + return intrinsics[channel][(ud << 1)] * pow(scaling, intrinsics[channel][(ud << 1) + 1]); + } + + }; + + const float CascadeIntrinsics::intrinsics[10][4] = + { //da, db, ua, ub + // hog-like orientation bins + {a, lambda / log(2), 1, 2}, + {a, lambda / log(2), 1, 2}, + {a, lambda / log(2), 1, 2}, + {a, lambda / log(2), 1, 2}, + {a, lambda / log(2), 1, 2}, + {a, lambda / log(2), 1, 2}, + // gradient magnitude + {a, lambda / log(2), 1, 2}, + // luv color channels + {1, 2, 1, 2}, + {1, 2, 1, 2}, + {1, 2, 1, 2} + }; + static const char *SC_F_THRESHOLD = "threshold"; static const char *SC_F_DIRECTION = "direction"; - static const char *SC_F_CHANNEL = "chennel"; + static const char *SC_F_CHANNEL = "channel"; static const char *SC_F_RECT = "rect"; struct Feature { float threshold; int direction; - int chennel; + int channel; cv::Rect rect; Feature() {} Feature(const cv::FileNode& fn) : threshold((float)fn[SC_F_THRESHOLD]), direction((int)fn[SC_F_DIRECTION]), - chennel((int)fn[SC_F_CHANNEL]) + channel((int)fn[SC_F_CHANNEL]) { cv::FileNode rn = fn[SC_F_RECT]; cv::FileNodeIterator r_it = rn.begin(); rect = cv::Rect(*(r_it++), *(r_it++), *(r_it++), *(r_it++)); - printf(" feature: %f %d %d [%d %d %d %d]\n",threshold, direction, chennel, rect.x, rect.y, rect.width, rect.height);} + printf(" feature: %f %d %d [%d %d %d %d]\n",threshold, direction, channel, rect.x, rect.y, rect.width, rect.height);} + + Feature rescale(float relScale) + { + Feature res(*this); + res.rect = cv::Rect (cvRound(rect.x * relScale), cvRound(rect.y * relScale), + cvRound(rect.width * relScale), cvRound(rect.height * relScale)); + res.threshold = threshold * CascadeIntrinsics::getFor(channel, relScale); + return res; + } + }; + + struct Level + { + int index; + float factor; + float logFactor; + int width; + int height; + float octave; + cv::Size objSize; + + Level(int i,float f, float lf, int w, int h): index(i), factor(f), logFactor(lf), width(w), height(h), octave(0.f) {} + + void assign(float o, int detW, int detH) + { + octave = o; + objSize = cv::Size(cv::saturate_cast(detW * o), cv::saturate_cast(detH * o)); + } + + float relScale() {return (factor / octave); } }; } @@ -112,6 +178,43 @@ struct cv::SoftCascade::Filds std::vector octaves; std::vector stages; std::vector features; + std::vector levels; + + // compute levels of full pyramid + void calcLevels(int frameW, int frameH, int scales) + { + CV_Assert(scales > 1); + levels.clear(); + float logFactor = (log(maxScale) - log(minScale)) / (scales -1); + + float scale = minScale; + for (int sc = 0; sc < scales; ++sc) + { + Level level(sc, scale, log(scale) + logFactor, + std::max(0.0f, frameW - (origObjWidth * scale)), std::max(0.0f, frameH - (origObjHeight * scale))); + if (!level.width || !level.height) + break; + else + levels.push_back(level); + + if (fabs(scale - maxScale) < FLT_EPSILON) break; + scale = std::min(maxScale, expf(log(scale) + logFactor)); + } + + for (std::vector::iterator level = levels.begin(); level < levels.end(); ++level) + { + float minAbsLog = FLT_MAX; + for (std::vector::iterator oct = octaves.begin(); oct < octaves.end(); ++oct) + { + const Octave& octave =*oct; + float logOctave = log(octave.scale); + float logAbsScale = fabs((*level).logFactor - logOctave); + + if(logAbsScale < minAbsLog) + (*level).assign(octave.scale, ORIG_OBJECT_WIDTH, ORIG_OBJECT_HEIGHT); + } + } + } bool fill(const FileNode &root, const float mins, const float maxs) { @@ -193,110 +296,6 @@ struct cv::SoftCascade::Filds } }; -// namespace { - -// struct Cascade { -// int logOctave; -// float octave; -// cv::Size objSize; -// }; - -// struct Level { -// int index; -// float factor; -// float logFactor; -// int width; -// int height; -// float octave; -// cv::Size objSize; - -// Level(int i,float f, float lf, int w, int h) : index(i), factor(f), logFactor(lf), width(w), height(h), octave(0.f) {} - -// void assign(float o, int detW, int detH) -// { -// octave = o; -// objSize = cv::Size(cv::saturate_cast(detW * o), cv::saturate_cast(detH * o)); -// } - -// float relScale() {return (factor / octave); } -// }; -// // compute levels of full pyramid -// void pyrLevels(int frameW, int frameH, int detW, int detH, int scales, float minScale, float maxScale, std::vector levels) -// { -// CV_Assert(scales > 1); -// levels.clear(); -// float logFactor = (log(maxScale) - log(minScale)) / (scales -1); - -// float scale = minScale; -// for (int sc = 0; sc < scales; ++sc) -// { -// Level level(sc, scale, log(scale) + logFactor, std::max(0.0f, frameW - (detW * scale)), std::max(0.0f, frameH - (detH * scale))); -// if (!level.width || !level.height) -// break; -// else -// levels.push_back(level); - -// if (fabs(scale - maxScale) < FLT_EPSILON) break; -// scale = std::min(maxScale, expf(log(scale) + logFactor)); -// } - -// } - -// // according to R. Benenson, M. Mathias, R. Timofte and L. Van Gool paper -// struct CascadeIntrinsics { -// static const float lambda = 1.099f, a = 0.89f; -// static const float intrinsics[10][4]; - -// static float getFor(int chennel, float scaling) -// { -// CV_Assert(chennel < 10); - -// if ((scaling - 1.f) < FLT_EPSILON) -// return 1.f; - -// int ud = (int)(scaling < 1.f); -// return intrinsics[chennel][(ud << 1)] * pow(scaling, intrinsics[chennel][(ud << 1) + 1]); -// } - -// }; - -// const float CascadeIntrinsics::intrinsics[10][4] = -// { //da, db, ua, ub -// // hog-like orientation bins -// {a, lambda / log(2), 1, 2}, -// {a, lambda / log(2), 1, 2}, -// {a, lambda / log(2), 1, 2}, -// {a, lambda / log(2), 1, 2}, -// {a, lambda / log(2), 1, 2}, -// {a, lambda / log(2), 1, 2}, -// // gradient magnitude -// {a, lambda / log(2), 1, 2}, -// // luv -color chennels -// {1, 2, 1, 2}, -// {1, 2, 1, 2}, -// {1, 2, 1, 2} -// }; - -// struct Feature -// { -// cv::Rect rect; -// int channel; -// float threshold; - -// Feature(int x, int y, int w, int h, int c, float t) : rect(cv::Rect(x, y, w, h)), channel(c), threshold(t) {} -// Feature(cv::Rect r, int c, float t) : rect(r), channel(c), threshold(t) {} - -// Feature rescale(float relScale) -// { -// cv::Rect r(cvRound(rect.x * relScale), cvRound(rect.y * relScale), cvRound(rect.width * relScale), cvRound(rect.height * relScale)); -// return Feature( r, channel, threshold * CascadeIntrinsics::getFor(channel, relScale)); -// } -// }; -// } - - - - cv::SoftCascade::SoftCascade() : filds(0) {} cv::SoftCascade::SoftCascade( const string& filename, const float minScale, const float maxScale) @@ -318,38 +317,9 @@ bool cv::SoftCascade::load( const string& filename, const float minScale, const if (!fs.isOpened()) return false; filds = new Filds; - if (!(*filds).fill(fs.getFirstTopLevelNode(), minScale, maxScale)) return false; - - // //////////////// - // // temp fixture - // Filds& flds = *filds; - // flds.octaves.push_back(0.5f); - // flds.octaves.push_back(1.0f); - // flds.octaves.push_back(2.0f); - // flds.octaves.push_back(4.0f); - // flds.octaves.push_back(8.0f); - - // // scales calculations - // std::vector levels; - - // pyrLevels(FRAME_WIDTH, FRAME_HEIGHT, ORIG_OBJECT_WIDTH, ORIG_OBJECT_HEIGHT, TOTAL_SCALES, minScale, maxScale, levels); - - // for (std::vector::iterator level = levels.begin(); level < levels.end(); ++level) - // { - // float minAbsLog = FLT_MAX; - // for (std::vector::iterator oct = flds.octaves.begin(); oct < flds.octaves.end(); ++oct) - // { - // float logOctave = log(*oct); - // float logAbsScale = fabs((*level).logFactor - logOctave); - - // if(logAbsScale < minAbsLog) - // (*level).assign(*oct, ORIG_OBJECT_WIDTH, ORIG_OBJECT_HEIGHT); - - // } - // } - - // load cascade from xml - // read(const FileNode &root) + Filds& flds = *filds; + if (!flds.fill(fs.getFirstTopLevelNode(), minScale, maxScale)) return false; + // flds.calcLevels(FRAME_WIDTH, FRAME_HEIGHT, TOTAL_SCALES); return true; } From b0b85f36f61b4b5a79ff7cbe035d3829556f0401 Mon Sep 17 00:00:00 2001 From: "marina.kolpakova" Date: Wed, 5 Sep 2012 12:36:37 +0400 Subject: [PATCH 10/91] add test for soft cascade detect method --- .../include/opencv2/objdetect/objdetect.hpp | 10 ++++++++-- modules/objdetect/src/softcascade.cpp | 12 +++++++++--- modules/objdetect/test/test_softcascade.cpp | 19 +++++++++++++++++++ 3 files changed, 36 insertions(+), 5 deletions(-) diff --git a/modules/objdetect/include/opencv2/objdetect/objdetect.hpp b/modules/objdetect/include/opencv2/objdetect/objdetect.hpp index 9bdc91462..9fab7410a 100644 --- a/modules/objdetect/include/opencv2/objdetect/objdetect.hpp +++ b/modules/objdetect/include/opencv2/objdetect/objdetect.hpp @@ -493,12 +493,18 @@ protected: class CV_EXPORTS SoftCascade { public: + //! empty cascade will be created. SoftCascade(); + + //! cascade will be loaded from file "filename" SoftCascade( const string& filename, const float minScale = 0.4f, const float maxScale = 5.f); - virtual ~SoftCascade(); bool load( const string& filename, const float minScale = 0.4f, const float maxScale = 5.f); - virtual void detectMultiScale(const Mat& image, const std::vector& rois, std::vector& objects, double factor = 1.05, int step = 4, int rejectfactor = 1); + virtual ~SoftCascade(); + + //! return vector of bounding boxes. Each box contains detected object + virtual void detectMultiScale(const Mat& image, const std::vector& rois, std::vector& objects, + int step = 4, int rejectfactor = 1); protected: virtual void detectForOctave(int octave); diff --git a/modules/objdetect/src/softcascade.cpp b/modules/objdetect/src/softcascade.cpp index 065fb0d8b..62d58f286 100644 --- a/modules/objdetect/src/softcascade.cpp +++ b/modules/objdetect/src/softcascade.cpp @@ -319,14 +319,20 @@ bool cv::SoftCascade::load( const string& filename, const float minScale, const filds = new Filds; Filds& flds = *filds; if (!flds.fill(fs.getFirstTopLevelNode(), minScale, maxScale)) return false; - // flds.calcLevels(FRAME_WIDTH, FRAME_HEIGHT, TOTAL_SCALES); + flds.calcLevels(FRAME_WIDTH, FRAME_HEIGHT, TOTAL_SCALES); return true; } void cv::SoftCascade::detectMultiScale(const Mat& image, const std::vector& rois, std::vector& objects, - const double factor, const int step, const int rejectfactor) -{} + const int step, const int rejectfactor) +{ + // only color images are supperted + CV_Assert(image.type() == CV_8UC3); + + // only this window size allowed + CV_Assert(image.cols == 640 && image.rows == 480); +} void cv::SoftCascade::detectForOctave(const int octave) {} \ No newline at end of file diff --git a/modules/objdetect/test/test_softcascade.cpp b/modules/objdetect/test/test_softcascade.cpp index a7b8548de..d283d0608 100644 --- a/modules/objdetect/test/test_softcascade.cpp +++ b/modules/objdetect/test/test_softcascade.cpp @@ -47,4 +47,23 @@ TEST(SoftCascade, readCascade) cv::SoftCascade cascade; ASSERT_TRUE(cascade.load(xml)); +} + +TEST(SoftCascade, Detect) +{ + std::string xml = cvtest::TS::ptr()->get_data_path() + "cascadeandhog/softcascade.xml"; + std::cout << "PATH: "<< xml << std::endl; + cv::SoftCascade cascade; + ASSERT_TRUE(cascade.load(xml)); + + cv::Mat colored = cv::imread(cvtest::TS::ptr()->get_data_path() + "cascadeandhog/bahnhof/image_00000006_0.png"); + ASSERT_FALSE(colored.empty()); + + std::vector objectBoxes; + std::vector rois; + rois.push_back(cv::Rect(0, 0, 640, 480)); + ASSERT_NO_THROW( + { + cascade.detectMultiScale(colored, rois, objectBoxes); + }); } \ No newline at end of file From 695827050f3b94500e99e9128850ab4daab9d7f9 Mon Sep 17 00:00:00 2001 From: "marina.kolpakova" Date: Wed, 5 Sep 2012 17:44:28 +0400 Subject: [PATCH 11/91] Integral images for ICF --- .../include/opencv2/objdetect/objdetect.hpp | 1 + modules/objdetect/src/softcascade.cpp | 88 ++++++++++++++++++- 2 files changed, 86 insertions(+), 3 deletions(-) diff --git a/modules/objdetect/include/opencv2/objdetect/objdetect.hpp b/modules/objdetect/include/opencv2/objdetect/objdetect.hpp index 9fab7410a..0ef391d04 100644 --- a/modules/objdetect/include/opencv2/objdetect/objdetect.hpp +++ b/modules/objdetect/include/opencv2/objdetect/objdetect.hpp @@ -507,6 +507,7 @@ public: int step = 4, int rejectfactor = 1); protected: + virtual void detectInRoi(); virtual void detectForOctave(int octave); // virtual bool detectSingleScale( const Mat& image, int stripCount, Size processingRectSize, // int stripSize, int yStep, double factor, vector& candidates, diff --git a/modules/objdetect/src/softcascade.cpp b/modules/objdetect/src/softcascade.cpp index 62d58f286..cace66799 100644 --- a/modules/objdetect/src/softcascade.cpp +++ b/modules/objdetect/src/softcascade.cpp @@ -59,7 +59,7 @@ namespace { Octave(){} Octave(const cv::FileNode& fn) : scale((float)fn[SC_OCT_SCALE]), stages((int)fn[SC_OCT_STAGES]) - {printf("octave: %f %d\n", scale, stages);} + {/*printf("octave: %f %d\n", scale, stages);*/} }; static const char *SC_STAGE_THRESHOLD = "stageThreshold"; @@ -72,7 +72,7 @@ namespace { Stage(){} Stage(const cv::FileNode& fn) : threshold((float)fn[SC_STAGE_THRESHOLD]), weight((float)fn[SC_STAGE_WEIGHT]) - {printf(" stage: %f %f\n",threshold, weight);} + {/*printf(" stage: %f %f\n",threshold, weight);*/} }; // according to R. Benenson, M. Mathias, R. Timofte and L. Van Gool paper @@ -131,7 +131,8 @@ namespace { cv::FileNode rn = fn[SC_F_RECT]; cv::FileNodeIterator r_it = rn.begin(); rect = cv::Rect(*(r_it++), *(r_it++), *(r_it++), *(r_it++)); - printf(" feature: %f %d %d [%d %d %d %d]\n",threshold, direction, channel, rect.x, rect.y, rect.width, rect.height);} + // printf(" feature: %f %d %d [%d %d %d %d]\n",threshold, direction, channel, rect.x, rect.y, rect.width, rect.height); + } Feature rescale(float relScale) { @@ -324,14 +325,95 @@ bool cv::SoftCascade::load( const string& filename, const float minScale, const return true; } +namespace { + + void calcHistBins(const cv::Mat& grey, std::vector& histInts, const int bins) + { + CV_Assert( grey.type() == CV_8U); + const int rows = grey.rows + 1; + const int cols = grey.cols + 1; + cv::Size intSumSize(cols, rows); + + histInts.clear(); + std::vector hist; + for (int bin = 0; bin < bins; ++bin) + { + hist.push_back(cv::Mat(rows, cols, CV_32FC1)); + } + cv::Mat df_dx, df_dy, mag, angle; + cv::Sobel(grey, df_dx, CV_32F, 1, 0); + cv::Sobel(grey, df_dy, CV_32F, 0, 1); + + cv::cartToPolar(df_dx, df_dy, mag, angle, true); + + const float magnitudeScaling = 1.0 / sqrt(2); + mag *= magnitudeScaling; + angle /= 60; + + for (int h = 0; h < mag.rows; ++h) + { + float* magnitude = mag.ptr(h); + float* ang = angle.ptr(h); + + for (int w = 0; w < mag.cols; ++w) + { + hist[(int)ang[w]].ptr(h)[w] = magnitude[w]; + } + } + + for (int bin = 0; bin < bins; ++bin) + { + cv::Mat sum; + cv::integral(hist[bin], sum); + histInts.push_back(sum); + } + + cv::Mat magIntegral; + cv::integral(mag, magIntegral, mag.depth()); + } + + struct Integrals + { + /* data */ + }; +} + +void cv::SoftCascade::detectInRoi() +{} + + void cv::SoftCascade::detectMultiScale(const Mat& image, const std::vector& rois, std::vector& objects, const int step, const int rejectfactor) { + typedef std::vector::const_iterator RIter_t; // only color images are supperted CV_Assert(image.type() == CV_8UC3); // only this window size allowed CV_Assert(image.cols == 640 && image.rows == 480); + + objects.clear(); + + // create integrals + cv::Mat luv; + cv::cvtColor(image, luv, CV_BGR2Luv); + + cv::Mat luvIntegral; + cv::integral(luv, luvIntegral); + + cv::Mat grey; + cv::cvtColor(image, grey, CV_RGB2GRAY); + + std::vector hist; + const int bins = 6; + calcHistBins(grey, hist, bins); + + for (RIter_t it = rois.begin(); it != rois.end(); ++it) + { + const cv::Rect& roi = *it; + // detectInRoi(roi, objects, step); + } + } void cv::SoftCascade::detectForOctave(const int octave) From c04725b6812902c16e8027787365e66be5ac16ae Mon Sep 17 00:00:00 2001 From: "marina.kolpakova" Date: Wed, 5 Sep 2012 18:29:13 +0400 Subject: [PATCH 12/91] add apply cascade method --- modules/gpu/CMakeLists.txt | 8 ++-- .../include/opencv2/objdetect/objdetect.hpp | 1 - modules/objdetect/src/softcascade.cpp | 46 ++++++++++++++----- modules/objdetect/test/test_softcascade.cpp | 6 +-- 4 files changed, 42 insertions(+), 19 deletions(-) diff --git a/modules/gpu/CMakeLists.txt b/modules/gpu/CMakeLists.txt index 580e7dfb9..78aafcf92 100644 --- a/modules/gpu/CMakeLists.txt +++ b/modules/gpu/CMakeLists.txt @@ -15,10 +15,10 @@ file(GLOB lib_cuda_hdrs "src/cuda/*.hpp" "src/cuda/*.h") file(GLOB lib_srcs "src/*.cpp") file(GLOB lib_cuda "src/cuda/*.cu*") -source_group("Include" FILES ${lib_hdrs}) -source_group("Src\\Host" FILES ${lib_srcs} ${lib_int_hdrs}) -source_group("Src\\Cuda" FILES ${lib_cuda} ${lib_cuda_hdrs}) -source_group("Device" FILES ${lib_device_hdrs}) +source_group("Include" FILES ${lib_hdrs}) +source_group("Src\\Host" FILES ${lib_srcs} ${lib_int_hdrs}) +source_group("Src\\Cuda" FILES ${lib_cuda} ${lib_cuda_hdrs}) +source_group("Device" FILES ${lib_device_hdrs}) source_group("Device\\Detail" FILES ${lib_device_hdrs_detail}) if (HAVE_CUDA) diff --git a/modules/objdetect/include/opencv2/objdetect/objdetect.hpp b/modules/objdetect/include/opencv2/objdetect/objdetect.hpp index 0ef391d04..9fab7410a 100644 --- a/modules/objdetect/include/opencv2/objdetect/objdetect.hpp +++ b/modules/objdetect/include/opencv2/objdetect/objdetect.hpp @@ -507,7 +507,6 @@ public: int step = 4, int rejectfactor = 1); protected: - virtual void detectInRoi(); virtual void detectForOctave(int octave); // virtual bool detectSingleScale( const Mat& image, int stripCount, Size processingRectSize, // int stripSize, int yStep, double factor, vector& candidates, diff --git a/modules/objdetect/src/softcascade.cpp b/modules/objdetect/src/softcascade.cpp index cace66799..fa9405278 100644 --- a/modules/objdetect/src/softcascade.cpp +++ b/modules/objdetect/src/softcascade.cpp @@ -164,6 +164,15 @@ namespace { float relScale() {return (factor / octave); } }; + + struct Integral + { + cv::Mat magnitude; + std::vector hist; + cv::Mat luv; + + Integral(cv::Mat m, std::vector h, cv::Mat l) : magnitude(m), hist(h), luv(l) {} + }; } struct cv::SoftCascade::Filds @@ -181,6 +190,26 @@ struct cv::SoftCascade::Filds std::vector features; std::vector levels; + typedef std::vector::iterator stIter_t; + + // carrently roi must be save for out of ranges. + void detectInRoi(const cv::Rect& roi, const Integral& ints, std::vector& objects, const int step) + { + for (int dy = roi.y; dy < roi.height; dy+=step) + for (int dx = roi.x; dx < roi.width; dx += step) + { + applyCascade(ints, dx, dy); + } + } + + void applyCascade(const Integral& ints, const int x, const int y) + { + for (stIter_t sIt = sIt.begin(); sIt != stages.end(); ++sIt) + { + Stage stage& = *sIt; + } + } + // compute levels of full pyramid void calcLevels(int frameW, int frameH, int scales) { @@ -327,7 +356,7 @@ bool cv::SoftCascade::load( const string& filename, const float minScale, const namespace { - void calcHistBins(const cv::Mat& grey, std::vector& histInts, const int bins) + void calcHistBins(const cv::Mat& grey, cv::Mat magIntegral, std::vector& histInts, const int bins) { CV_Assert( grey.type() == CV_8U); const int rows = grey.rows + 1; @@ -368,18 +397,10 @@ namespace { histInts.push_back(sum); } - cv::Mat magIntegral; cv::integral(mag, magIntegral, mag.depth()); } - - struct Integrals - { - /* data */ - }; } -void cv::SoftCascade::detectInRoi() -{} void cv::SoftCascade::detectMultiScale(const Mat& image, const std::vector& rois, std::vector& objects, @@ -405,13 +426,16 @@ void cv::SoftCascade::detectMultiScale(const Mat& image, const std::vector hist; + cv::Mat magnitude; const int bins = 6; - calcHistBins(grey, hist, bins); + calcHistBins(grey, magnitude, hist, bins); + + Integral integrals(magnitude, hist, luv); for (RIter_t it = rois.begin(); it != rois.end(); ++it) { const cv::Rect& roi = *it; - // detectInRoi(roi, objects, step); + (*filds).detectInRoi(roi, integrals, objects, step); } } diff --git a/modules/objdetect/test/test_softcascade.cpp b/modules/objdetect/test/test_softcascade.cpp index d283d0608..bb02a091c 100644 --- a/modules/objdetect/test/test_softcascade.cpp +++ b/modules/objdetect/test/test_softcascade.cpp @@ -62,8 +62,8 @@ TEST(SoftCascade, Detect) std::vector objectBoxes; std::vector rois; rois.push_back(cv::Rect(0, 0, 640, 480)); - ASSERT_NO_THROW( - { + // ASSERT_NO_THROW( + // { cascade.detectMultiScale(colored, rois, objectBoxes); - }); + // }); } \ No newline at end of file From dc74ce20abc3002d7806809e40560785099bd470 Mon Sep 17 00:00:00 2001 From: "marina.kolpakova" Date: Wed, 12 Sep 2012 20:30:21 +0400 Subject: [PATCH 13/91] OpenCV friendly xml format for soft cascade --- .../include/opencv2/objdetect/objdetect.hpp | 28 +- modules/objdetect/src/softcascade.cpp | 487 ++++++++++-------- modules/objdetect/test/test_softcascade.cpp | 5 +- 3 files changed, 279 insertions(+), 241 deletions(-) diff --git a/modules/objdetect/include/opencv2/objdetect/objdetect.hpp b/modules/objdetect/include/opencv2/objdetect/objdetect.hpp index 9fab7410a..97d6122fe 100644 --- a/modules/objdetect/include/opencv2/objdetect/objdetect.hpp +++ b/modules/objdetect/include/opencv2/objdetect/objdetect.hpp @@ -493,32 +493,36 @@ protected: class CV_EXPORTS SoftCascade { public: - //! empty cascade will be created. + //! An empty cascade will be created. SoftCascade(); - //! cascade will be loaded from file "filename" + //! Cascade will be created from file for scales from minScale to maxScale. + //! Param filename is a path to xml-serialized cascade. + //! Param minScale is a minimum scale relative to the original size of the image on which cascade will be applyed. + //! Param minScale is a maximum scale relative to the original size of the image on which cascade will be applyed. SoftCascade( const string& filename, const float minScale = 0.4f, const float maxScale = 5.f); + + //! cascade will be loaded from file "filename". The previous cascade will be destroyed. + //! Param filename is a path to xml-serialized cascade. + //! Param minScale is a minimum scale relative to the original size of the image on which cascade will be applyed. + //! Param minScale is a maximum scale relative to the original size of the image on which cascade will be applyed. bool load( const string& filename, const float minScale = 0.4f, const float maxScale = 5.f); virtual ~SoftCascade(); - //! return vector of bounding boxes. Each box contains detected object + //! return vector of bounding boxes. Each box contains one detected object virtual void detectMultiScale(const Mat& image, const std::vector& rois, std::vector& objects, int step = 4, int rejectfactor = 1); protected: - virtual void detectForOctave(int octave); - // virtual bool detectSingleScale( const Mat& image, int stripCount, Size processingRectSize, - // int stripSize, int yStep, double factor, vector& candidates, - // vector& rejectLevels, vector& levelWeights, bool outputRejectLevels=false); enum { BOOST = 0 }; enum { - FRAME_WIDTH = 640, - FRAME_HEIGHT = 480, - TOTAL_SCALES = 55, - CLASSIFIERS = 5, - ORIG_OBJECT_WIDTH = 64, + FRAME_WIDTH = 640, + FRAME_HEIGHT = 480, + TOTAL_SCALES = 55, + CLASSIFIERS = 5, + ORIG_OBJECT_WIDTH = 64, ORIG_OBJECT_HEIGHT = 128 }; diff --git a/modules/objdetect/src/softcascade.cpp b/modules/objdetect/src/softcascade.cpp index fa9405278..c00285a69 100644 --- a/modules/objdetect/src/softcascade.cpp +++ b/modules/objdetect/src/softcascade.cpp @@ -45,134 +45,160 @@ #include #include -#include +#include namespace { - static const char* SC_OCT_SCALE = "scale"; - static const char* SC_OCT_STAGES = "stageNum"; - struct Octave { float scale; int stages; + cv::Size size; + int shrinkage; + static const char *const SC_OCT_SCALE; + static const char *const SC_OCT_STAGES; + static const char *const SC_OCT_SHRINKAGE; Octave(){} - Octave(const cv::FileNode& fn) : scale((float)fn[SC_OCT_SCALE]), stages((int)fn[SC_OCT_STAGES]) - {/*printf("octave: %f %d\n", scale, stages);*/} + Octave(cv::Size origObjSize, const cv::FileNode& fn) + : scale((float)fn[SC_OCT_SCALE]), stages((int)fn[SC_OCT_STAGES]), + size(cvRound(origObjSize.width * scale), cvRound(origObjSize.height * scale)), + shrinkage((int)fn[SC_OCT_SHRINKAGE]) + {} }; - static const char *SC_STAGE_THRESHOLD = "stageThreshold"; - static const char *SC_STAGE_WEIGHT = "weight"; + const char *const Octave::SC_OCT_SCALE = "scale"; + const char *const Octave::SC_OCT_STAGES = "stageNum"; + const char *const Octave::SC_OCT_SHRINKAGE = "shrinkingFactor"; + struct Stage { float threshold; - float weight; + + static const char *const SC_STAGE_THRESHOLD; Stage(){} - Stage(const cv::FileNode& fn) : threshold((float)fn[SC_STAGE_THRESHOLD]), weight((float)fn[SC_STAGE_WEIGHT]) - {/*printf(" stage: %f %f\n",threshold, weight);*/} + Stage(const cv::FileNode& fn) : threshold((float)fn[SC_STAGE_THRESHOLD]) + { std::cout << " stage: " << threshold << std::endl; } }; - // according to R. Benenson, M. Mathias, R. Timofte and L. Van Gool paper - struct CascadeIntrinsics + const char *const Stage::SC_STAGE_THRESHOLD = "stageThreshold"; + + struct Node { - static const float lambda = 1.099f, a = 0.89f; - static const float intrinsics[10][4]; - - static float getFor(int channel, float scaling) - { - CV_Assert(channel < 10); - - if ((scaling - 1.f) < FLT_EPSILON) - return 1.f; - - int ud = (int)(scaling < 1.f); - return intrinsics[channel][(ud << 1)] * pow(scaling, intrinsics[channel][(ud << 1) + 1]); - } + int feature; + float threshold; + Node(){} + Node(cv::FileNodeIterator& fIt) : feature((int)(*(fIt +=2)++)), threshold((float)(*(fIt++))) + { std::cout << " Node: " << feature << " " << threshold << std::endl; } }; - const float CascadeIntrinsics::intrinsics[10][4] = - { //da, db, ua, ub - // hog-like orientation bins - {a, lambda / log(2), 1, 2}, - {a, lambda / log(2), 1, 2}, - {a, lambda / log(2), 1, 2}, - {a, lambda / log(2), 1, 2}, - {a, lambda / log(2), 1, 2}, - {a, lambda / log(2), 1, 2}, - // gradient magnitude - {a, lambda / log(2), 1, 2}, - // luv color channels - {1, 2, 1, 2}, - {1, 2, 1, 2}, - {1, 2, 1, 2} - }; - - static const char *SC_F_THRESHOLD = "threshold"; - static const char *SC_F_DIRECTION = "direction"; - static const char *SC_F_CHANNEL = "channel"; - static const char *SC_F_RECT = "rect"; struct Feature { - float threshold; - int direction; int channel; cv::Rect rect; + static const char * const SC_F_CHANNEL; + static const char * const SC_F_RECT; + Feature() {} - Feature(const cv::FileNode& fn) - : threshold((float)fn[SC_F_THRESHOLD]), direction((int)fn[SC_F_DIRECTION]), - channel((int)fn[SC_F_CHANNEL]) + Feature(const cv::FileNode& fn) : channel((int)fn[SC_F_CHANNEL]) { cv::FileNode rn = fn[SC_F_RECT]; - cv::FileNodeIterator r_it = rn.begin(); - rect = cv::Rect(*(r_it++), *(r_it++), *(r_it++), *(r_it++)); - // printf(" feature: %f %d %d [%d %d %d %d]\n",threshold, direction, channel, rect.x, rect.y, rect.width, rect.height); + cv::FileNodeIterator r_it = rn.end(); + rect = cv::Rect(*(--r_it), *(--r_it), *(--r_it), *(--r_it)); + std::cout << "feature: " << rect.x << " " << rect.y << " " << rect.width << " " << rect.height << " " << channel << std::endl; } - Feature rescale(float relScale) - { - Feature res(*this); - res.rect = cv::Rect (cvRound(rect.x * relScale), cvRound(rect.y * relScale), - cvRound(rect.width * relScale), cvRound(rect.height * relScale)); - res.threshold = threshold * CascadeIntrinsics::getFor(channel, relScale); - return res; - } +// Feature rescale(float relScale) +// { +// Feature res(*this); +// res.rect = cv::Rect (cvRound(rect.x * relScale), cvRound(rect.y * relScale), +// cvRound(rect.width * relScale), cvRound(rect.height * relScale)); +// res.threshold = threshold * CascadeIntrinsics::getFor(channel, relScale); +// return res; +// } }; - struct Level - { - int index; - float factor; - float logFactor; - int width; - int height; - float octave; - cv::Size objSize; + const char * const Feature::SC_F_CHANNEL = "channel"; + const char * const Feature::SC_F_RECT = "rect"; +// // according to R. Benenson, M. Mathias, R. Timofte and L. Van Gool paper +// struct CascadeIntrinsics +// { +// static const float lambda = 1.099f, a = 0.89f; +// static const float intrinsics[10][4]; - Level(int i,float f, float lf, int w, int h): index(i), factor(f), logFactor(lf), width(w), height(h), octave(0.f) {} +// static float getFor(int channel, float scaling) +// { +// CV_Assert(channel < 10); - void assign(float o, int detW, int detH) - { - octave = o; - objSize = cv::Size(cv::saturate_cast(detW * o), cv::saturate_cast(detH * o)); - } +// if ((scaling - 1.f) < FLT_EPSILON) +// return 1.f; - float relScale() {return (factor / octave); } - }; +// int ud = (int)(scaling < 1.f); +// return intrinsics[channel][(ud << 1)] * pow(scaling, intrinsics[channel][(ud << 1) + 1]); +// } - struct Integral - { - cv::Mat magnitude; - std::vector hist; - cv::Mat luv; +// }; - Integral(cv::Mat m, std::vector h, cv::Mat l) : magnitude(m), hist(h), luv(l) {} - }; +// const float CascadeIntrinsics::intrinsics[10][4] = +// { //da, db, ua, ub +// // hog-like orientation bins +// {a, lambda / log(2), 1, 2}, +// {a, lambda / log(2), 1, 2}, +// {a, lambda / log(2), 1, 2}, +// {a, lambda / log(2), 1, 2}, +// {a, lambda / log(2), 1, 2}, +// {a, lambda / log(2), 1, 2}, +// // gradient magnitude +// {a, lambda / log(2), 1, 2}, +// // luv color channels +// {1, 2, 1, 2}, +// {1, 2, 1, 2}, +// {1, 2, 1, 2} +// }; + +// struct Level +// { +// int index; + +// float factor; +// float logFactor; + +// int width; +// int height; + +// Octave octave; + +// cv::Size objSize; +// cv::Size dWinSize; + +// static const float shrinkage = 0.25; + +// Level(int i,float f, float lf, int w, int h): index(i), factor(f), logFactor(lf), width(w), height(h), octave(Octave()) +// {} + +// void assign(const Octave& o, int detW, int detH) +// { +// octave = o; +// objSize = cv::Size(cv::saturate_cast(detW * o.scale), cv::saturate_cast(detH * o.scale)); +// } + +// float relScale() {return (factor / octave.scale); } +// float srScale() {return (factor / octave.scale * shrinkage); } +// }; + +// struct Integral +// { +// cv::Mat magnitude; +// std::vector hist; +// cv::Mat luv; + +// Integral(cv::Mat m, std::vector h, cv::Mat l) : magnitude(m), hist(h), luv(l) {} +// }; } struct cv::SoftCascade::Filds @@ -183,68 +209,72 @@ struct cv::SoftCascade::Filds int origObjWidth; int origObjHeight; - int noctaves; - std::vector octaves; std::vector stages; + std::vector nodes; + std::vector leaves; + std::vector features; - std::vector levels; - typedef std::vector::iterator stIter_t; + // typedef std::vector::iterator stIter_t; - // carrently roi must be save for out of ranges. - void detectInRoi(const cv::Rect& roi, const Integral& ints, std::vector& objects, const int step) - { - for (int dy = roi.y; dy < roi.height; dy+=step) - for (int dx = roi.x; dx < roi.width; dx += step) - { - applyCascade(ints, dx, dy); - } - } + // // carrently roi must be save for out of ranges. + // void detectInRoi(const cv::Rect& roi, const Integral& ints, std::vector& objects, const int step) + // { + // for (int dy = roi.y; dy < roi.height; dy+=step) + // for (int dx = roi.x; dx < roi.width; dx += step) + // { + // applyCascade(ints, dx, dy); + // } + // } - void applyCascade(const Integral& ints, const int x, const int y) - { - for (stIter_t sIt = sIt.begin(); sIt != stages.end(); ++sIt) - { - Stage stage& = *sIt; - } - } + // void applyCascade(const Integral& ints, const int x, const int y) + // { + // for (stIter_t sIt = stages.begin(); sIt != stages.end(); ++sIt) + // { + // Stage& stage = *sIt; + // } + // } - // compute levels of full pyramid - void calcLevels(int frameW, int frameH, int scales) - { - CV_Assert(scales > 1); - levels.clear(); - float logFactor = (log(maxScale) - log(minScale)) / (scales -1); + // // compute levels of full pyramid + // void calcLevels(int frameW, int frameH, int scales) + // { + // CV_Assert(scales > 1); + // levels.clear(); + // float logFactor = (log(maxScale) - log(minScale)) / (scales -1); - float scale = minScale; - for (int sc = 0; sc < scales; ++sc) - { - Level level(sc, scale, log(scale) + logFactor, - std::max(0.0f, frameW - (origObjWidth * scale)), std::max(0.0f, frameH - (origObjHeight * scale))); - if (!level.width || !level.height) - break; - else - levels.push_back(level); + // float scale = minScale; + // for (int sc = 0; sc < scales; ++sc) + // { + // Level level(sc, scale, log(scale), std::max(0.0f, frameW - (origObjWidth * scale)), std::max(0.0f, frameH - (origObjHeight * scale))); + // if (!level.width || !level.height) + // break; + // else + // levels.push_back(level); - if (fabs(scale - maxScale) < FLT_EPSILON) break; - scale = std::min(maxScale, expf(log(scale) + logFactor)); - } + // if (fabs(scale - maxScale) < FLT_EPSILON) break; + // scale = std::min(maxScale, expf(log(scale) + logFactor)); + // } - for (std::vector::iterator level = levels.begin(); level < levels.end(); ++level) - { - float minAbsLog = FLT_MAX; - for (std::vector::iterator oct = octaves.begin(); oct < octaves.end(); ++oct) - { - const Octave& octave =*oct; - float logOctave = log(octave.scale); - float logAbsScale = fabs((*level).logFactor - logOctave); + // for (std::vector::iterator level = levels.begin(); level < levels.end(); ++level) + // { + // float minAbsLog = FLT_MAX; + // for (std::vector::iterator oct = octaves.begin(); oct < octaves.end(); ++oct) + // { + // const Octave& octave =*oct; + // float logOctave = log(octave.scale); + // float logAbsScale = fabs((*level).logFactor - logOctave); - if(logAbsScale < minAbsLog) - (*level).assign(octave.scale, ORIG_OBJECT_WIDTH, ORIG_OBJECT_HEIGHT); - } - } - } + + // if(logAbsScale < minAbsLog) + // { + // printf("######### %f %f %f %f\n", octave.scale, logOctave, logAbsScale, (*level).logFactor); + // minAbsLog = logAbsScale; + // (*level).assign(octave, ORIG_OBJECT_WIDTH, ORIG_OBJECT_HEIGHT); + // } + // } + // } + // } bool fill(const FileNode &root, const float mins, const float maxs) { @@ -252,19 +282,22 @@ struct cv::SoftCascade::Filds maxScale = maxs; // cascade properties - const char *SC_STAGE_TYPE = "stageType"; - const char *SC_BOOST = "BOOST"; - const char *SC_FEATURE_TYPE = "featureType"; - const char *SC_ICF = "ICF"; - const char *SC_TREE_TYPE = "stageTreeType"; - const char *SC_STAGE_TH2 = "TH2"; - const char *SC_NUM_OCTAVES = "octavesNum"; - const char *SC_ORIG_W = "origObjWidth"; - const char *SC_ORIG_H = "origObjHeight"; + static const char *const SC_STAGE_TYPE = "stageType"; + static const char *const SC_BOOST = "BOOST"; - const char* SC_OCTAVES = "octaves"; - const char *SC_STAGES = "stages"; - const char *SC_FEATURES = "features"; + static const char *const SC_FEATURE_TYPE = "featureType"; + static const char *const SC_ICF = "ICF"; + + static const char *const SC_ORIG_W = "width"; + static const char *const SC_ORIG_H = "height"; + + static const char *const SC_OCTAVES = "octaves"; + static const char *const SC_STAGES = "stages"; + static const char *const SC_FEATURES = "features"; + + static const char *const SC_WEEK = "weakClassifiers"; + static const char *const SC_INTERNAL = "internalNodes"; + static const char *const SC_LEAF = "leafValues"; // only boost supported @@ -275,14 +308,6 @@ struct cv::SoftCascade::Filds string featureTypeStr = (string)root[SC_FEATURE_TYPE]; CV_Assert(featureTypeStr == SC_ICF); - // only trees of height 2 - string stageTreeTypeStr = (string)root[SC_TREE_TYPE]; - CV_Assert(stageTreeTypeStr == SC_STAGE_TH2); - - // not empty - noctaves = (int)root[SC_NUM_OCTAVES]; - CV_Assert(noctaves > 0); - origObjWidth = (int)root[SC_ORIG_W]; CV_Assert(origObjWidth == SoftCascade::ORIG_OBJECT_WIDTH); @@ -293,15 +318,17 @@ struct cv::SoftCascade::Filds FileNode fn = root[SC_OCTAVES]; if (fn.empty()) return false; - octaves.reserve(noctaves); + // octaves.reserve(noctaves); FileNodeIterator it = fn.begin(), it_end = fn.end(); for (; it != it_end; ++it) { FileNode fns = *it; - Octave octave = Octave(fns); + Octave octave(cv::Size(SoftCascade::ORIG_OBJECT_WIDTH, SoftCascade::ORIG_OBJECT_HEIGHT), fns); CV_Assert(octave.stages > 0); octaves.push_back(octave); - stages.reserve(stages.size() + octave.stages); + + FileNode ffs = fns[SC_FEATURES]; + if (ffs.empty()) return false; fns = fns[SC_STAGES]; if (fn.empty()) return false; @@ -313,14 +340,25 @@ struct cv::SoftCascade::Filds fns = *st; stages.push_back(Stage(fns)); - fns = fns[SC_FEATURES]; - // for each feature for tree. features stored in order {root, left, right} + fns = fns[SC_WEEK]; FileNodeIterator ftr = fns.begin(), ft_end = fns.end(); for (; ftr != ft_end; ++ftr) { - features.push_back(Feature(*ftr)); + fns = (*ftr)[SC_INTERNAL]; + FileNodeIterator inIt = fns.begin(), inIt_end = fns.end(); + for (; inIt != inIt_end;) + nodes.push_back(Node(inIt)); + + fns = (*ftr)[SC_LEAF]; + inIt = fns.begin(), inIt_end = fns.end(); + for (; inIt != inIt_end; ++inIt) + leaves.push_back((float)(*inIt)); } } + + st = ffs.begin(), st_end = ffs.end(); + for (; st != st_end; ++st ) + features.push_back(Feature(*st)); } return true; } @@ -349,7 +387,7 @@ bool cv::SoftCascade::load( const string& filename, const float minScale, const filds = new Filds; Filds& flds = *filds; if (!flds.fill(fs.getFirstTopLevelNode(), minScale, maxScale)) return false; - flds.calcLevels(FRAME_WIDTH, FRAME_HEIGHT, TOTAL_SCALES); + // // flds.calcLevels(FRAME_WIDTH, FRAME_HEIGHT, TOTAL_SCALES); return true; } @@ -358,87 +396,84 @@ namespace { void calcHistBins(const cv::Mat& grey, cv::Mat magIntegral, std::vector& histInts, const int bins) { - CV_Assert( grey.type() == CV_8U); - const int rows = grey.rows + 1; - const int cols = grey.cols + 1; - cv::Size intSumSize(cols, rows); + // CV_Assert( grey.type() == CV_8U); + // const int rows = grey.rows + 1; + // const int cols = grey.cols + 1; + // cv::Size intSumSize(cols, rows); - histInts.clear(); - std::vector hist; - for (int bin = 0; bin < bins; ++bin) - { - hist.push_back(cv::Mat(rows, cols, CV_32FC1)); - } - cv::Mat df_dx, df_dy, mag, angle; - cv::Sobel(grey, df_dx, CV_32F, 1, 0); - cv::Sobel(grey, df_dy, CV_32F, 0, 1); + // histInts.clear(); + // std::vector hist; + // for (int bin = 0; bin < bins; ++bin) + // { + // hist.push_back(cv::Mat(rows, cols, CV_32FC1)); + // } + // cv::Mat df_dx, df_dy, mag, angle; + // cv::Sobel(grey, df_dx, CV_32F, 1, 0); + // cv::Sobel(grey, df_dy, CV_32F, 0, 1); - cv::cartToPolar(df_dx, df_dy, mag, angle, true); + // cv::cartToPolar(df_dx, df_dy, mag, angle, true); - const float magnitudeScaling = 1.0 / sqrt(2); - mag *= magnitudeScaling; - angle /= 60; + // const float magnitudeScaling = 1.0 / sqrt(2); + // mag *= magnitudeScaling; + // angle /= 60; - for (int h = 0; h < mag.rows; ++h) - { - float* magnitude = mag.ptr(h); - float* ang = angle.ptr(h); + // for (int h = 0; h < mag.rows; ++h) + // { + // float* magnitude = mag.ptr(h); + // float* ang = angle.ptr(h); - for (int w = 0; w < mag.cols; ++w) - { - hist[(int)ang[w]].ptr(h)[w] = magnitude[w]; - } - } + // for (int w = 0; w < mag.cols; ++w) + // { + // hist[(int)ang[w]].ptr(h)[w] = magnitude[w]; + // } + // } - for (int bin = 0; bin < bins; ++bin) - { - cv::Mat sum; - cv::integral(hist[bin], sum); - histInts.push_back(sum); - } + // for (int bin = 0; bin < bins; ++bin) + // { + // cv::Mat sum; + // cv::integral(hist[bin], sum); + // histInts.push_back(sum); + // } - cv::integral(mag, magIntegral, mag.depth()); + // cv::integral(mag, magIntegral, mag.depth()); } } void cv::SoftCascade::detectMultiScale(const Mat& image, const std::vector& rois, std::vector& objects, - const int step, const int rejectfactor) + const int step, const int rejectfactor)// add step scaling { - typedef std::vector::const_iterator RIter_t; - // only color images are supperted - CV_Assert(image.type() == CV_8UC3); + // typedef std::vector::const_iterator RIter_t; + // // only color images are supperted + // CV_Assert(image.type() == CV_8UC3); - // only this window size allowed - CV_Assert(image.cols == 640 && image.rows == 480); + // // only this window size allowed + // CV_Assert(image.cols == 640 && image.rows == 480); - objects.clear(); + // objects.clear(); - // create integrals - cv::Mat luv; - cv::cvtColor(image, luv, CV_BGR2Luv); + // // create integrals + // cv::Mat luv; + // cv::cvtColor(image, luv, CV_BGR2Luv); - cv::Mat luvIntegral; - cv::integral(luv, luvIntegral); + // cv::Mat luvIntegral; + // cv::integral(luv, luvIntegral); - cv::Mat grey; - cv::cvtColor(image, grey, CV_RGB2GRAY); + // cv::Mat grey; + // cv::cvtColor(image, grey, CV_RGB2GRAY); - std::vector hist; - cv::Mat magnitude; - const int bins = 6; - calcHistBins(grey, magnitude, hist, bins); + // std::vector hist; + // cv::Mat magnitude; + // const int bins = 6; + // calcHistBins(grey, magnitude, hist, bins); - Integral integrals(magnitude, hist, luv); + // Integral integrals(magnitude, hist, luv); - for (RIter_t it = rois.begin(); it != rois.end(); ++it) - { - const cv::Rect& roi = *it; - (*filds).detectInRoi(roi, integrals, objects, step); - } + // for (RIter_t it = rois.begin(); it != rois.end(); ++it) + // { + // const cv::Rect& roi = *it; + // (*filds).detectInRoi(roi, integrals, objects, step); + // } -} - -void cv::SoftCascade::detectForOctave(const int octave) -{} \ No newline at end of file +} \ No newline at end of file diff --git a/modules/objdetect/test/test_softcascade.cpp b/modules/objdetect/test/test_softcascade.cpp index bb02a091c..ccf713957 100644 --- a/modules/objdetect/test/test_softcascade.cpp +++ b/modules/objdetect/test/test_softcascade.cpp @@ -43,16 +43,15 @@ TEST(SoftCascade, readCascade) { - std::string xml = "/home/kellan/icf-template.xml"; + std::string xml = cvtest::TS::ptr()->get_data_path() + "cascadeandhog/icf-template.xml"; cv::SoftCascade cascade; ASSERT_TRUE(cascade.load(xml)); } -TEST(SoftCascade, Detect) +TEST(SoftCascade, detect) { std::string xml = cvtest::TS::ptr()->get_data_path() + "cascadeandhog/softcascade.xml"; - std::cout << "PATH: "<< xml << std::endl; cv::SoftCascade cascade; ASSERT_TRUE(cascade.load(xml)); From 6f53be4102d59340198d682b2e7a71e4b57400b2 Mon Sep 17 00:00:00 2001 From: "marina.kolpakova" Date: Thu, 13 Sep 2012 15:15:26 +0400 Subject: [PATCH 14/91] shrinking before integral calculation --- modules/objdetect/src/softcascade.cpp | 166 ++++++++++++-------- modules/objdetect/test/test_softcascade.cpp | 2 +- 2 files changed, 99 insertions(+), 69 deletions(-) diff --git a/modules/objdetect/src/softcascade.cpp b/modules/objdetect/src/softcascade.cpp index c00285a69..6cb9d693f 100644 --- a/modules/objdetect/src/softcascade.cpp +++ b/modules/objdetect/src/softcascade.cpp @@ -161,8 +161,8 @@ namespace { // {1, 2, 1, 2} // }; -// struct Level -// { + struct Level + { // int index; // float factor; @@ -189,7 +189,7 @@ namespace { // float relScale() {return (factor / octave.scale); } // float srScale() {return (factor / octave.scale * shrinkage); } -// }; + }; // struct Integral // { @@ -209,6 +209,8 @@ struct cv::SoftCascade::Filds int origObjWidth; int origObjHeight; + int shrinkage; + std::vector octaves; std::vector stages; std::vector nodes; @@ -216,6 +218,8 @@ struct cv::SoftCascade::Filds std::vector features; + std::vector levels; + // typedef std::vector::iterator stIter_t; // // carrently roi must be save for out of ranges. @@ -236,11 +240,11 @@ struct cv::SoftCascade::Filds // } // } - // // compute levels of full pyramid - // void calcLevels(int frameW, int frameH, int scales) - // { - // CV_Assert(scales > 1); - // levels.clear(); + // compute levels of full pyramid + void calcLevels(int frameW, int frameH, int scales) + { + CV_Assert(scales > 1); + levels.clear(); // float logFactor = (log(maxScale) - log(minScale)) / (scales -1); // float scale = minScale; @@ -274,7 +278,7 @@ struct cv::SoftCascade::Filds // } // } // } - // } + } bool fill(const FileNode &root, const float mins, const float maxs) { @@ -360,15 +364,16 @@ struct cv::SoftCascade::Filds for (; st != st_end; ++st ) features.push_back(Feature(*st)); } + + shrinkage = octaves[0].shrinkage; return true; } }; cv::SoftCascade::SoftCascade() : filds(0) {} -cv::SoftCascade::SoftCascade( const string& filename, const float minScale, const float maxScale) +cv::SoftCascade::SoftCascade( const string& filename, const float minScale, const float maxScale) : filds(0) { - filds = new Filds; load(filename, minScale, maxScale); } cv::SoftCascade::~SoftCascade() @@ -378,7 +383,8 @@ cv::SoftCascade::~SoftCascade() bool cv::SoftCascade::load( const string& filename, const float minScale, const float maxScale) { - delete filds; + if (filds) + delete filds; filds = 0; cv::FileStorage fs(filename, FileStorage::READ); @@ -387,56 +393,92 @@ bool cv::SoftCascade::load( const string& filename, const float minScale, const filds = new Filds; Filds& flds = *filds; if (!flds.fill(fs.getFirstTopLevelNode(), minScale, maxScale)) return false; - // // flds.calcLevels(FRAME_WIDTH, FRAME_HEIGHT, TOTAL_SCALES); + flds.calcLevels(FRAME_WIDTH, FRAME_HEIGHT, TOTAL_SCALES); return true; } namespace { - void calcHistBins(const cv::Mat& grey, cv::Mat magIntegral, std::vector& histInts, const int bins) + void calcHistBins(const cv::Mat& grey, cv::Mat& magIntegral, std::vector& histInts, const int bins, int shrinkage) { - // CV_Assert( grey.type() == CV_8U); - // const int rows = grey.rows + 1; - // const int cols = grey.cols + 1; - // cv::Size intSumSize(cols, rows); + CV_Assert( grey.type() == CV_8U); - // histInts.clear(); - // std::vector hist; - // for (int bin = 0; bin < bins; ++bin) - // { - // hist.push_back(cv::Mat(rows, cols, CV_32FC1)); - // } - // cv::Mat df_dx, df_dy, mag, angle; - // cv::Sobel(grey, df_dx, CV_32F, 1, 0); - // cv::Sobel(grey, df_dy, CV_32F, 0, 1); + float scale = 1.f / shrinkage; - // cv::cartToPolar(df_dx, df_dy, mag, angle, true); + const int rows = grey.rows + 1; + const int cols = grey.cols + 1; + cv::Size intSumSize(cols, rows); - // const float magnitudeScaling = 1.0 / sqrt(2); - // mag *= magnitudeScaling; - // angle /= 60; + histInts.clear(); + std::vector hist; + for (int bin = 0; bin < bins; ++bin) + { + hist.push_back(cv::Mat(rows, cols, CV_32FC1)); + } - // for (int h = 0; h < mag.rows; ++h) - // { - // float* magnitude = mag.ptr(h); - // float* ang = angle.ptr(h); + cv::Mat df_dx, df_dy, mag, angle; + cv::Sobel(grey, df_dx, CV_32F, 1, 0); + cv::Sobel(grey, df_dy, CV_32F, 0, 1); - // for (int w = 0; w < mag.cols; ++w) - // { - // hist[(int)ang[w]].ptr(h)[w] = magnitude[w]; - // } - // } + cv::cartToPolar(df_dx, df_dy, mag, angle, true); - // for (int bin = 0; bin < bins; ++bin) - // { - // cv::Mat sum; - // cv::integral(hist[bin], sum); - // histInts.push_back(sum); - // } + const float magnitudeScaling = 1.0 / sqrt(2); + mag *= magnitudeScaling; + angle /= 60; - // cv::integral(mag, magIntegral, mag.depth()); + for (int h = 0; h < mag.rows; ++h) + { + float* magnitude = mag.ptr(h); + float* ang = angle.ptr(h); + + for (int w = 0; w < mag.cols; ++w) + { + hist[(int)ang[w]].ptr(h)[w] = magnitude[w]; + } + } + + for (int bin = 0; bin < bins; ++bin) + { + cv::Mat shrunk, sum; + cv::resize(hist[bin], shrunk, cv::Size(), scale, scale, cv::INTER_AREA); + cv::integral(shrunk, sum); + histInts.push_back(sum); + } + + cv::Mat shrMag; + cv::resize(mag, shrMag, cv::Size(), scale, scale, cv::INTER_AREA); + + cv::integral(shrMag, magIntegral, mag.depth()); } + + struct ChannelStorage + { + std::vector hog; + cv::Mat luv; + cv::Mat magnitude; + + int shrinkage; + + enum {HOG_BINS = 6}; + + ChannelStorage() {} + ChannelStorage(const cv::Mat& colored, int shr) : shrinkage(shr) + { + cv::Mat _luv; + cv::cvtColor(colored, _luv, CV_BGR2Luv); + + cv::integral(luv, luv); + + cv::Mat grey; + cv::cvtColor(colored, grey, CV_RGB2GRAY); + + calcHistBins(grey, magnitude, hog, HOG_BINS, shrinkage); + std::cout << magnitude.cols << " " << magnitude.rows << std::endl; + cv::imshow("1", magnitude); + cv::waitKey(0); + } + }; } @@ -444,31 +486,19 @@ namespace { void cv::SoftCascade::detectMultiScale(const Mat& image, const std::vector& rois, std::vector& objects, const int step, const int rejectfactor)// add step scaling { - // typedef std::vector::const_iterator RIter_t; - // // only color images are supperted - // CV_Assert(image.type() == CV_8UC3); + typedef std::vector::const_iterator RIter_t; + // only color images are supperted + CV_Assert(image.type() == CV_8UC3); - // // only this window size allowed - // CV_Assert(image.cols == 640 && image.rows == 480); + // only this window size allowed + CV_Assert(image.cols == 640 && image.rows == 480); - // objects.clear(); + objects.clear(); - // // create integrals - // cv::Mat luv; - // cv::cvtColor(image, luv, CV_BGR2Luv); + const Filds& fld = *filds; - // cv::Mat luvIntegral; - // cv::integral(luv, luvIntegral); - - // cv::Mat grey; - // cv::cvtColor(image, grey, CV_RGB2GRAY); - - // std::vector hist; - // cv::Mat magnitude; - // const int bins = 6; - // calcHistBins(grey, magnitude, hist, bins); - - // Integral integrals(magnitude, hist, luv); + // create integrals + ChannelStorage storage(image, fld.shrinkage); // for (RIter_t it = rois.begin(); it != rois.end(); ++it) // { diff --git a/modules/objdetect/test/test_softcascade.cpp b/modules/objdetect/test/test_softcascade.cpp index ccf713957..7311ad291 100644 --- a/modules/objdetect/test/test_softcascade.cpp +++ b/modules/objdetect/test/test_softcascade.cpp @@ -51,7 +51,7 @@ TEST(SoftCascade, readCascade) TEST(SoftCascade, detect) { - std::string xml = cvtest::TS::ptr()->get_data_path() + "cascadeandhog/softcascade.xml"; + std::string xml = cvtest::TS::ptr()->get_data_path() + "cascadeandhog/sc_cvpr_2012_to_opencv.xml"; cv::SoftCascade cascade; ASSERT_TRUE(cascade.load(xml)); From 801368ee82d68c1a502e97c19f8a621042050e90 Mon Sep 17 00:00:00 2001 From: "marina.kolpakova" Date: Thu, 13 Sep 2012 18:58:14 +0400 Subject: [PATCH 15/91] refactoring --- modules/objdetect/src/softcascade.cpp | 268 +++++++++++++------------- 1 file changed, 137 insertions(+), 131 deletions(-) diff --git a/modules/objdetect/src/softcascade.cpp b/modules/objdetect/src/softcascade.cpp index 6cb9d693f..8dfe14b6a 100644 --- a/modules/objdetect/src/softcascade.cpp +++ b/modules/objdetect/src/softcascade.cpp @@ -49,69 +49,93 @@ namespace { - struct Octave +struct Octave +{ + float scale; + int stages; + cv::Size size; + int shrinkage; + + static const char *const SC_OCT_SCALE; + static const char *const SC_OCT_STAGES; + static const char *const SC_OCT_SHRINKAGE; + + Octave() : scale(0), stages(0), size(cv::Size()), shrinkage(0) {} + Octave(cv::Size origObjSize, const cv::FileNode& fn) + : scale((float)fn[SC_OCT_SCALE]), stages((int)fn[SC_OCT_STAGES]), + size(cvRound(origObjSize.width * scale), cvRound(origObjSize.height * scale)), + shrinkage((int)fn[SC_OCT_SHRINKAGE]) + {} +}; + +const char *const Octave::SC_OCT_SCALE = "scale"; +const char *const Octave::SC_OCT_STAGES = "stageNum"; +const char *const Octave::SC_OCT_SHRINKAGE = "shrinkingFactor"; + + +struct Stage +{ + float threshold; + + static const char *const SC_STAGE_THRESHOLD; + + Stage(){} + Stage(const cv::FileNode& fn) : threshold((float)fn[SC_STAGE_THRESHOLD]){} +}; + +const char *const Stage::SC_STAGE_THRESHOLD = "stageThreshold"; + +struct Node +{ + int feature; + float threshold; + + Node(){} + Node(cv::FileNodeIterator& fIt) : feature((int)(*(fIt +=2)++)), threshold((float)(*(fIt++))){} +}; + + +struct Feature +{ + int channel; + cv::Rect rect; + + static const char * const SC_F_CHANNEL; + static const char * const SC_F_RECT; + + Feature() {} + Feature(const cv::FileNode& fn) : channel((int)fn[SC_F_CHANNEL]) { - float scale; - int stages; - cv::Size size; - int shrinkage; - static const char *const SC_OCT_SCALE; - static const char *const SC_OCT_STAGES; - static const char *const SC_OCT_SHRINKAGE; + cv::FileNode rn = fn[SC_F_RECT]; + cv::FileNodeIterator r_it = rn.end(); + rect = cv::Rect(*(--r_it), *(--r_it), *(--r_it), *(--r_it)); + // std::cout << "feature: " << rect.x << " " << rect.y << " " << rect.width + //<< " " << rect.height << " " << channel << std::endl; + } +}; - Octave(){} - Octave(cv::Size origObjSize, const cv::FileNode& fn) - : scale((float)fn[SC_OCT_SCALE]), stages((int)fn[SC_OCT_STAGES]), - size(cvRound(origObjSize.width * scale), cvRound(origObjSize.height * scale)), - shrinkage((int)fn[SC_OCT_SHRINKAGE]) - {} - }; +const char * const Feature::SC_F_CHANNEL = "channel"; +const char * const Feature::SC_F_RECT = "rect"; - const char *const Octave::SC_OCT_SCALE = "scale"; - const char *const Octave::SC_OCT_STAGES = "stageNum"; - const char *const Octave::SC_OCT_SHRINKAGE = "shrinkingFactor"; +struct Level +{ + const Octave* octave; + + float origScale; + float relScale; + float shrScale; + + cv::Size workRect; + cv::Size objSize; - struct Stage - { - float threshold; - - static const char *const SC_STAGE_THRESHOLD; - - Stage(){} - Stage(const cv::FileNode& fn) : threshold((float)fn[SC_STAGE_THRESHOLD]) - { std::cout << " stage: " << threshold << std::endl; } - }; - - const char *const Stage::SC_STAGE_THRESHOLD = "stageThreshold"; - - struct Node - { - int feature; - float threshold; - - Node(){} - Node(cv::FileNodeIterator& fIt) : feature((int)(*(fIt +=2)++)), threshold((float)(*(fIt++))) - { std::cout << " Node: " << feature << " " << threshold << std::endl; } - }; - - - struct Feature - { - int channel; - cv::Rect rect; - - static const char * const SC_F_CHANNEL; - static const char * const SC_F_RECT; - - Feature() {} - Feature(const cv::FileNode& fn) : channel((int)fn[SC_F_CHANNEL]) - { - cv::FileNode rn = fn[SC_F_RECT]; - cv::FileNodeIterator r_it = rn.end(); - rect = cv::Rect(*(--r_it), *(--r_it), *(--r_it), *(--r_it)); - std::cout << "feature: " << rect.x << " " << rect.y << " " << rect.width << " " << rect.height << " " << channel << std::endl; - } + // TiDo not reounding + Level(const Octave& oct, const float scale, const int shrinkage, const int w, const int h) + : octave(&oct), origScale(scale), relScale(scale / oct.scale), shrScale (relScale / shrinkage), + workRect(cv::Size(cvRound(w / (float)shrinkage),cvRound(h / (float)shrinkage))), + objSize(cv::Size(cvRound(oct.size.width * relScale), cvRound(oct.size.height * relScale))) + {} +}; // Feature rescale(float relScale) // { @@ -121,10 +145,7 @@ namespace { // res.threshold = threshold * CascadeIntrinsics::getFor(channel, relScale); // return res; // } - }; - const char * const Feature::SC_F_CHANNEL = "channel"; - const char * const Feature::SC_F_RECT = "rect"; // // according to R. Benenson, M. Mathias, R. Timofte and L. Van Gool paper // struct CascadeIntrinsics // { @@ -161,44 +182,6 @@ namespace { // {1, 2, 1, 2} // }; - struct Level - { -// int index; - -// float factor; -// float logFactor; - -// int width; -// int height; - -// Octave octave; - -// cv::Size objSize; -// cv::Size dWinSize; - -// static const float shrinkage = 0.25; - -// Level(int i,float f, float lf, int w, int h): index(i), factor(f), logFactor(lf), width(w), height(h), octave(Octave()) -// {} - -// void assign(const Octave& o, int detW, int detH) -// { -// octave = o; -// objSize = cv::Size(cv::saturate_cast(detW * o.scale), cv::saturate_cast(detH * o.scale)); -// } - -// float relScale() {return (factor / octave.scale); } -// float srScale() {return (factor / octave.scale * shrinkage); } - }; - -// struct Integral -// { -// cv::Mat magnitude; -// std::vector hist; -// cv::Mat luv; - -// Integral(cv::Mat m, std::vector h, cv::Mat l) : magnitude(m), hist(h), luv(l) {} -// }; } struct cv::SoftCascade::Filds @@ -240,44 +223,70 @@ struct cv::SoftCascade::Filds // } // } + typedef std::vector::iterator octIt_t; + + octIt_t fitOctave(const float& logFactor) + { + float minAbsLog = FLT_MAX; + octIt_t res = octaves.begin(); + for (octIt_t oct = octaves.begin(); oct < octaves.end(); ++oct) + { + const Octave& octave =*oct; + float logOctave = log(octave.scale); + float logAbsScale = fabs(logFactor - logOctave); + + if(logAbsScale < minAbsLog) + { + res = oct; + minAbsLog = logAbsScale; + } + } + return res; + } + // compute levels of full pyramid void calcLevels(int frameW, int frameH, int scales) { CV_Assert(scales > 1); levels.clear(); - // float logFactor = (log(maxScale) - log(minScale)) / (scales -1); + float logFactor = (log(maxScale) - log(minScale)) / (scales -1); - // float scale = minScale; - // for (int sc = 0; sc < scales; ++sc) - // { - // Level level(sc, scale, log(scale), std::max(0.0f, frameW - (origObjWidth * scale)), std::max(0.0f, frameH - (origObjHeight * scale))); - // if (!level.width || !level.height) - // break; - // else - // levels.push_back(level); + float scale = minScale; + for (int sc = 0; sc < scales; ++sc) + { + int width = std::max(0.0f, frameW - (origObjWidth * scale)); + int height = std::max(0.0f, frameH - (origObjHeight * scale)); - // if (fabs(scale - maxScale) < FLT_EPSILON) break; - // scale = std::min(maxScale, expf(log(scale) + logFactor)); - // } - - // for (std::vector::iterator level = levels.begin(); level < levels.end(); ++level) - // { - // float minAbsLog = FLT_MAX; - // for (std::vector::iterator oct = octaves.begin(); oct < octaves.end(); ++oct) - // { - // const Octave& octave =*oct; - // float logOctave = log(octave.scale); - // float logAbsScale = fabs((*level).logFactor - logOctave); + float logScale = log(scale); + octIt_t fit = fitOctave(logScale); - // if(logAbsScale < minAbsLog) - // { - // printf("######### %f %f %f %f\n", octave.scale, logOctave, logAbsScale, (*level).logFactor); - // minAbsLog = logAbsScale; - // (*level).assign(octave, ORIG_OBJECT_WIDTH, ORIG_OBJECT_HEIGHT); - // } - // } - // } + Level level(*fit, scale, shrinkage, width, height); + + if (!width || !height) + break; + else + levels.push_back(level); + + if (fabs(scale - maxScale) < FLT_EPSILON) break; + scale = std::min(maxScale, expf(log(scale) + logFactor)); + + // std::cout << "level scale " + // << levels[sc].origScale + // << " octeve " + // << levels[sc].octave->scale + // << " " + // << levels[sc].relScale + // << " " << levels[sc].shrScale + // << " [" << levels[sc].objSize.width + // << " " << levels[sc].objSize.height << "] [" + // << levels[sc].workRect.width << " " << levels[sc].workRect.height << std::endl; + } + + return; + + + std::cout << std::endl << std::endl << std::endl; } bool fill(const FileNode &root, const float mins, const float maxs) @@ -474,9 +483,6 @@ namespace { cv::cvtColor(colored, grey, CV_RGB2GRAY); calcHistBins(grey, magnitude, hog, HOG_BINS, shrinkage); - std::cout << magnitude.cols << " " << magnitude.rows << std::endl; - cv::imshow("1", magnitude); - cv::waitKey(0); } }; } From 8d90b973b0517cfbc1cc2a568a6b10bd5f4d906f Mon Sep 17 00:00:00 2001 From: "marina.kolpakova" Date: Thu, 13 Sep 2012 21:19:01 +0400 Subject: [PATCH 16/91] add detectAt to soft cascade --- modules/objdetect/src/softcascade.cpp | 239 ++++++++++++++------------ 1 file changed, 130 insertions(+), 109 deletions(-) diff --git a/modules/objdetect/src/softcascade.cpp b/modules/objdetect/src/softcascade.cpp index 8dfe14b6a..6e8c6ee36 100644 --- a/modules/objdetect/src/softcascade.cpp +++ b/modules/objdetect/src/softcascade.cpp @@ -66,6 +66,8 @@ struct Octave size(cvRound(origObjSize.width * scale), cvRound(origObjSize.height * scale)), shrinkage((int)fn[SC_OCT_SHRINKAGE]) {} + + int index() const {return (int)log(scale);} }; const char *const Octave::SC_OCT_SCALE = "scale"; @@ -182,6 +184,89 @@ struct Level // {1, 2, 1, 2} // }; + +void calcHistBins(const cv::Mat& grey, cv::Mat& magIntegral, std::vector& histInts, + const int bins, int shrinkage) +{ + CV_Assert( grey.type() == CV_8U); + + float scale = 1.f / shrinkage; + + const int rows = grey.rows + 1; + const int cols = grey.cols + 1; + cv::Size intSumSize(cols, rows); + + histInts.clear(); + std::vector hist; + for (int bin = 0; bin < bins; ++bin) + { + hist.push_back(cv::Mat(rows, cols, CV_32FC1)); + } + + cv::Mat df_dx, df_dy, mag, angle; + cv::Sobel(grey, df_dx, CV_32F, 1, 0); + cv::Sobel(grey, df_dy, CV_32F, 0, 1); + + cv::cartToPolar(df_dx, df_dy, mag, angle, true); + + const float magnitudeScaling = 1.0 / sqrt(2); + mag *= magnitudeScaling; + angle /= 60; + + for (int h = 0; h < mag.rows; ++h) + { + float* magnitude = mag.ptr(h); + float* ang = angle.ptr(h); + + for (int w = 0; w < mag.cols; ++w) + { + hist[(int)ang[w]].ptr(h)[w] = magnitude[w]; + } + } + + for (int bin = 0; bin < bins; ++bin) + { + cv::Mat shrunk, sum; + cv::resize(hist[bin], shrunk, cv::Size(), scale, scale, cv::INTER_AREA); + cv::integral(shrunk, sum); + histInts.push_back(sum); + } + + cv::Mat shrMag; + cv::resize(mag, shrMag, cv::Size(), scale, scale, cv::INTER_AREA); + + cv::integral(shrMag, magIntegral, mag.depth()); +} + +struct ChannelStorage +{ + std::vector hog; + cv::Mat magnitude; + cv::Mat luv; + + int shrinkage; + + enum {HOG_BINS = 6}; + + ChannelStorage() {} + ChannelStorage(const cv::Mat& colored, int shr) : shrinkage(shr) + { + cv::Mat _luv; + cv::cvtColor(colored, _luv, CV_BGR2Luv); + + cv::integral(luv, luv); + + cv::Mat grey; + cv::cvtColor(colored, grey, CV_RGB2GRAY); + + calcHistBins(grey, magnitude, hog, HOG_BINS, shrinkage); + } + + float get(int chennel, cv::Rect area) const + { + return 1.f; + } +}; } struct cv::SoftCascade::Filds @@ -203,28 +288,38 @@ struct cv::SoftCascade::Filds std::vector levels; - // typedef std::vector::iterator stIter_t; - - // // carrently roi must be save for out of ranges. - // void detectInRoi(const cv::Rect& roi, const Integral& ints, std::vector& objects, const int step) - // { - // for (int dy = roi.y; dy < roi.height; dy+=step) - // for (int dx = roi.x; dx < roi.width; dx += step) - // { - // applyCascade(ints, dx, dy); - // } - // } - - // void applyCascade(const Integral& ints, const int x, const int y) - // { - // for (stIter_t sIt = stages.begin(); sIt != stages.end(); ++sIt) - // { - // Stage& stage = *sIt; - // } - // } - typedef std::vector::iterator octIt_t; + void detectAt(const Level& level, const int dx, const int dy, const ChannelStorage& storage, + const std::vector& detections) const + { + float detectionScore = 0.f; + + const Octave& octave = *(level.octave); + int stBegin = octave.index() * octave.stages, stEnd = stBegin + octave.stages; + for(int st = stBegin; st < stEnd; ++st) + { + const Stage& stage = stages[st]; + if (detectionScore > stage.threshold) + { + int nId = st * 3; + const Node& node = nodes[nId]; + const Feature& feature = features[node.feature]; + + float sum = storage.get(feature.channel, feature.rect); + int next = (sum >= node.threshold)? 2 : 1; + + const Node& leaf = nodes[nId + next]; + const Feature& fLeaf = features[node.feature]; + sum = storage.get(feature.channel, feature.rect); + + int lShift = (next - 1) * 2 + (sum >= leaf.threshold) ? 1 : 0; + float impact = leaves[nId + lShift]; + detectionScore += impact; + } + } + } + octIt_t fitOctave(const float& logFactor) { float minAbsLog = FLT_MAX; @@ -407,90 +502,9 @@ bool cv::SoftCascade::load( const string& filename, const float minScale, const return true; } -namespace { - - void calcHistBins(const cv::Mat& grey, cv::Mat& magIntegral, std::vector& histInts, const int bins, int shrinkage) - { - CV_Assert( grey.type() == CV_8U); - - float scale = 1.f / shrinkage; - - const int rows = grey.rows + 1; - const int cols = grey.cols + 1; - cv::Size intSumSize(cols, rows); - - histInts.clear(); - std::vector hist; - for (int bin = 0; bin < bins; ++bin) - { - hist.push_back(cv::Mat(rows, cols, CV_32FC1)); - } - - cv::Mat df_dx, df_dy, mag, angle; - cv::Sobel(grey, df_dx, CV_32F, 1, 0); - cv::Sobel(grey, df_dy, CV_32F, 0, 1); - - cv::cartToPolar(df_dx, df_dy, mag, angle, true); - - const float magnitudeScaling = 1.0 / sqrt(2); - mag *= magnitudeScaling; - angle /= 60; - - for (int h = 0; h < mag.rows; ++h) - { - float* magnitude = mag.ptr(h); - float* ang = angle.ptr(h); - - for (int w = 0; w < mag.cols; ++w) - { - hist[(int)ang[w]].ptr(h)[w] = magnitude[w]; - } - } - - for (int bin = 0; bin < bins; ++bin) - { - cv::Mat shrunk, sum; - cv::resize(hist[bin], shrunk, cv::Size(), scale, scale, cv::INTER_AREA); - cv::integral(shrunk, sum); - histInts.push_back(sum); - } - - cv::Mat shrMag; - cv::resize(mag, shrMag, cv::Size(), scale, scale, cv::INTER_AREA); - - cv::integral(shrMag, magIntegral, mag.depth()); - } - - struct ChannelStorage - { - std::vector hog; - cv::Mat luv; - cv::Mat magnitude; - - int shrinkage; - - enum {HOG_BINS = 6}; - - ChannelStorage() {} - ChannelStorage(const cv::Mat& colored, int shr) : shrinkage(shr) - { - cv::Mat _luv; - cv::cvtColor(colored, _luv, CV_BGR2Luv); - - cv::integral(luv, luv); - - cv::Mat grey; - cv::cvtColor(colored, grey, CV_RGB2GRAY); - - calcHistBins(grey, magnitude, hog, HOG_BINS, shrinkage); - } - }; -} - - - -void cv::SoftCascade::detectMultiScale(const Mat& image, const std::vector& rois, std::vector& objects, - const int step, const int rejectfactor)// add step scaling +void cv::SoftCascade::detectMultiScale(const Mat& image, const std::vector& rois, + std::vector& objects, + const int step, const int rejectfactor) { typedef std::vector::const_iterator RIter_t; // only color images are supperted @@ -506,10 +520,17 @@ void cv::SoftCascade::detectMultiScale(const Mat& image, const std::vector detections; + typedef std::vector::const_iterator lIt; + for (lIt it = fld.levels.begin(); it != fld.levels.end(); ++it) + { + const Level& level = *it; + for (int dy = 0; dy < level.workRect.height; ++dy) + for (int dx = 0; dx < level.workRect.width; ++dx) + fld.detectAt(level, dx, dy, storage, detections); + } + + std::swap(detections, objects); } \ No newline at end of file From ba27d89173d253cbcc34671bffda31ea450328c8 Mon Sep 17 00:00:00 2001 From: "marina.kolpakova" Date: Fri, 14 Sep 2012 19:22:08 +0400 Subject: [PATCH 17/91] add feature rescaling according to Dollal's paper FPDW --- modules/objdetect/src/softcascade.cpp | 196 ++++++++++++++++++-------- 1 file changed, 134 insertions(+), 62 deletions(-) diff --git a/modules/objdetect/src/softcascade.cpp b/modules/objdetect/src/softcascade.cpp index 6e8c6ee36..64620fe2c 100644 --- a/modules/objdetect/src/softcascade.cpp +++ b/modules/objdetect/src/softcascade.cpp @@ -1,31 +1,31 @@ /*M/////////////////////////////////////////////////////////////////////////////////////// // -// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. // -// By downloading, copying, installing or using the software you agree to this license. -// If you do not agree to this license, do not download, install, -// copy or use the software. +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. // // -// License Agreement -// For Open Source Computer Vision Library +// License Agreement +// For Open Source Computer Vision Library // // Copyright (C) 2000-2008, Intel Corporation, all rights reserved. -// Copyright (C) 2008-2011, Willow Garage Inc., all rights reserved. +// Copyright (C) 2008-2012, Willow Garage Inc., all rights reserved. // Third party copyrights are property of their respective owners. // // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: // -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. // -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. // -// * The name of the copyright holders may not be used to endorse or promote products -// derived from this software without specific prior written permission. +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. // // This software is provided by the copyright holders and contributors "as is" and // any express or implied warranties, including, but not limited to, the implied @@ -37,6 +37,7 @@ // and on any theory of liability, whether in contract, strict liability, // or tort (including negligence or otherwise) arising in any way out of // the use of this software, even if advised of the possibility of such damage. +// //M*/ #include @@ -137,6 +138,43 @@ struct Level workRect(cv::Size(cvRound(w / (float)shrinkage),cvRound(h / (float)shrinkage))), objSize(cv::Size(cvRound(oct.size.width * relScale), cvRound(oct.size.height * relScale))) {} + + void markDetection(const int x, const int dx, std::vector& detections) const + { + + } +}; + + +struct CascadeIntrinsics +{ + static const float lambda = 1.099f, a = 0.89f; + + static float getFor(int channel, float scaling) + { + CV_Assert(channel < 10); + + if ((scaling - 1.f) < FLT_EPSILON) + return 1.f; + + // according to R. Benenson, M. Mathias, R. Timofte and L. Van Gool paper + static const float A[2][2] = + { //channel <= 6, otherwise + { 0.89f, 1.f}, // down + { 1.00f, 1.f} // up + }; + + static const float B[2][2] = + { //channel <= 6, otherwise + { 1.099f / log(2), 2.f}, // down + { 2.f, 2.f} // up + }; + + float a = A[(int)(scaling >= 1)][(int)(channel >= 6)]; + float b = B[(int)(scaling >= 1)][(int)(channel >= 6)]; + + return a * pow(scaling, b); + } }; // Feature rescale(float relScale) @@ -148,42 +186,6 @@ struct Level // return res; // } -// // according to R. Benenson, M. Mathias, R. Timofte and L. Van Gool paper -// struct CascadeIntrinsics -// { -// static const float lambda = 1.099f, a = 0.89f; -// static const float intrinsics[10][4]; - -// static float getFor(int channel, float scaling) -// { -// CV_Assert(channel < 10); - -// if ((scaling - 1.f) < FLT_EPSILON) -// return 1.f; - -// int ud = (int)(scaling < 1.f); -// return intrinsics[channel][(ud << 1)] * pow(scaling, intrinsics[channel][(ud << 1) + 1]); -// } - -// }; - -// const float CascadeIntrinsics::intrinsics[10][4] = -// { //da, db, ua, ub -// // hog-like orientation bins -// {a, lambda / log(2), 1, 2}, -// {a, lambda / log(2), 1, 2}, -// {a, lambda / log(2), 1, 2}, -// {a, lambda / log(2), 1, 2}, -// {a, lambda / log(2), 1, 2}, -// {a, lambda / log(2), 1, 2}, -// // gradient magnitude -// {a, lambda / log(2), 1, 2}, -// // luv color channels -// {1, 2, 1, 2}, -// {1, 2, 1, 2}, -// {1, 2, 1, 2} -// }; - void calcHistBins(const cv::Mat& grey, cv::Mat& magIntegral, std::vector& histInts, const int bins, int shrinkage) @@ -236,6 +238,7 @@ void calcHistBins(const cv::Mat& grey, cv::Mat& magIntegral, std::vector splited; + split(luv, splited); cv::Mat grey; cv::cvtColor(colored, grey, CV_RGB2GRAY); calcHistBins(grey, magnitude, hog, HOG_BINS, shrinkage); + + hog.insert(hog.end(), splited.begin(), splited.end()); } - float get(int chennel, cv::Rect area) const + float get(const int x, const int y, const int channel, const cv::Rect& area) const { - return 1.f; + CV_Assert(channel < HOG_LUV_BINS); + + const cv::Mat m = hog[channel]; + + float a = m.ptr(y + area.y)[x + area.x]; + float b = m.ptr(y + area.y)[x + area.width]; + float c = m.ptr(y + area.height)[x + area.width]; + float d = m.ptr(y + area.height)[x + area.x]; + + return (a - b + c - d); } }; } @@ -291,33 +309,87 @@ struct cv::SoftCascade::Filds typedef std::vector::iterator octIt_t; void detectAt(const Level& level, const int dx, const int dy, const ChannelStorage& storage, - const std::vector& detections) const + std::vector& detections) const { float detectionScore = 0.f; const Octave& octave = *(level.octave); int stBegin = octave.index() * octave.stages, stEnd = stBegin + octave.stages; - for(int st = stBegin; st < stEnd; ++st) + int st = stBegin; + for(; st < stEnd; ++st) { const Stage& stage = stages[st]; - if (detectionScore > stage.threshold) { int nId = st * 3; + + // work with root node const Node& node = nodes[nId]; const Feature& feature = features[node.feature]; - float sum = storage.get(feature.channel, feature.rect); - int next = (sum >= node.threshold)? 2 : 1; + // rescaling + float scaling = CascadeIntrinsics::getFor(feature.channel, level.relScale); + cv::Rect scaledRect = feature.rect; + float farea = (scaledRect.width - scaledRect.x) * (scaledRect.height - scaledRect.y); + // rescale + scaledRect.x = cvRound(scaling * scaledRect.x); + scaledRect.y = cvRound(scaling * scaledRect.y); + scaledRect.width = cvRound(scaling * scaledRect.width); + scaledRect.height = cvRound(scaling * scaledRect.height); + float sarea = (scaledRect.width - scaledRect.x) * (scaledRect.height - scaledRect.y); + + float approx = 1.f; + if ((farea - 0.f) > FLT_EPSILON && (farea - 0.f) > FLT_EPSILON) + { + const float expected_new_area = farea*level.relScale*level.relScale; + approx = expected_new_area / sarea; + } + + float rootThreshold = node.threshold / approx; // ToDo check + rootThreshold *= scaling; + + // use rescaled + float sum = storage.get(dx, dy, feature.channel, scaledRect); + int next = (sum >= rootThreshold)? 2 : 1; + + // leaces const Node& leaf = nodes[nId + next]; const Feature& fLeaf = features[node.feature]; - sum = storage.get(feature.channel, feature.rect); - int lShift = (next - 1) * 2 + (sum >= leaf.threshold) ? 1 : 0; + // rescaling + scaling = CascadeIntrinsics::getFor(fLeaf.channel, level.relScale); + scaledRect = fLeaf.rect; + farea = (scaledRect.width - scaledRect.x) * (scaledRect.height - scaledRect.y); + // rescale + scaledRect.x = cvRound(scaling * scaledRect.x); + scaledRect.y = cvRound(scaling * scaledRect.y); + scaledRect.width = cvRound(scaling * scaledRect.width); + scaledRect.height = cvRound(scaling * scaledRect.height); + + sarea = (scaledRect.width - scaledRect.x) * (scaledRect.height - scaledRect.y); + + approx = 1.f; + if ((farea - 0.f) > FLT_EPSILON && (farea - 0.f) > FLT_EPSILON) + { + const float expected_new_area = farea*level.relScale*level.relScale; + approx = expected_new_area / sarea; + } + + rootThreshold = leaf.threshold / approx; // ToDo check + rootThreshold *= scaling; + + sum = storage.get(dx, dy, feature.channel, scaledRect); + + int lShift = (next - 1) * 2 + (sum >= rootThreshold) ? 1 : 0; float impact = leaves[nId + lShift]; detectionScore += impact; } + + if (detectionScore <= stage.threshold) break; } + + if (st == octave.stages - 1) + level.markDetection(dx, dy, detections); } octIt_t fitOctave(const float& logFactor) From 765dea9ddf50ec1b47e68802665642cdd27496a5 Mon Sep 17 00:00:00 2001 From: "marina.kolpakova" Date: Wed, 19 Sep 2012 09:31:02 +0400 Subject: [PATCH 18/91] fix bugs in the soft cascade detect method; add options for debug logging - WITH_DEBUG_OUT for logging cascade scales - DEBUG_STORE_IMAGES for xml matrix serialization - DEBUG_SHOW_RESULT to see detection result --- .../include/opencv2/objdetect/objdetect.hpp | 2 +- modules/objdetect/src/softcascade.cpp | 565 +++++++++++++----- modules/objdetect/test/test_softcascade.cpp | 2 +- 3 files changed, 421 insertions(+), 148 deletions(-) diff --git a/modules/objdetect/include/opencv2/objdetect/objdetect.hpp b/modules/objdetect/include/opencv2/objdetect/objdetect.hpp index 97d6122fe..bb4240f59 100644 --- a/modules/objdetect/include/opencv2/objdetect/objdetect.hpp +++ b/modules/objdetect/include/opencv2/objdetect/objdetect.hpp @@ -512,7 +512,7 @@ public: //! return vector of bounding boxes. Each box contains one detected object virtual void detectMultiScale(const Mat& image, const std::vector& rois, std::vector& objects, - int step = 4, int rejectfactor = 1); + int rejectfactor = 1); protected: enum { BOOST = 0 }; diff --git a/modules/objdetect/src/softcascade.cpp b/modules/objdetect/src/softcascade.cpp index 64620fe2c..9e1c550d7 100644 --- a/modules/objdetect/src/softcascade.cpp +++ b/modules/objdetect/src/softcascade.cpp @@ -47,11 +47,23 @@ #include #include #include +#include +#include namespace { +char *itoa(long i, char* s, int /*dummy_radix*/) +{ + sprintf(s, "%ld", i); + return s; +} + +// used for noisy printfs +// #define WITH_DEBUG_OUT + struct Octave { + int index; float scale; int stages; cv::Size size; @@ -61,21 +73,17 @@ struct Octave static const char *const SC_OCT_STAGES; static const char *const SC_OCT_SHRINKAGE; - Octave() : scale(0), stages(0), size(cv::Size()), shrinkage(0) {} - Octave(cv::Size origObjSize, const cv::FileNode& fn) - : scale((float)fn[SC_OCT_SCALE]), stages((int)fn[SC_OCT_STAGES]), + Octave(const int i, cv::Size origObjSize, const cv::FileNode& fn) + : index(i), scale((float)fn[SC_OCT_SCALE]), stages((int)fn[SC_OCT_STAGES]), size(cvRound(origObjSize.width * scale), cvRound(origObjSize.height * scale)), shrinkage((int)fn[SC_OCT_SHRINKAGE]) {} - - int index() const {return (int)log(scale);} }; const char *const Octave::SC_OCT_SCALE = "scale"; const char *const Octave::SC_OCT_STAGES = "stageNum"; const char *const Octave::SC_OCT_SHRINKAGE = "shrinkingFactor"; - struct Stage { float threshold; @@ -94,10 +102,10 @@ struct Node float threshold; Node(){} - Node(cv::FileNodeIterator& fIt) : feature((int)(*(fIt +=2)++)), threshold((float)(*(fIt++))){} + Node(const int offset, cv::FileNodeIterator& fIt) + : feature((int)(*(fIt +=2)++) + offset), threshold((float)(*(fIt++))){} }; - struct Feature { int channel; @@ -112,40 +120,48 @@ struct Feature cv::FileNode rn = fn[SC_F_RECT]; cv::FileNodeIterator r_it = rn.end(); rect = cv::Rect(*(--r_it), *(--r_it), *(--r_it), *(--r_it)); - // std::cout << "feature: " << rect.x << " " << rect.y << " " << rect.width - //<< " " << rect.height << " " << channel << std::endl; } }; const char * const Feature::SC_F_CHANNEL = "channel"; const char * const Feature::SC_F_RECT = "rect"; +struct Object +{ + enum Class{PEDESTRIAN}; + cv::Rect rect; + float confidence; + Class detType; + + Object(const cv::Rect& r, const float c, Class dt = PEDESTRIAN) : rect(r), confidence(c), detType(dt) {} +}; + struct Level { const Octave* octave; float origScale; float relScale; - float shrScale; + float shrScale; // used for marking detection cv::Size workRect; cv::Size objSize; - - // TiDo not reounding Level(const Octave& oct, const float scale, const int shrinkage, const int w, const int h) - : octave(&oct), origScale(scale), relScale(scale / oct.scale), shrScale (relScale / shrinkage), + : octave(&oct), origScale(scale), relScale(scale / oct.scale), shrScale (relScale / (float)shrinkage), workRect(cv::Size(cvRound(w / (float)shrinkage),cvRound(h / (float)shrinkage))), objSize(cv::Size(cvRound(oct.size.width * relScale), cvRound(oct.size.height * relScale))) {} - void markDetection(const int x, const int dx, std::vector& detections) const + void markDetection(const int x, const int y, float confidence, std::vector& detections) const { + int shrinkage = (*octave).shrinkage; + cv::Rect rect(cvRound(x * shrinkage), cvRound(y * shrinkage), objSize.width, objSize.height); + detections.push_back(Object(rect, confidence)); } }; - struct CascadeIntrinsics { static const float lambda = 1.099f, a = 0.89f; @@ -157,7 +173,7 @@ struct CascadeIntrinsics if ((scaling - 1.f) < FLT_EPSILON) return 1.f; - // according to R. Benenson, M. Mathias, R. Timofte and L. Van Gool paper + // according to R. Benenson, M. Mathias, R. Timofte and L. Van Gool's and Dallal's papers static const float A[2][2] = { //channel <= 6, otherwise { 0.89f, 1.f}, // down @@ -167,77 +183,164 @@ struct CascadeIntrinsics static const float B[2][2] = { //channel <= 6, otherwise { 1.099f / log(2), 2.f}, // down - { 2.f, 2.f} // up + { 0.f, 2.f} // up }; - float a = A[(int)(scaling >= 1)][(int)(channel >= 6)]; - float b = B[(int)(scaling >= 1)][(int)(channel >= 6)]; + float a = A[(int)(scaling >= 1)][(int)(channel > 6)]; + float b = B[(int)(scaling >= 1)][(int)(channel > 6)]; +#if defined WITH_DEBUG_OUT + printf("scaling: %f %f %f %f\n", scaling, a, b, a * pow(scaling, b)); +#endif return a * pow(scaling, b); } }; -// Feature rescale(float relScale) -// { -// Feature res(*this); -// res.rect = cv::Rect (cvRound(rect.x * relScale), cvRound(rect.y * relScale), -// cvRound(rect.width * relScale), cvRound(rect.height * relScale)); -// res.threshold = threshold * CascadeIntrinsics::getFor(channel, relScale); -// return res; -// } +int qangle6(float dfdx, float dfdy) +{ + static const float vectors[6][2] = + { + {std::cos(0), std::sin(0) }, + {std::cos(M_PI / 6.f), std::sin(M_PI / 6.f) }, + {std::cos(M_PI / 3.f), std::sin(M_PI / 3.f) }, + {std::cos(M_PI / 2.f), std::sin(M_PI / 2.f) }, + {std::cos(2.f * M_PI / 3.f), std::sin(2.f * M_PI / 3.f)}, + {std::cos(5.f * M_PI / 6.f), std::sin(5.f * M_PI / 6.f)} + }; + + int index = 0; + + float dot = fabs(dfdx * vectors[0][0] + dfdy * vectors[0][1]); + + for(int i = 1; i < 6; ++i) + { + const float curr = fabs(dfdx * vectors[i][0] + dfdy * vectors[i][1]); + + if(curr > dot) + { + dot = curr; + index = i; + } + } + + return index; +} + +//ToDo void calcHistBins(const cv::Mat& grey, cv::Mat& magIntegral, std::vector& histInts, const int bins, int shrinkage) { + static const float magnitudeScaling = 1.f / sqrt(2); + CV_Assert( grey.type() == CV_8U); float scale = 1.f / shrinkage; const int rows = grey.rows + 1; const int cols = grey.cols + 1; - cv::Size intSumSize(cols, rows); + + cv::Mat df_dx(grey.rows, grey.cols, CV_32F), + df_dy(grey.rows, grey.cols, CV_32F), mag, angle; + // cv::Sobel(grey, df_dx, CV_32F, 1, 0); + // cv::Sobel(grey, df_dy, CV_32F, 0, 1); + + for (int y = 1; y < grey.rows -1; ++y) + { + float* dx = df_dx.ptr(y); + float* dy = df_dy.ptr(y); + + const uchar* gr = grey.ptr(y); + const uchar* gr_down = grey.ptr(y - 1); + const uchar* gr_up = grey.ptr(y + 1); + for (int x = 1; x < grey.cols - 1; ++x) + { + float dx_a = gr[x + 1]; + float dx_b = gr[x - 1]; + dx[x] = dx_a - dx_b; + + float dy_a = gr_up[x]; + float dy_b = gr_down[x]; + dy[x] = dy_a - dy_b; + } + } + + cv::cartToPolar(df_dx, df_dy, mag, angle, true); + + mag *= magnitudeScaling; + + cv::Mat saturatedMag(grey.rows, grey.cols, CV_8UC1); + for (int y = 0; y < grey.rows; ++y) + { + float* rm = mag.ptr(y); + uchar* mg = saturatedMag.ptr(y); + for (int x = 0; x < grey.cols; ++x) + { + mg[x] = cv::saturate_cast(rm[x]); + } + } + + mag = saturatedMag; histInts.clear(); std::vector hist; for (int bin = 0; bin < bins; ++bin) { - hist.push_back(cv::Mat(rows, cols, CV_32FC1)); + hist.push_back(cv::Mat(rows, cols, CV_8UC1)); } - cv::Mat df_dx, df_dy, mag, angle; - cv::Sobel(grey, df_dx, CV_32F, 1, 0); - cv::Sobel(grey, df_dy, CV_32F, 0, 1); - - cv::cartToPolar(df_dx, df_dy, mag, angle, true); - - const float magnitudeScaling = 1.0 / sqrt(2); - mag *= magnitudeScaling; - angle /= 60; - - for (int h = 0; h < mag.rows; ++h) + for (int h = 0; h < saturatedMag.rows; ++h) { - float* magnitude = mag.ptr(h); - float* ang = angle.ptr(h); + uchar* magnitude = saturatedMag.ptr(h); + float* dfdx = df_dx.ptr(h); + float* dfdy = df_dy.ptr(h); - for (int w = 0; w < mag.cols; ++w) + for (int w = 0; w < saturatedMag.cols; ++w) { - hist[(int)ang[w]].ptr(h)[w] = magnitude[w]; + hist[ qangle6(dfdx[w], dfdy[w]) ].ptr(h)[w] = magnitude[w]; } } + angle /= 60; + + + // for (int h = 0; h < saturatedMag.rows; ++h) + // { + // uchar* magnitude = saturatedMag.ptr(h); + // float* ang = angle.ptr(h); + + // for (int w = 0; w < saturatedMag.cols; ++w) + // { + // hist[ (int)ang[w] ].ptr(h)[w] = magnitude[w]; + // } + // } + char buffer[33]; + for (int bin = 0; bin < bins; ++bin) { cv::Mat shrunk, sum; + cv::imshow(std::string("hist[bin]") + itoa(bin, buffer, 10), hist[bin]); cv::resize(hist[bin], shrunk, cv::Size(), scale, scale, cv::INTER_AREA); + cv::imshow(std::string("shrunk") + itoa(bin, buffer, 10), shrunk); cv::integral(shrunk, sum); + cv::imshow(std::string("sum") + itoa(bin, buffer, 10), sum); histInts.push_back(sum); + + // std::cout << shrunk << std::endl << std::endl; } cv::Mat shrMag; + cv::imshow("mag", mag); cv::resize(mag, shrMag, cv::Size(), scale, scale, cv::INTER_AREA); + cv::FileStorage fs("/home/kellan/actualChannels.xml", cv::FileStorage::WRITE); + cv::imshow("shrunk_channel", shrMag); + fs << "shrunk_channel6" << shrMag; + + // cv::imshow("shrMag", shrMag); cv::integral(shrMag, magIntegral, mag.depth()); + // cv::imshow("magIntegral", magIntegral); histInts.push_back(magIntegral); } @@ -252,39 +355,92 @@ struct ChannelStorage enum {HOG_BINS = 6, HOG_LUV_BINS = 10}; ChannelStorage() {} - ChannelStorage(const cv::Mat& colored, int shr) : shrinkage(shr) + ChannelStorage(cv::Mat& colored, int shr) : shrinkage(shr) { - cv::Mat _luv, shrLuv; - cv::cvtColor(colored, _luv, CV_BGR2Luv); - cv::resize(_luv, shrLuv, cv::Size(), 1.f / shr, 1.f / shr, cv::INTER_AREA); + hog.clear(); + cv::FileStorage fs("/home/kellan/testInts.xml", cv::FileStorage::READ); + char buff[33]; + float scale = 1.f / shrinkage; + for(int i = 0; i < 10; ++i) + { + cv::Mat channel; + fs[std::string("channel") + itoa(i, buff, 10)] >> channel; - cv::integral(shrLuv, luv); - - std::vector splited; - split(luv, splited); - - cv::Mat grey; - cv::cvtColor(colored, grey, CV_RGB2GRAY); - - calcHistBins(grey, magnitude, hog, HOG_BINS, shrinkage); - - hog.insert(hog.end(), splited.begin(), splited.end()); + cv::Mat shrunk, sum; + // cv::resize(channel, shrunk, cv::Size(), scale, scale, cv::INTER_AREA); + // cv::imshow(std::string("channel") + itoa(i, buff, 10), shrunk); + // cv::waitKey(0); + // cv::integral(channel, sum); + // if (i == 1) + // std::cout << channel << std::endl; + hog.push_back(channel); + } + // exit(1); } + // { + // // add gauss + // cv::Mat gauss; + // cv::GaussianBlur(colored, gauss, cv::Size(3,3), 0 ,0); + + // colored = gauss; + // // cv::imshow("colored", colored); + + // cv::Mat _luv, shrLuv; + // cv::cvtColor(colored, _luv, CV_BGR2Luv); + + // // cv::imshow("_luv", _luv); + + // cv::resize(_luv, shrLuv, cv::Size(), 1.f / shr, 1.f / shr, cv::INTER_AREA); + + // // cv::imshow("shrLuv", shrLuv); + + // cv::integral(shrLuv, luv); + + // // cv::imshow("luv", luv); + + // std::vector splited; + // split(luv, splited); + + // char buffer[33]; + + // for (int i = 0; i < (int)splited.size(); i++) + // { + // // cv::imshow(itoa(i,buffer,10), splited[i]); + // } + + // cv::Mat grey; + // cv::cvtColor(colored, grey, CV_RGB2GRAY); + + // // cv::imshow("grey", grey); + + // calcHistBins(grey, magnitude, hog, HOG_BINS, shrinkage); + + // hog.insert(hog.end(), splited.begin(), splited.end()); + // } float get(const int x, const int y, const int channel, const cv::Rect& area) const { CV_Assert(channel < HOG_LUV_BINS); - const cv::Mat m = hog[channel]; - float a = m.ptr(y + area.y)[x + area.x]; - float b = m.ptr(y + area.y)[x + area.width]; - float c = m.ptr(y + area.height)[x + area.width]; - float d = m.ptr(y + area.height)[x + area.x]; +#if defined WITH_DEBUG_OUT + printf("feature box %d %d %d %d ", area.x, area.y, area.width, area.height); + printf("get for channel %d\n", channel); + printf("!! %d\n", m.depth()); +#endif + int a = m.ptr(y + area.y)[x + area.x]; + int b = m.ptr(y + area.y)[x + area.width]; + int c = m.ptr(y + area.height)[x + area.width]; + int d = m.ptr(y + area.height)[x + area.x]; + +#if defined WITH_DEBUG_OUT + printf(" retruved integral values: %d %d %d %d\n", a, b, c, d); +#endif return (a - b + c - d); } }; + } struct cv::SoftCascade::Filds @@ -299,25 +455,91 @@ struct cv::SoftCascade::Filds std::vector octaves; std::vector stages; - std::vector nodes; - std::vector leaves; - + std::vector nodes; + std::vector leaves; std::vector features; std::vector levels; typedef std::vector::iterator octIt_t; - void detectAt(const Level& level, const int dx, const int dy, const ChannelStorage& storage, - std::vector& detections) const + float rescale(const Feature& feature, const float relScale, cv::Rect& scaledRect, const float threshold) const { + float scaling = CascadeIntrinsics::getFor(feature.channel, relScale); + scaledRect = feature.rect; + +#if defined WITH_DEBUG_OUT + printf("feature %d box %d %d %d %d\n", feature.channel, scaledRect.x, scaledRect.y, + scaledRect.width, scaledRect.height); + + std::cout << "rescale: " << feature.channel << " " << relScale << " " << scaling << std::endl; +#endif + + float farea = (scaledRect.width - scaledRect.x) * (scaledRect.height - scaledRect.y); + // rescale + scaledRect.x = cvRound(relScale * scaledRect.x); + scaledRect.y = cvRound(relScale * scaledRect.y); + scaledRect.width = cvRound(relScale * scaledRect.width); + scaledRect.height = cvRound(relScale * scaledRect.height); + +#if defined WITH_DEBUG_OUT + printf("feature %d box %d %d %d %d\n", feature.channel, scaledRect.x, scaledRect.y, + scaledRect.width, scaledRect.height); + + std::cout << " new rect: " << scaledRect.x << " " << scaledRect.y + << " " << scaledRect.width << " " << scaledRect.height << " "; +#endif + + float sarea = (scaledRect.width - scaledRect.x) * (scaledRect.height - scaledRect.y); + + float approx = 1.f; + if ((farea - 0.f) > FLT_EPSILON && (farea - 0.f) > FLT_EPSILON) + { + const float expected_new_area = farea * relScale * relScale; + approx = expected_new_area / sarea; + +#if defined WITH_DEBUG_OUT + std::cout << " rel areas " << expected_new_area << " " << sarea << std::endl; +#endif + + } + + // compensation areas rounding + float rootThreshold = threshold / approx;/ + rootThreshold *= scaling; + +#if defined WITH_DEBUG_OUT + std::cout << "approximation " << approx << " " << threshold << " -> " << rootThreshold + << " " << scaling << std::endl; +#endif + + return rootThreshold; + } + + void detectAt(const Level& level, const int dx, const int dy, const ChannelStorage& storage, + std::vector& detections) const + { +#if defined WITH_DEBUG_OUT + std::cout << "detect at: " << dx << " " << dy << std::endl; +#endif float detectionScore = 0.f; const Octave& octave = *(level.octave); - int stBegin = octave.index() * octave.stages, stEnd = stBegin + octave.stages; + int stBegin = octave.index * octave.stages, stEnd = stBegin + octave.stages; + +#if defined WITH_DEBUG_OUT + std::cout << " octave stages: " << stBegin << " to " << stEnd << " index " << octave.index << " " + << octave.scale << " level " << level.origScale << std::endl; +#endif + int st = stBegin; for(; st < stEnd; ++st) { + +#if defined WITH_DEBUG_OUT + printf("index: %d\n", st); +#endif + const Stage& stage = stages[st]; { int nId = st * 3; @@ -325,71 +547,55 @@ struct cv::SoftCascade::Filds // work with root node const Node& node = nodes[nId]; const Feature& feature = features[node.feature]; + cv::Rect scaledRect; + float threshold = rescale(feature, level.relScale, scaledRect, node.threshold); - // rescaling - float scaling = CascadeIntrinsics::getFor(feature.channel, level.relScale); - cv::Rect scaledRect = feature.rect; - float farea = (scaledRect.width - scaledRect.x) * (scaledRect.height - scaledRect.y); - // rescale - scaledRect.x = cvRound(scaling * scaledRect.x); - scaledRect.y = cvRound(scaling * scaledRect.y); - scaledRect.width = cvRound(scaling * scaledRect.width); - scaledRect.height = cvRound(scaling * scaledRect.height); - float sarea = (scaledRect.width - scaledRect.x) * (scaledRect.height - scaledRect.y); - - float approx = 1.f; - if ((farea - 0.f) > FLT_EPSILON && (farea - 0.f) > FLT_EPSILON) - { - const float expected_new_area = farea*level.relScale*level.relScale; - approx = expected_new_area / sarea; - } - - float rootThreshold = node.threshold / approx; // ToDo check - rootThreshold *= scaling; - - // use rescaled float sum = storage.get(dx, dy, feature.channel, scaledRect); - int next = (sum >= rootThreshold)? 2 : 1; - // leaces +#if defined WITH_DEBUG_OUT + printf("root feature %d %f\n",feature.channel, sum); +#endif + + int next = (sum >= threshold)? 2 : 1; + +#if defined WITH_DEBUG_OUT + printf("go: %d (%f >= %f)\n\n" ,next, sum, threshold); +#endif + + // leaves const Node& leaf = nodes[nId + next]; - const Feature& fLeaf = features[node.feature]; + const Feature& fLeaf = features[leaf.feature]; - // rescaling - scaling = CascadeIntrinsics::getFor(fLeaf.channel, level.relScale); - scaledRect = fLeaf.rect; - farea = (scaledRect.width - scaledRect.x) * (scaledRect.height - scaledRect.y); - // rescale - scaledRect.x = cvRound(scaling * scaledRect.x); - scaledRect.y = cvRound(scaling * scaledRect.y); - scaledRect.width = cvRound(scaling * scaledRect.width); - scaledRect.height = cvRound(scaling * scaledRect.height); + threshold = rescale(fLeaf, level.relScale, scaledRect, leaf.threshold); + sum = storage.get(dx, dy, fLeaf.channel, scaledRect); - sarea = (scaledRect.width - scaledRect.x) * (scaledRect.height - scaledRect.y); - approx = 1.f; - if ((farea - 0.f) > FLT_EPSILON && (farea - 0.f) > FLT_EPSILON) - { - const float expected_new_area = farea*level.relScale*level.relScale; - approx = expected_new_area / sarea; - } - - rootThreshold = leaf.threshold / approx; // ToDo check - rootThreshold *= scaling; - - sum = storage.get(dx, dy, feature.channel, scaledRect); - - int lShift = (next - 1) * 2 + (sum >= rootThreshold) ? 1 : 0; - float impact = leaves[nId + lShift]; + int lShift = (next - 1) * 2 + ((sum >= threshold) ? 1 : 0); + float impact = leaves[(st * 4) + lShift]; +#if defined WITH_DEBUG_OUT + printf("decided: %d (%f >= %f) %d %f\n\n" ,next, sum, threshold, lShift, impact); +#endif detectionScore += impact; } +#if defined WITH_DEBUG_OUT + printf("extracted stage:\n"); + printf("ct %f\n", stage.threshold); + printf("computed score %f\n\n", detectionScore); + // if (st - stBegin > 100) break; +#endif + if (detectionScore <= stage.threshold) break; } - if (st == octave.stages - 1) - level.markDetection(dx, dy, detections); + printf("x %d y %d: %d\n", dx, dy, st - stBegin); + + if (st == stEnd) + { + std::cout << " got " << st << std::endl; + level.markDetection(dx, dy, detectionScore, detections); + } } octIt_t fitOctave(const float& logFactor) @@ -438,22 +644,17 @@ struct cv::SoftCascade::Filds if (fabs(scale - maxScale) < FLT_EPSILON) break; scale = std::min(maxScale, expf(log(scale) + logFactor)); - // std::cout << "level scale " - // << levels[sc].origScale - // << " octeve " - // << levels[sc].octave->scale - // << " " - // << levels[sc].relScale - // << " " << levels[sc].shrScale - // << " [" << levels[sc].objSize.width - // << " " << levels[sc].objSize.height << "] [" - // << levels[sc].workRect.width << " " << levels[sc].workRect.height << std::endl; + std::cout << "level " << sc << " scale " + << levels[sc].origScale + << " octeve " + << levels[sc].octave->scale + << " " + << levels[sc].relScale + << " " << levels[sc].shrScale + << " [" << levels[sc].objSize.width + << " " << levels[sc].objSize.height << "] [" + << levels[sc].workRect.width << " " << levels[sc].workRect.height << "]" << std::endl; } - - return; - - - std::cout << std::endl << std::endl << std::endl; } bool fill(const FileNode &root, const float mins, const float maxs) @@ -500,10 +701,12 @@ struct cv::SoftCascade::Filds // octaves.reserve(noctaves); FileNodeIterator it = fn.begin(), it_end = fn.end(); + int feature_offset = 0; + int octIndex = 0; for (; it != it_end; ++it) { FileNode fns = *it; - Octave octave(cv::Size(SoftCascade::ORIG_OBJECT_WIDTH, SoftCascade::ORIG_OBJECT_HEIGHT), fns); + Octave octave(octIndex, cv::Size(SoftCascade::ORIG_OBJECT_WIDTH, SoftCascade::ORIG_OBJECT_HEIGHT), fns); CV_Assert(octave.stages > 0); octaves.push_back(octave); @@ -527,7 +730,7 @@ struct cv::SoftCascade::Filds fns = (*ftr)[SC_INTERNAL]; FileNodeIterator inIt = fns.begin(), inIt_end = fns.end(); for (; inIt != inIt_end;) - nodes.push_back(Node(inIt)); + nodes.push_back(Node(feature_offset, inIt)); fns = (*ftr)[SC_LEAF]; inIt = fns.begin(), inIt_end = fns.end(); @@ -539,9 +742,31 @@ struct cv::SoftCascade::Filds st = ffs.begin(), st_end = ffs.end(); for (; st != st_end; ++st ) features.push_back(Feature(*st)); + + feature_offset += octave.stages * 3; + ++octIndex; } shrinkage = octaves[0].shrinkage; + + //debug print + // std::cout << "collected " << stages.size() << " stages" << std::endl; + // for (int i = 0; i < (int)stages.size(); ++i) + // { + // std::cout << "stage " << i << ": " << stages[i].threshold << std::endl; + // } + + // std::cout << "collected " << nodes.size() << " nodes" << std::endl; + // for (int i = 0; i < (int)nodes.size(); ++i) + // { + // std::cout << "node " << i << ": " << nodes[i].threshold << " " << nodes[i].feature << std::endl; + // } + + // std::cout << "collected " << leaves.size() << " leaves" << std::endl; + // for (int i = 0; i < (int)leaves.size(); ++i) + // { + // std::cout << "leaf " << i << ": " << leaves[i] << std::endl; + // } return true; } }; @@ -574,9 +799,11 @@ bool cv::SoftCascade::load( const string& filename, const float minScale, const return true; } -void cv::SoftCascade::detectMultiScale(const Mat& image, const std::vector& rois, - std::vector& objects, - const int step, const int rejectfactor) +#define DEBUG_STORE_IMAGES +#define DEBUG_SHOW_RESULT + +void cv::SoftCascade::detectMultiScale(const Mat& image, const std::vector& /*rois*/, + std::vector& objects, const int /*rejectfactor*/) { typedef std::vector::const_iterator RIter_t; // only color images are supperted @@ -589,20 +816,66 @@ void cv::SoftCascade::detectMultiScale(const Mat& image, const std::vector> doppia; + + cv::Mat diff; + cv::absdiff(image1, doppia, diff); + + fs << "absdiff" << diff; + fs.release(); +#if defined DEBUG_STORE_IMAGES + // create integrals - ChannelStorage storage(image, fld.shrinkage); + ChannelStorage storage(image1, fld.shrinkage); // object candidates - std::vector detections; + std::vector detections; typedef std::vector::const_iterator lIt; - for (lIt it = fld.levels.begin(); it != fld.levels.end(); ++it) + int total = 0, l = 0; + for (lIt it = fld.levels.begin() + 26; it != fld.levels.end(); ++it) { const Level& level = *it; + +#if defined WITH_DEBUG_OUT + std::cout << "================================ " << l++ << std::endl; +#endif for (int dy = 0; dy < level.workRect.height; ++dy) + { for (int dx = 0; dx < level.workRect.width; ++dx) + { fld.detectAt(level, dx, dy, storage, detections); + total++; + // break; + } + // break; + } + break; } - std::swap(detections, objects); + cv::Mat out = image.clone(); + +#if defined DEBUG_SHOW_RESULT + + printf("TOTAL: %d from %d\n", (int)detections.size(),total) ; + + for(int i = 0; i < (int)detections.size(); ++i) + { + cv::rectangle(out, detections[i].rect, cv::Scalar(255, 0, 0, 255), 2); + } + + cv::imshow("out", out); + cv::waitKey(0); +#endif + // std::swap(detections, objects); } \ No newline at end of file diff --git a/modules/objdetect/test/test_softcascade.cpp b/modules/objdetect/test/test_softcascade.cpp index 7311ad291..9c316fd90 100644 --- a/modules/objdetect/test/test_softcascade.cpp +++ b/modules/objdetect/test/test_softcascade.cpp @@ -55,7 +55,7 @@ TEST(SoftCascade, detect) cv::SoftCascade cascade; ASSERT_TRUE(cascade.load(xml)); - cv::Mat colored = cv::imread(cvtest::TS::ptr()->get_data_path() + "cascadeandhog/bahnhof/image_00000006_0.png"); + cv::Mat colored = cv::imread(cvtest::TS::ptr()->get_data_path() + "cascadeandhog/bahnhof/image_00000000_0.png"); ASSERT_FALSE(colored.empty()); std::vector objectBoxes; From efd26158448b3fed82f03f883fbd301ed36d90ef Mon Sep 17 00:00:00 2001 From: "marina.kolpakova" Date: Wed, 19 Sep 2012 17:58:44 +0400 Subject: [PATCH 19/91] fix floating point bug --- modules/objdetect/src/softcascade.cpp | 166 ++++++++++++++++++++------ 1 file changed, 131 insertions(+), 35 deletions(-) diff --git a/modules/objdetect/src/softcascade.cpp b/modules/objdetect/src/softcascade.cpp index 9e1c550d7..24c055de6 100644 --- a/modules/objdetect/src/softcascade.cpp +++ b/modules/objdetect/src/softcascade.cpp @@ -169,8 +169,12 @@ struct CascadeIntrinsics static float getFor(int channel, float scaling) { CV_Assert(channel < 10); +#if defined WITH_DEBUG_OUT + printf("QQQQQQQQQQQQQQQq: %f %f\n", scaling, fabs(scaling - 1.f)); +#endif - if ((scaling - 1.f) < FLT_EPSILON) + if (fabs(scaling - 1.f) < FLT_EPSILON) + // if (scaling == 1.f) return 1.f; // according to R. Benenson, M. Mathias, R. Timofte and L. Van Gool's and Dallal's papers @@ -190,7 +194,7 @@ struct CascadeIntrinsics float b = B[(int)(scaling >= 1)][(int)(channel > 6)]; #if defined WITH_DEBUG_OUT - printf("scaling: %f %f %f %f\n", scaling, a, b, a * pow(scaling, b)); + printf("!!! scaling: %f %f %f %f\n", scaling, a, b, a * pow(scaling, b)); #endif return a * pow(scaling, b); } @@ -344,6 +348,47 @@ void calcHistBins(const cv::Mat& grey, cv::Mat& magIntegral, std::vector +struct Decimate { + int shrinkage; + + Decimate(const int sr) : shrinkage(sr) {} + + void operator()(const cv::Mat& in, cv::Mat& out) const + { + int cols = in.cols / shrinkage; + int rows = in.rows / shrinkage; + out.create(rows, cols, in.type()); + + CV_Assert(cols * shrinkage == in.cols); + CV_Assert(rows * shrinkage == in.rows); + + std::cout << "type: " << out.type() << std::endl; + + for (int outIdx_y = 0; outIdx_y < rows; ++outIdx_y) + { + T* outPtr = out.ptr(outIdx_y); + for (int outIdx_x = 0; outIdx_x < cols; ++outIdx_x) + { + // do desimate + int inIdx_y = outIdx_y * shrinkage; + int inIdx_x = outIdx_x * shrinkage; + int sum = 0; + + for (int y = inIdx_y; y < inIdx_y + shrinkage; ++y) + for (int x = inIdx_x; x < inIdx_x + shrinkage; ++x) + sum += in.at(y, x); + + sum /= shrinkage * shrinkage; + outPtr[outIdx_x] = cv::saturate_cast(sum); + } + } + } + +}; + +//#define USE_REFERENCE_VALUES + struct ChannelStorage { std::vector hog; @@ -358,24 +403,65 @@ struct ChannelStorage ChannelStorage(cv::Mat& colored, int shr) : shrinkage(shr) { hog.clear(); - cv::FileStorage fs("/home/kellan/testInts.xml", cv::FileStorage::READ); - char buff[33]; - float scale = 1.f / shrinkage; - for(int i = 0; i < 10; ++i) - { - cv::Mat channel; - fs[std::string("channel") + itoa(i, buff, 10)] >> channel; + Decimate decimate(shr); - cv::Mat shrunk, sum; - // cv::resize(channel, shrunk, cv::Size(), scale, scale, cv::INTER_AREA); - // cv::imshow(std::string("channel") + itoa(i, buff, 10), shrunk); - // cv::waitKey(0); - // cv::integral(channel, sum); - // if (i == 1) - // std::cout << channel << std::endl; - hog.push_back(channel); +#if defined USE_REFERENCE_VALUES + cv::FileStorage imgs("/home/kellan/testInts.xml", cv::FileStorage::READ); +#else + + // add gauss + cv::Mat gauss; + cv::GaussianBlur(colored, gauss, cv::Size(3,3), 0 ,0); + + // convert to luv + cv::Mat luv; + cv::cvtColor(colored, luv, CV_RGB2Luv); + + // split to 3 one channel matrix + std::vector splited, luvs; + split(luv, splited); + + // shrink and integrate + for (int i = 0; i < (int)splited.size(); i++) + { + cv::Mat shrunk, sum; + decimate(splited[i], shrunk); + cv::integral(shrunk, sum, cv::noArray(), CV_32S); + luvs.push_back(sum); } - // exit(1); + + // calculate magnitude + static const float magnitudeScaling = 1.f / sqrt(2); + cv::Mat grey; + cv::cvtColor(colored, grey, CV_RGB2GRAY); + + // channels + cv::FileStorage imgs("/home/kellan/testImgs.xml", cv::FileStorage::READ); +#endif + + char buff[33]; + for(int i = 0; i < 7; ++i) + { + cv::Mat channel, shrunk, sum; + imgs[std::string("channel") + itoa(i, buff, 10)] >> channel; + +#if defined USE_REFERENCE_VALUES + hog.push_back(channel); +#else + + decimate(channel, shrunk); + // cv::resize(channel, shrunk, cv::Size(), 1.f / shr, 1.f / shr, cv::INTER_AREA); + cv::integral(shrunk, sum, cv::noArray(), CV_32S); + + hog.push_back(sum); +#endif + } + +#if !defined USE_REFERENCE_VALUES + hog.insert(hog.end(), luvs.begin(), luvs.end()); + CV_Assert(hog.size() == 10); +#endif + // exit(10); } // { // // add gauss @@ -427,6 +513,12 @@ struct ChannelStorage printf("feature box %d %d %d %d ", area.x, area.y, area.width, area.height); printf("get for channel %d\n", channel); printf("!! %d\n", m.depth()); + + printf("extract feature for: [%d %d] [%d %d] [%d %d] [%d %d]\n", + x + area.x, y + area.y, x + area.width,y + area.y, x + area.width,y + area.height, + x + area.x, y + area.height); + + printf("at point %d %d with offset %d\n", x, y, 0); #endif int a = m.ptr(y + area.y)[x + area.x]; @@ -493,7 +585,7 @@ struct cv::SoftCascade::Filds float sarea = (scaledRect.width - scaledRect.x) * (scaledRect.height - scaledRect.y); float approx = 1.f; - if ((farea - 0.f) > FLT_EPSILON && (farea - 0.f) > FLT_EPSILON) + if (fabs(farea - 0.f) > FLT_EPSILON && fabs(farea - 0.f) > FLT_EPSILON) { const float expected_new_area = farea * relScale * relScale; approx = expected_new_area / sarea; @@ -505,7 +597,7 @@ struct cv::SoftCascade::Filds } // compensation areas rounding - float rootThreshold = threshold / approx;/ + float rootThreshold = threshold / approx; rootThreshold *= scaling; #if defined WITH_DEBUG_OUT @@ -583,7 +675,7 @@ struct cv::SoftCascade::Filds printf("extracted stage:\n"); printf("ct %f\n", stage.threshold); printf("computed score %f\n\n", detectionScore); - // if (st - stBegin > 100) break; + if (st - stBegin > 50 ) break; #endif if (detectionScore <= stage.threshold) break; @@ -681,7 +773,7 @@ struct cv::SoftCascade::Filds static const char *const SC_LEAF = "leafValues"; - // only boost supported + // only Ada Boost supported std::string stageTypeStr = (string)root[SC_STAGE_TYPE]; CV_Assert(stageTypeStr == SC_BOOST); @@ -799,7 +891,7 @@ bool cv::SoftCascade::load( const string& filename, const float minScale, const return true; } -#define DEBUG_STORE_IMAGES +// #define DEBUG_STORE_IMAGES #define DEBUG_SHOW_RESULT void cv::SoftCascade::detectMultiScale(const Mat& image, const std::vector& /*rois*/, @@ -833,7 +925,8 @@ void cv::SoftCascade::detectMultiScale(const Mat& image, const std::vector::const_iterator lIt; int total = 0, l = 0; - for (lIt it = fld.levels.begin() + 26; it != fld.levels.end(); ++it) + for (lIt it = fld.levels.begin(); it != fld.levels.end(); ++it) { const Level& level = *it; #if defined WITH_DEBUG_OUT std::cout << "================================ " << l++ << std::endl; #endif + // int dx = 79; int dy = 76; for (int dy = 0; dy < level.workRect.height; ++dy) { for (int dx = 0; dx < level.workRect.width; ++dx) @@ -860,22 +954,24 @@ void cv::SoftCascade::detectMultiScale(const Mat& image, const std::vector Date: Wed, 19 Sep 2012 18:47:56 +0400 Subject: [PATCH 20/91] fix hog channels --- modules/objdetect/src/softcascade.cpp | 116 +++++++++++++------------- 1 file changed, 59 insertions(+), 57 deletions(-) diff --git a/modules/objdetect/src/softcascade.cpp b/modules/objdetect/src/softcascade.cpp index 24c055de6..989b53659 100644 --- a/modules/objdetect/src/softcascade.cpp +++ b/modules/objdetect/src/softcascade.cpp @@ -387,14 +387,11 @@ struct Decimate { }; -//#define USE_REFERENCE_VALUES +#define USE_REFERENCE_VALUES struct ChannelStorage { std::vector hog; - cv::Mat magnitude; - cv::Mat luv; - int shrinkage; enum {HOG_BINS = 6, HOG_LUV_BINS = 10}; @@ -407,8 +404,8 @@ struct ChannelStorage #if defined USE_REFERENCE_VALUES cv::FileStorage imgs("/home/kellan/testInts.xml", cv::FileStorage::READ); + char buff[33]; #else - // add gauss cv::Mat gauss; cv::GaussianBlur(colored, gauss, cv::Size(3,3), 0 ,0); @@ -430,79 +427,84 @@ struct ChannelStorage luvs.push_back(sum); } - // calculate magnitude - static const float magnitudeScaling = 1.f / sqrt(2); + // convert to grey cv::Mat grey; cv::cvtColor(colored, grey, CV_RGB2GRAY); - // channels - cv::FileStorage imgs("/home/kellan/testImgs.xml", cv::FileStorage::READ); -#endif + // get derivative + cv::Mat df_dx, df_dy, mag, angle; + cv::Sobel(grey, df_dx, CV_32F, 1, 0); + cv::Sobel(grey, df_dy, CV_32F, 0, 1); - char buff[33]; - for(int i = 0; i < 7; ++i) + // normalize + df_dx /= 4; + df_dy /= 4; + + // calculate magnitude + cv::cartToPolar(df_dx, df_dy, mag, angle, true); + + // normalize to avoid uchar overflow + static const float magnitudeScaling = 1.f / sqrt(2); + mag *= magnitudeScaling; + + // convert to uchar + cv::Mat saturatedMag(grey.rows, grey.cols, CV_8UC1), shrMag; + for (int y = 0; y < grey.rows; ++y) + { + float* rm = mag.ptr(y); + uchar* mg = saturatedMag.ptr(y); + for (int x = 0; x < grey.cols; ++x) + { + mg[x] = cv::saturate_cast(rm[x]); + } + } + + // srink and integrate + decimate(saturatedMag, shrMag); + cv::integral(shrMag, mag, cv::noArray(), CV_32S); + + // create hog channels + angle /= 60; + + std::vector hist; + for (int bin = 0; bin < 6; ++bin) + { + hist.push_back(cv::Mat(colored.rows, colored.cols, CV_8UC1)); + } + + for (int y = 0; y < saturatedMag.rows; ++y) + { + uchar* magnitude = saturatedMag.ptr(y); + float* ang = angle.ptr(y); + + for (int x = 0; x < saturatedMag.cols; ++x) + { + hist[ (int)ang[x] ].ptr(y)[x] = magnitude[x]; + } + } + +#endif + for(int i = 0; i < 6; ++i) { cv::Mat channel, shrunk, sum; - imgs[std::string("channel") + itoa(i, buff, 10)] >> channel; #if defined USE_REFERENCE_VALUES + imgs[std::string("channel") + itoa(i, buff, 10)] >> channel; hog.push_back(channel); #else - - decimate(channel, shrunk); - // cv::resize(channel, shrunk, cv::Size(), 1.f / shr, 1.f / shr, cv::INTER_AREA); + decimate(hist[i], shrunk); cv::integral(shrunk, sum, cv::noArray(), CV_32S); - hog.push_back(sum); #endif } #if !defined USE_REFERENCE_VALUES + hog.push_back(mag); hog.insert(hog.end(), luvs.begin(), luvs.end()); CV_Assert(hog.size() == 10); #endif // exit(10); } - // { - // // add gauss - // cv::Mat gauss; - // cv::GaussianBlur(colored, gauss, cv::Size(3,3), 0 ,0); - - // colored = gauss; - // // cv::imshow("colored", colored); - - // cv::Mat _luv, shrLuv; - // cv::cvtColor(colored, _luv, CV_BGR2Luv); - - // // cv::imshow("_luv", _luv); - - // cv::resize(_luv, shrLuv, cv::Size(), 1.f / shr, 1.f / shr, cv::INTER_AREA); - - // // cv::imshow("shrLuv", shrLuv); - - // cv::integral(shrLuv, luv); - - // // cv::imshow("luv", luv); - - // std::vector splited; - // split(luv, splited); - - // char buffer[33]; - - // for (int i = 0; i < (int)splited.size(); i++) - // { - // // cv::imshow(itoa(i,buffer,10), splited[i]); - // } - - // cv::Mat grey; - // cv::cvtColor(colored, grey, CV_RGB2GRAY); - - // // cv::imshow("grey", grey); - - // calcHistBins(grey, magnitude, hog, HOG_BINS, shrinkage); - - // hog.insert(hog.end(), splited.begin(), splited.end()); - // } float get(const int x, const int y, const int channel, const cv::Rect& area) const { From b6081438fa20f07ce8312d3bcf342a4e9fd6edc7 Mon Sep 17 00:00:00 2001 From: "marina.kolpakova" Date: Wed, 19 Sep 2012 18:57:59 +0400 Subject: [PATCH 21/91] clean code --- modules/objdetect/src/softcascade.cpp | 138 ++------------------------ 1 file changed, 10 insertions(+), 128 deletions(-) diff --git a/modules/objdetect/src/softcascade.cpp b/modules/objdetect/src/softcascade.cpp index 989b53659..8e8a0ce4a 100644 --- a/modules/objdetect/src/softcascade.cpp +++ b/modules/objdetect/src/softcascade.cpp @@ -232,122 +232,6 @@ int qangle6(float dfdx, float dfdy) return index; } -//ToDo -void calcHistBins(const cv::Mat& grey, cv::Mat& magIntegral, std::vector& histInts, - const int bins, int shrinkage) -{ - static const float magnitudeScaling = 1.f / sqrt(2); - - CV_Assert( grey.type() == CV_8U); - - float scale = 1.f / shrinkage; - - const int rows = grey.rows + 1; - const int cols = grey.cols + 1; - - cv::Mat df_dx(grey.rows, grey.cols, CV_32F), - df_dy(grey.rows, grey.cols, CV_32F), mag, angle; - // cv::Sobel(grey, df_dx, CV_32F, 1, 0); - // cv::Sobel(grey, df_dy, CV_32F, 0, 1); - - for (int y = 1; y < grey.rows -1; ++y) - { - float* dx = df_dx.ptr(y); - float* dy = df_dy.ptr(y); - - const uchar* gr = grey.ptr(y); - const uchar* gr_down = grey.ptr(y - 1); - const uchar* gr_up = grey.ptr(y + 1); - for (int x = 1; x < grey.cols - 1; ++x) - { - float dx_a = gr[x + 1]; - float dx_b = gr[x - 1]; - dx[x] = dx_a - dx_b; - - float dy_a = gr_up[x]; - float dy_b = gr_down[x]; - dy[x] = dy_a - dy_b; - } - } - - cv::cartToPolar(df_dx, df_dy, mag, angle, true); - - mag *= magnitudeScaling; - - cv::Mat saturatedMag(grey.rows, grey.cols, CV_8UC1); - for (int y = 0; y < grey.rows; ++y) - { - float* rm = mag.ptr(y); - uchar* mg = saturatedMag.ptr(y); - for (int x = 0; x < grey.cols; ++x) - { - mg[x] = cv::saturate_cast(rm[x]); - } - } - - mag = saturatedMag; - - histInts.clear(); - std::vector hist; - for (int bin = 0; bin < bins; ++bin) - { - hist.push_back(cv::Mat(rows, cols, CV_8UC1)); - } - - for (int h = 0; h < saturatedMag.rows; ++h) - { - uchar* magnitude = saturatedMag.ptr(h); - float* dfdx = df_dx.ptr(h); - float* dfdy = df_dy.ptr(h); - - for (int w = 0; w < saturatedMag.cols; ++w) - { - hist[ qangle6(dfdx[w], dfdy[w]) ].ptr(h)[w] = magnitude[w]; - } - } - - angle /= 60; - - - // for (int h = 0; h < saturatedMag.rows; ++h) - // { - // uchar* magnitude = saturatedMag.ptr(h); - // float* ang = angle.ptr(h); - - // for (int w = 0; w < saturatedMag.cols; ++w) - // { - // hist[ (int)ang[w] ].ptr(h)[w] = magnitude[w]; - // } - // } - char buffer[33]; - - for (int bin = 0; bin < bins; ++bin) - { - cv::Mat shrunk, sum; - cv::imshow(std::string("hist[bin]") + itoa(bin, buffer, 10), hist[bin]); - cv::resize(hist[bin], shrunk, cv::Size(), scale, scale, cv::INTER_AREA); - cv::imshow(std::string("shrunk") + itoa(bin, buffer, 10), shrunk); - cv::integral(shrunk, sum); - cv::imshow(std::string("sum") + itoa(bin, buffer, 10), sum); - histInts.push_back(sum); - - // std::cout << shrunk << std::endl << std::endl; - } - - cv::Mat shrMag; - cv::imshow("mag", mag); - cv::resize(mag, shrMag, cv::Size(), scale, scale, cv::INTER_AREA); - - cv::FileStorage fs("/home/kellan/actualChannels.xml", cv::FileStorage::WRITE); - cv::imshow("shrunk_channel", shrMag); - fs << "shrunk_channel6" << shrMag; - - // cv::imshow("shrMag", shrMag); - cv::integral(shrMag, magIntegral, mag.depth()); - // cv::imshow("magIntegral", magIntegral); - histInts.push_back(magIntegral); -} - template< typename T> struct Decimate { int shrinkage; @@ -363,8 +247,6 @@ struct Decimate { CV_Assert(cols * shrinkage == in.cols); CV_Assert(rows * shrinkage == in.rows); - std::cout << "type: " << out.type() << std::endl; - for (int outIdx_y = 0; outIdx_y < rows; ++outIdx_y) { T* outPtr = out.ptr(outIdx_y); @@ -387,7 +269,7 @@ struct Decimate { }; -#define USE_REFERENCE_VALUES +// #define USE_REFERENCE_VALUES struct ChannelStorage { @@ -405,6 +287,13 @@ struct ChannelStorage #if defined USE_REFERENCE_VALUES cv::FileStorage imgs("/home/kellan/testInts.xml", cv::FileStorage::READ); char buff[33]; + + for(int i = 0; i < HOG_LUV_BINS; ++i) + { + cv::Mat channel; + imgs[std::string("channel") + itoa(i, buff, 10)] >> channel; + hog.push_back(channel); + } #else // add gauss cv::Mat gauss; @@ -483,22 +372,15 @@ struct ChannelStorage } } -#endif - for(int i = 0; i < 6; ++i) + for(int i = 0; i < HOG_BINS; ++i) { - cv::Mat channel, shrunk, sum; + cv::Mat shrunk, sum; -#if defined USE_REFERENCE_VALUES - imgs[std::string("channel") + itoa(i, buff, 10)] >> channel; - hog.push_back(channel); -#else decimate(hist[i], shrunk); cv::integral(shrunk, sum, cv::noArray(), CV_32S); hog.push_back(sum); -#endif } -#if !defined USE_REFERENCE_VALUES hog.push_back(mag); hog.insert(hog.end(), luvs.begin(), luvs.end()); CV_Assert(hog.size() == 10); From 26af7d7389b70724c71e8bd8fcf20dd4fc993b3b Mon Sep 17 00:00:00 2001 From: "marina.kolpakova" Date: Tue, 25 Sep 2012 22:09:45 +0400 Subject: [PATCH 22/91] refactor logs --- modules/objdetect/src/softcascade.cpp | 126 +++++++++++--------------- 1 file changed, 53 insertions(+), 73 deletions(-) diff --git a/modules/objdetect/src/softcascade.cpp b/modules/objdetect/src/softcascade.cpp index 8e8a0ce4a..cea31b0b3 100644 --- a/modules/objdetect/src/softcascade.cpp +++ b/modules/objdetect/src/softcascade.cpp @@ -47,8 +47,8 @@ #include #include #include -#include #include +#include namespace { @@ -61,6 +61,13 @@ char *itoa(long i, char* s, int /*dummy_radix*/) // used for noisy printfs // #define WITH_DEBUG_OUT +#if defined WITH_DEBUG_OUT +# define dprintf(format, ...) \ + do { printf(format, __VA_ARGS__); } while (0) +#else +# define dprintf(format, ...) +#endif + struct Octave { int index; @@ -169,9 +176,6 @@ struct CascadeIntrinsics static float getFor(int channel, float scaling) { CV_Assert(channel < 10); -#if defined WITH_DEBUG_OUT - printf("QQQQQQQQQQQQQQQq: %f %f\n", scaling, fabs(scaling - 1.f)); -#endif if (fabs(scaling - 1.f) < FLT_EPSILON) // if (scaling == 1.f) @@ -193,9 +197,7 @@ struct CascadeIntrinsics float a = A[(int)(scaling >= 1)][(int)(channel > 6)]; float b = B[(int)(scaling >= 1)][(int)(channel > 6)]; -#if defined WITH_DEBUG_OUT - printf("!!! scaling: %f %f %f %f\n", scaling, a, b, a * pow(scaling, b)); -#endif + dprintf("scaling: %f %f %f %f\n", scaling, a, b, a * pow(scaling, b)); return a * pow(scaling, b); } }; @@ -269,6 +271,7 @@ struct Decimate { }; +// use previous stored integrals for regression testing // #define USE_REFERENCE_VALUES struct ChannelStorage @@ -279,14 +282,14 @@ struct ChannelStorage enum {HOG_BINS = 6, HOG_LUV_BINS = 10}; ChannelStorage() {} - ChannelStorage(cv::Mat& colored, int shr) : shrinkage(shr) + ChannelStorage(const cv::Mat& colored, int shr) : shrinkage(shr) { hog.clear(); Decimate decimate(shr); #if defined USE_REFERENCE_VALUES - cv::FileStorage imgs("/home/kellan/testInts.xml", cv::FileStorage::READ); char buff[33]; + cv::FileStorage imgs("/home/kellan/testInts.xml", cv::FileStorage::READ); for(int i = 0; i < HOG_LUV_BINS; ++i) { @@ -310,10 +313,10 @@ struct ChannelStorage // shrink and integrate for (int i = 0; i < (int)splited.size(); i++) { - cv::Mat shrunk, sum; - decimate(splited[i], shrunk); - cv::integral(shrunk, sum, cv::noArray(), CV_32S); - luvs.push_back(sum); + cv::Mat shrunk, sum; + decimate(splited[i], shrunk); + cv::integral(shrunk, sum, cv::noArray(), CV_32S); + luvs.push_back(sum); } // convert to grey @@ -353,12 +356,12 @@ struct ChannelStorage cv::integral(shrMag, mag, cv::noArray(), CV_32S); // create hog channels - angle /= 60; + angle /= 60.f; std::vector hist; - for (int bin = 0; bin < 6; ++bin) + for (int bin = 0; bin < HOG_BINS; ++bin) { - hist.push_back(cv::Mat(colored.rows, colored.cols, CV_8UC1)); + hist.push_back(cv::Mat::zeros(saturatedMag.rows, saturatedMag.cols, CV_8UC1)); } for (int y = 0; y < saturatedMag.rows; ++y) @@ -375,7 +378,6 @@ struct ChannelStorage for(int i = 0; i < HOG_BINS; ++i) { cv::Mat shrunk, sum; - decimate(hist[i], shrunk); cv::integral(shrunk, sum, cv::noArray(), CV_32S); hog.push_back(sum); @@ -385,7 +387,6 @@ struct ChannelStorage hog.insert(hog.end(), luvs.begin(), luvs.end()); CV_Assert(hog.size() == 10); #endif - // exit(10); } float get(const int x, const int y, const int channel, const cv::Rect& area) const @@ -393,26 +394,23 @@ struct ChannelStorage CV_Assert(channel < HOG_LUV_BINS); const cv::Mat m = hog[channel]; -#if defined WITH_DEBUG_OUT - printf("feature box %d %d %d %d ", area.x, area.y, area.width, area.height); - printf("get for channel %d\n", channel); - printf("!! %d\n", m.depth()); + dprintf("feature box %d %d %d %d ", area.x, area.y, area.width, area.height); + dprintf("get for channel %d\n", channel); + dprintf("!! %d\n", m.depth()); - printf("extract feature for: [%d %d] [%d %d] [%d %d] [%d %d]\n", + dprintf("extract feature for: [%d %d] [%d %d] [%d %d] [%d %d]\n", x + area.x, y + area.y, x + area.width,y + area.y, x + area.width,y + area.height, x + area.x, y + area.height); - printf("at point %d %d with offset %d\n", x, y, 0); -#endif + dprintf("at point %d %d with offset %d\n", x, y, 0); int a = m.ptr(y + area.y)[x + area.x]; int b = m.ptr(y + area.y)[x + area.width]; int c = m.ptr(y + area.height)[x + area.width]; int d = m.ptr(y + area.height)[x + area.x]; -#if defined WITH_DEBUG_OUT - printf(" retruved integral values: %d %d %d %d\n", a, b, c, d); -#endif + dprintf(" retruved integral values: %d %d %d %d\n", a, b, c, d); + return (a - b + c - d); } }; @@ -444,12 +442,10 @@ struct cv::SoftCascade::Filds float scaling = CascadeIntrinsics::getFor(feature.channel, relScale); scaledRect = feature.rect; -#if defined WITH_DEBUG_OUT - printf("feature %d box %d %d %d %d\n", feature.channel, scaledRect.x, scaledRect.y, + dprintf("feature %d box %d %d %d %d\n", feature.channel, scaledRect.x, scaledRect.y, scaledRect.width, scaledRect.height); - std::cout << "rescale: " << feature.channel << " " << relScale << " " << scaling << std::endl; -#endif + dprintf("rescale: %d %f %f\n",feature.channel, relScale, scaling); float farea = (scaledRect.width - scaledRect.x) * (scaledRect.height - scaledRect.y); // rescale @@ -458,14 +454,9 @@ struct cv::SoftCascade::Filds scaledRect.width = cvRound(relScale * scaledRect.width); scaledRect.height = cvRound(relScale * scaledRect.height); -#if defined WITH_DEBUG_OUT - printf("feature %d box %d %d %d %d\n", feature.channel, scaledRect.x, scaledRect.y, + dprintf("feature %d box %d %d %d %d\n", feature.channel, scaledRect.x, scaledRect.y, scaledRect.width, scaledRect.height); - std::cout << " new rect: " << scaledRect.x << " " << scaledRect.y - << " " << scaledRect.width << " " << scaledRect.height << " "; -#endif - float sarea = (scaledRect.width - scaledRect.x) * (scaledRect.height - scaledRect.y); float approx = 1.f; @@ -474,20 +465,14 @@ struct cv::SoftCascade::Filds const float expected_new_area = farea * relScale * relScale; approx = expected_new_area / sarea; -#if defined WITH_DEBUG_OUT - std::cout << " rel areas " << expected_new_area << " " << sarea << std::endl; -#endif - + dprintf(" rel areas %f %f\n", expected_new_area, sarea); } // compensation areas rounding float rootThreshold = threshold / approx; rootThreshold *= scaling; -#if defined WITH_DEBUG_OUT - std::cout << "approximation " << approx << " " << threshold << " -> " << rootThreshold - << " " << scaling << std::endl; -#endif + dprintf("approximation %f %f -> %f %f\n", approx, threshold, rootThreshold, scaling); return rootThreshold; } @@ -495,26 +480,21 @@ struct cv::SoftCascade::Filds void detectAt(const Level& level, const int dx, const int dy, const ChannelStorage& storage, std::vector& detections) const { -#if defined WITH_DEBUG_OUT - std::cout << "detect at: " << dx << " " << dy << std::endl; -#endif + dprintf("detect at: %d %d\n", dx, dy); + float detectionScore = 0.f; const Octave& octave = *(level.octave); int stBegin = octave.index * octave.stages, stEnd = stBegin + octave.stages; -#if defined WITH_DEBUG_OUT - std::cout << " octave stages: " << stBegin << " to " << stEnd << " index " << octave.index << " " - << octave.scale << " level " << level.origScale << std::endl; -#endif + dprintf(" octave stages: %d to %d index %d %f level %f\n", + stBegin, stEnd, octave.index, octave.scale, level.origScale); int st = stBegin; for(; st < stEnd; ++st) { -#if defined WITH_DEBUG_OUT - printf("index: %d\n", st); -#endif + dprintf("index: %d\n", st); const Stage& stage = stages[st]; { @@ -529,15 +509,11 @@ struct cv::SoftCascade::Filds float sum = storage.get(dx, dy, feature.channel, scaledRect); -#if defined WITH_DEBUG_OUT - printf("root feature %d %f\n",feature.channel, sum); -#endif + dprintf("root feature %d %f\n",feature.channel, sum); int next = (sum >= threshold)? 2 : 1; -#if defined WITH_DEBUG_OUT - printf("go: %d (%f >= %f)\n\n" ,next, sum, threshold); -#endif + dprintf("go: %d (%f >= %f)\n\n" ,next, sum, threshold); // leaves const Node& leaf = nodes[nId + next]; @@ -549,23 +525,24 @@ struct cv::SoftCascade::Filds int lShift = (next - 1) * 2 + ((sum >= threshold) ? 1 : 0); float impact = leaves[(st * 4) + lShift]; -#if defined WITH_DEBUG_OUT - printf("decided: %d (%f >= %f) %d %f\n\n" ,next, sum, threshold, lShift, impact); -#endif + + dprintf("decided: %d (%f >= %f) %d %f\n\n" ,next, sum, threshold, lShift, impact); + detectionScore += impact; } + dprintf("extracted stage:\n"); + dprintf("ct %f\n", stage.threshold); + dprintf("computed score %f\n\n", detectionScore); + #if defined WITH_DEBUG_OUT - printf("extracted stage:\n"); - printf("ct %f\n", stage.threshold); - printf("computed score %f\n\n", detectionScore); if (st - stBegin > 50 ) break; #endif if (detectionScore <= stage.threshold) break; } - printf("x %d y %d: %d\n", dx, dy, st - stBegin); + dprintf("x %d y %d: %d\n", dx, dy, st - stBegin); if (st == stEnd) { @@ -793,7 +770,7 @@ void cv::SoftCascade::detectMultiScale(const Mat& image, const std::vector detections; @@ -826,6 +806,8 @@ void cv::SoftCascade::detectMultiScale(const Mat& image, const std::vector Date: Fri, 28 Sep 2012 10:21:22 +0400 Subject: [PATCH 23/91] add perfomance test for CPU soft cascade --- .../objdetect/perf/perf_cascadeclassifier.cpp | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/modules/objdetect/perf/perf_cascadeclassifier.cpp b/modules/objdetect/perf/perf_cascadeclassifier.cpp index 98007e45d..cb214154c 100644 --- a/modules/objdetect/perf/perf_cascadeclassifier.cpp +++ b/modules/objdetect/perf/perf_cascadeclassifier.cpp @@ -52,3 +52,26 @@ PERF_TEST_P(ImageName_MinSize, CascadeClassifierLBPFrontalFace, std::sort(faces.begin(), faces.end(), comparators::RectLess()); SANITY_CHECK(faces, 3.001 * faces.size()); } + +typedef std::tr1::tuple fixture; +typedef perf::TestBaseWithParam detect; + +PERF_TEST_P(detect, SoftCascade, + testing::Combine(testing::Values(std::string("cv/cascadeandhog/sc_cvpr_2012_to_opencv.xml")), + testing::Values(std::string("cv/cascadeandhog/bahnhof/image_00000000_0.png")))) +{ + cv::Mat colored = imread(getDataPath(get<1>(GetParam()))); + ASSERT_FALSE(colored.empty()); + + cv::SoftCascade cascade; + ASSERT_TRUE(cascade.load(getDataPath(get<0>(GetParam())))); + + std::vector rois, objectBoxes; + cascade.detectMultiScale(colored, rois, objectBoxes); + + TEST_CYCLE() + { + cascade.detectMultiScale(colored, rois, objectBoxes); + } + SANITY_CHECK(objectBoxes); +} From 0ff8a4633d156d794f4143d5e3ca717ee710b521 Mon Sep 17 00:00:00 2001 From: "marina.kolpakova" Date: Fri, 28 Sep 2012 16:32:33 +0400 Subject: [PATCH 24/91] remove pow calculations --- modules/objdetect/src/softcascade.cpp | 154 ++++++++------------------ 1 file changed, 48 insertions(+), 106 deletions(-) diff --git a/modules/objdetect/src/softcascade.cpp b/modules/objdetect/src/softcascade.cpp index cea31b0b3..684433608 100644 --- a/modules/objdetect/src/softcascade.cpp +++ b/modules/objdetect/src/softcascade.cpp @@ -50,6 +50,11 @@ #include #include +// use previous stored integrals for regression testing +// #define USE_REFERENCE_VALUES + +#if defined USE_REFERENCE_VALUES + namespace { char *itoa(long i, char* s, int /*dummy_radix*/) @@ -58,6 +63,8 @@ char *itoa(long i, char* s, int /*dummy_radix*/) return s; } +#endif + // used for noisy printfs // #define WITH_DEBUG_OUT @@ -68,6 +75,8 @@ char *itoa(long i, char* s, int /*dummy_radix*/) # define dprintf(format, ...) #endif +namespace { + struct Octave { int index; @@ -143,32 +152,6 @@ struct Object Object(const cv::Rect& r, const float c, Class dt = PEDESTRIAN) : rect(r), confidence(c), detType(dt) {} }; -struct Level -{ - const Octave* octave; - - float origScale; - float relScale; - float shrScale; // used for marking detection - - cv::Size workRect; - cv::Size objSize; - - Level(const Octave& oct, const float scale, const int shrinkage, const int w, const int h) - : octave(&oct), origScale(scale), relScale(scale / oct.scale), shrScale (relScale / (float)shrinkage), - workRect(cv::Size(cvRound(w / (float)shrinkage),cvRound(h / (float)shrinkage))), - objSize(cv::Size(cvRound(oct.size.width * relScale), cvRound(oct.size.height * relScale))) - {} - - void markDetection(const int x, const int y, float confidence, std::vector& detections) const - { - int shrinkage = (*octave).shrinkage; - cv::Rect rect(cvRound(x * shrinkage), cvRound(y * shrinkage), objSize.width, objSize.height); - - detections.push_back(Object(rect, confidence)); - } -}; - struct CascadeIntrinsics { static const float lambda = 1.099f, a = 0.89f; @@ -202,37 +185,36 @@ struct CascadeIntrinsics } }; - -int qangle6(float dfdx, float dfdy) +struct Level { - static const float vectors[6][2] = + const Octave* octave; + + float origScale; + float relScale; + float shrScale; // used for marking detection + + cv::Size workRect; + cv::Size objSize; + + float scaling[2]; + + Level(const Octave& oct, const float scale, const int shrinkage, const int w, const int h) + : octave(&oct), origScale(scale), relScale(scale / oct.scale), shrScale (relScale / (float)shrinkage), + workRect(cv::Size(cvRound(w / (float)shrinkage),cvRound(h / (float)shrinkage))), + objSize(cv::Size(cvRound(oct.size.width * relScale), cvRound(oct.size.height * relScale))) { - {std::cos(0), std::sin(0) }, - {std::cos(M_PI / 6.f), std::sin(M_PI / 6.f) }, - {std::cos(M_PI / 3.f), std::sin(M_PI / 3.f) }, - - {std::cos(M_PI / 2.f), std::sin(M_PI / 2.f) }, - {std::cos(2.f * M_PI / 3.f), std::sin(2.f * M_PI / 3.f)}, - {std::cos(5.f * M_PI / 6.f), std::sin(5.f * M_PI / 6.f)} - }; - - int index = 0; - - float dot = fabs(dfdx * vectors[0][0] + dfdy * vectors[0][1]); - - for(int i = 1; i < 6; ++i) - { - const float curr = fabs(dfdx * vectors[i][0] + dfdy * vectors[i][1]); - - if(curr > dot) - { - dot = curr; - index = i; - } + scaling[0] = CascadeIntrinsics::getFor(0, relScale); + scaling[1] = CascadeIntrinsics::getFor(9, relScale); } - return index; -} + void markDetection(const int x, const int y, float confidence, std::vector& detections) const + { + int shrinkage = (*octave).shrinkage; + cv::Rect rect(cvRound(x * shrinkage), cvRound(y * shrinkage), objSize.width, objSize.height); + + detections.push_back(Object(rect, confidence)); + } +}; template< typename T> struct Decimate { @@ -271,9 +253,6 @@ struct Decimate { }; -// use previous stored integrals for regression testing -// #define USE_REFERENCE_VALUES - struct ChannelStorage { std::vector hog; @@ -437,9 +416,10 @@ struct cv::SoftCascade::Filds typedef std::vector::iterator octIt_t; - float rescale(const Feature& feature, const float relScale, cv::Rect& scaledRect, const float threshold) const + float rescale(const Feature& feature, const float scaling, const float relScale, + cv::Rect& scaledRect, const float threshold) const { - float scaling = CascadeIntrinsics::getFor(feature.channel, relScale); + // float scaling = CascadeIntrinsics::getFor(feature.channel, relScale); scaledRect = feature.rect; dprintf("feature %d box %d %d %d %d\n", feature.channel, scaledRect.x, scaledRect.y, @@ -460,16 +440,16 @@ struct cv::SoftCascade::Filds float sarea = (scaledRect.width - scaledRect.x) * (scaledRect.height - scaledRect.y); float approx = 1.f; - if (fabs(farea - 0.f) > FLT_EPSILON && fabs(farea - 0.f) > FLT_EPSILON) + // if (fabs(farea - 0.f) > FLT_EPSILON && fabs(farea - 0.f) > FLT_EPSILON) { const float expected_new_area = farea * relScale * relScale; - approx = expected_new_area / sarea; + approx = sarea / expected_new_area; dprintf(" rel areas %f %f\n", expected_new_area, sarea); } // compensation areas rounding - float rootThreshold = threshold / approx; + float rootThreshold = threshold * approx; rootThreshold *= scaling; dprintf("approximation %f %f -> %f %f\n", approx, threshold, rootThreshold, scaling); @@ -504,7 +484,8 @@ struct cv::SoftCascade::Filds const Node& node = nodes[nId]; const Feature& feature = features[node.feature]; cv::Rect scaledRect; - float threshold = rescale(feature, level.relScale, scaledRect, node.threshold); + float threshold = rescale(feature, level.scaling[(int)(feature.channel > 6)], + level.relScale, scaledRect, node.threshold); float sum = storage.get(dx, dy, feature.channel, scaledRect); @@ -519,7 +500,8 @@ struct cv::SoftCascade::Filds const Node& leaf = nodes[nId + next]; const Feature& fLeaf = features[leaf.feature]; - threshold = rescale(fLeaf, level.relScale, scaledRect, leaf.threshold); + threshold = rescale(fLeaf, level.scaling[(int)(fLeaf.channel > 6)], + level.relScale, scaledRect, leaf.threshold); sum = storage.get(dx, dy, fLeaf.channel, scaledRect); @@ -546,7 +528,7 @@ struct cv::SoftCascade::Filds if (st == stEnd) { - std::cout << " got " << st << std::endl; + dprintf(" got %d\n", st); level.markDetection(dx, dy, detectionScore, detections); } } @@ -701,25 +683,6 @@ struct cv::SoftCascade::Filds } shrinkage = octaves[0].shrinkage; - - //debug print - // std::cout << "collected " << stages.size() << " stages" << std::endl; - // for (int i = 0; i < (int)stages.size(); ++i) - // { - // std::cout << "stage " << i << ": " << stages[i].threshold << std::endl; - // } - - // std::cout << "collected " << nodes.size() << " nodes" << std::endl; - // for (int i = 0; i < (int)nodes.size(); ++i) - // { - // std::cout << "node " << i << ": " << nodes[i].threshold << " " << nodes[i].feature << std::endl; - // } - - // std::cout << "collected " << leaves.size() << " leaves" << std::endl; - // for (int i = 0; i < (int)leaves.size(); ++i) - // { - // std::cout << "leaf " << i << ": " << leaves[i] << std::endl; - // } return true; } }; @@ -752,8 +715,7 @@ bool cv::SoftCascade::load( const string& filename, const float minScale, const return true; } -// #define DEBUG_STORE_IMAGES -#define DEBUG_SHOW_RESULT +// #define DEBUG_SHOW_RESULT void cv::SoftCascade::detectMultiScale(const Mat& image, const std::vector& /*rois*/, std::vector& objects, const int /*rejectfactor*/) @@ -772,26 +734,6 @@ void cv::SoftCascade::detectMultiScale(const Mat& image, const std::vector> doppia; - - cv::Mat diff; - cv::absdiff(image1, doppia, diff); - - fs << "absdiff" << diff; - fs.release(); - -#endif - - cv::imshow("!!", image1); - cv::waitKey(0); - // create integrals ChannelStorage storage(image, fld.shrinkage); @@ -831,9 +773,9 @@ void cv::SoftCascade::detectMultiScale(const Mat& image, const std::vector Date: Fri, 5 Oct 2012 15:59:51 +0400 Subject: [PATCH 25/91] remove Mat copying --- modules/objdetect/src/softcascade.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/modules/objdetect/src/softcascade.cpp b/modules/objdetect/src/softcascade.cpp index 684433608..dcdf2633a 100644 --- a/modules/objdetect/src/softcascade.cpp +++ b/modules/objdetect/src/softcascade.cpp @@ -283,7 +283,7 @@ struct ChannelStorage // convert to luv cv::Mat luv; - cv::cvtColor(colored, luv, CV_RGB2Luv); + cv::cvtColor(colored, luv, CV_BGR2Luv); // split to 3 one channel matrix std::vector splited, luvs; @@ -300,7 +300,7 @@ struct ChannelStorage // convert to grey cv::Mat grey; - cv::cvtColor(colored, grey, CV_RGB2GRAY); + cv::cvtColor(colored, grey, CV_BGR2GRAY); // get derivative cv::Mat df_dx, df_dy, mag, angle; @@ -371,7 +371,7 @@ struct ChannelStorage float get(const int x, const int y, const int channel, const cv::Rect& area) const { CV_Assert(channel < HOG_LUV_BINS); - const cv::Mat m = hog[channel]; + const cv::Mat& m = hog[channel]; dprintf("feature box %d %d %d %d ", area.x, area.y, area.width, area.height); dprintf("get for channel %d\n", channel); @@ -731,9 +731,6 @@ void cv::SoftCascade::detectMultiScale(const Mat& image, const std::vector Date: Sat, 6 Oct 2012 15:15:59 +0400 Subject: [PATCH 26/91] add const qualifier to detectMultiScale method --- .../include/opencv2/objdetect/objdetect.hpp | 2 +- modules/objdetect/src/softcascade.cpp | 18 ++++++------------ 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/modules/objdetect/include/opencv2/objdetect/objdetect.hpp b/modules/objdetect/include/opencv2/objdetect/objdetect.hpp index bb4240f59..fd48b32ff 100644 --- a/modules/objdetect/include/opencv2/objdetect/objdetect.hpp +++ b/modules/objdetect/include/opencv2/objdetect/objdetect.hpp @@ -512,7 +512,7 @@ public: //! return vector of bounding boxes. Each box contains one detected object virtual void detectMultiScale(const Mat& image, const std::vector& rois, std::vector& objects, - int rejectfactor = 1); + int rejectfactor = 1) const; protected: enum { BOOST = 0 }; diff --git a/modules/objdetect/src/softcascade.cpp b/modules/objdetect/src/softcascade.cpp index dcdf2633a..d3c5821c3 100644 --- a/modules/objdetect/src/softcascade.cpp +++ b/modules/objdetect/src/softcascade.cpp @@ -419,7 +419,6 @@ struct cv::SoftCascade::Filds float rescale(const Feature& feature, const float scaling, const float relScale, cv::Rect& scaledRect, const float threshold) const { - // float scaling = CascadeIntrinsics::getFor(feature.channel, relScale); scaledRect = feature.rect; dprintf("feature %d box %d %d %d %d\n", feature.channel, scaledRect.x, scaledRect.y, @@ -439,18 +438,13 @@ struct cv::SoftCascade::Filds float sarea = (scaledRect.width - scaledRect.x) * (scaledRect.height - scaledRect.y); - float approx = 1.f; - // if (fabs(farea - 0.f) > FLT_EPSILON && fabs(farea - 0.f) > FLT_EPSILON) - { - const float expected_new_area = farea * relScale * relScale; - approx = sarea / expected_new_area; + const float expected_new_area = farea * relScale * relScale; + float approx = sarea / expected_new_area; - dprintf(" rel areas %f %f\n", expected_new_area, sarea); - } + dprintf(" rel areas %f %f\n", expected_new_area, sarea); // compensation areas rounding - float rootThreshold = threshold * approx; - rootThreshold *= scaling; + float rootThreshold = threshold * approx * scaling; dprintf("approximation %f %f -> %f %f\n", approx, threshold, rootThreshold, scaling); @@ -715,10 +709,10 @@ bool cv::SoftCascade::load( const string& filename, const float minScale, const return true; } -// #define DEBUG_SHOW_RESULT +//#define DEBUG_SHOW_RESULT void cv::SoftCascade::detectMultiScale(const Mat& image, const std::vector& /*rois*/, - std::vector& objects, const int /*rejectfactor*/) + std::vector& objects, const int /*rejectfactor*/) const { typedef std::vector::const_iterator RIter_t; // only color images are supperted From 2914f2452185d4ef976de1b556e04085e4836aad Mon Sep 17 00:00:00 2001 From: "marina.kolpakova" Date: Sat, 6 Oct 2012 16:58:48 +0400 Subject: [PATCH 27/91] improve cpu version of SoftCascade: - remove division - remove cvRound - cache feature area --- modules/objdetect/src/softcascade.cpp | 77 ++++++++++++--------------- 1 file changed, 34 insertions(+), 43 deletions(-) diff --git a/modules/objdetect/src/softcascade.cpp b/modules/objdetect/src/softcascade.cpp index d3c5821c3..9eba9bd90 100644 --- a/modules/objdetect/src/softcascade.cpp +++ b/modules/objdetect/src/softcascade.cpp @@ -126,6 +126,7 @@ struct Feature { int channel; cv::Rect rect; + float rarea; static const char * const SC_F_CHANNEL; static const char * const SC_F_RECT; @@ -136,6 +137,9 @@ struct Feature cv::FileNode rn = fn[SC_F_RECT]; cv::FileNodeIterator r_it = rn.end(); rect = cv::Rect(*(--r_it), *(--r_it), *(--r_it), *(--r_it)); + + // 1 / area + rarea = 1.f / ((rect.width - rect.x) * (rect.height - rect.y)); } }; @@ -192,10 +196,13 @@ struct Level float origScale; float relScale; float shrScale; // used for marking detection + int scaleshift; cv::Size workRect; cv::Size objSize; + enum { R_SHIFT = 1 << 15 }; + float scaling[2]; Level(const Octave& oct, const float scale, const int shrinkage, const int w, const int h) @@ -203,8 +210,9 @@ struct Level workRect(cv::Size(cvRound(w / (float)shrinkage),cvRound(h / (float)shrinkage))), objSize(cv::Size(cvRound(oct.size.width * relScale), cvRound(oct.size.height * relScale))) { - scaling[0] = CascadeIntrinsics::getFor(0, relScale); - scaling[1] = CascadeIntrinsics::getFor(9, relScale); + scaling[0] = CascadeIntrinsics::getFor(0, relScale) / (relScale * relScale); + scaling[1] = CascadeIntrinsics::getFor(9, relScale) / (relScale * relScale); + scaleshift = relScale * (1 << 16); } void markDetection(const int x, const int y, float confidence, std::vector& detections) const @@ -214,6 +222,25 @@ struct Level detections.push_back(Object(rect, confidence)); } + + float rescale(cv::Rect& scaledRect, const float threshold, int idx) const + { + // rescale + // scaledRect.x = cvRound(relScale * scaledRect.x); + // scaledRect.y = cvRound(relScale * scaledRect.y); + // scaledRect.width = cvRound(relScale * scaledRect.width); + // scaledRect.height = cvRound(relScale * scaledRect.height); + + scaledRect.x = (scaleshift * scaledRect.x + R_SHIFT) >> 16; + scaledRect.y = (scaleshift * scaledRect.y + R_SHIFT) >> 16; + scaledRect.width = (scaleshift * scaledRect.width + R_SHIFT) >> 16; + scaledRect.height = (scaleshift * scaledRect.height + R_SHIFT) >> 16; + + float sarea = (scaledRect.width - scaledRect.x) * (scaledRect.height - scaledRect.y); + + // compensation areas rounding + return (threshold * scaling[idx] * sarea); + } }; template< typename T> @@ -416,41 +443,6 @@ struct cv::SoftCascade::Filds typedef std::vector::iterator octIt_t; - float rescale(const Feature& feature, const float scaling, const float relScale, - cv::Rect& scaledRect, const float threshold) const - { - scaledRect = feature.rect; - - dprintf("feature %d box %d %d %d %d\n", feature.channel, scaledRect.x, scaledRect.y, - scaledRect.width, scaledRect.height); - - dprintf("rescale: %d %f %f\n",feature.channel, relScale, scaling); - - float farea = (scaledRect.width - scaledRect.x) * (scaledRect.height - scaledRect.y); - // rescale - scaledRect.x = cvRound(relScale * scaledRect.x); - scaledRect.y = cvRound(relScale * scaledRect.y); - scaledRect.width = cvRound(relScale * scaledRect.width); - scaledRect.height = cvRound(relScale * scaledRect.height); - - dprintf("feature %d box %d %d %d %d\n", feature.channel, scaledRect.x, scaledRect.y, - scaledRect.width, scaledRect.height); - - float sarea = (scaledRect.width - scaledRect.x) * (scaledRect.height - scaledRect.y); - - const float expected_new_area = farea * relScale * relScale; - float approx = sarea / expected_new_area; - - dprintf(" rel areas %f %f\n", expected_new_area, sarea); - - // compensation areas rounding - float rootThreshold = threshold * approx * scaling; - - dprintf("approximation %f %f -> %f %f\n", approx, threshold, rootThreshold, scaling); - - return rootThreshold; - } - void detectAt(const Level& level, const int dx, const int dy, const ChannelStorage& storage, std::vector& detections) const { @@ -477,10 +469,9 @@ struct cv::SoftCascade::Filds // work with root node const Node& node = nodes[nId]; const Feature& feature = features[node.feature]; - cv::Rect scaledRect; - float threshold = rescale(feature, level.scaling[(int)(feature.channel > 6)], - level.relScale, scaledRect, node.threshold); + cv::Rect scaledRect(feature.rect); + float threshold = level.rescale(scaledRect, node.threshold,(int)(feature.channel > 6)) * feature.rarea; float sum = storage.get(dx, dy, feature.channel, scaledRect); @@ -494,10 +485,10 @@ struct cv::SoftCascade::Filds const Node& leaf = nodes[nId + next]; const Feature& fLeaf = features[leaf.feature]; - threshold = rescale(fLeaf, level.scaling[(int)(fLeaf.channel > 6)], - level.relScale, scaledRect, leaf.threshold); - sum = storage.get(dx, dy, fLeaf.channel, scaledRect); + scaledRect = fLeaf.rect; + threshold = level.rescale(scaledRect, leaf.threshold, (int)(fLeaf.channel > 6)) * fLeaf.rarea; + sum = storage.get(dx, dy, fLeaf.channel, scaledRect); int lShift = (next - 1) * 2 + ((sum >= threshold) ? 1 : 0); float impact = leaves[(st * 4) + lShift]; From 754fd7311b484aa05637a3d17aff509b79ae1209 Mon Sep 17 00:00:00 2001 From: "marina.kolpakova" Date: Sat, 6 Oct 2012 20:18:36 +0400 Subject: [PATCH 28/91] improve pointer usage --- modules/objdetect/src/softcascade.cpp | 59 +++++++++++---------------- 1 file changed, 23 insertions(+), 36 deletions(-) diff --git a/modules/objdetect/src/softcascade.cpp b/modules/objdetect/src/softcascade.cpp index 9eba9bd90..73639084d 100644 --- a/modules/objdetect/src/softcascade.cpp +++ b/modules/objdetect/src/softcascade.cpp @@ -226,11 +226,6 @@ struct Level float rescale(cv::Rect& scaledRect, const float threshold, int idx) const { // rescale - // scaledRect.x = cvRound(relScale * scaledRect.x); - // scaledRect.y = cvRound(relScale * scaledRect.y); - // scaledRect.width = cvRound(relScale * scaledRect.width); - // scaledRect.height = cvRound(relScale * scaledRect.height); - scaledRect.x = (scaleshift * scaledRect.x + R_SHIFT) >> 16; scaledRect.y = (scaleshift * scaledRect.y + R_SHIFT) >> 16; scaledRect.width = (scaleshift * scaledRect.width + R_SHIFT) >> 16; @@ -284,6 +279,8 @@ struct ChannelStorage { std::vector hog; int shrinkage; + int offset; + int step; enum {HOG_BINS = 6, HOG_LUV_BINS = 10}; @@ -391,31 +388,23 @@ struct ChannelStorage hog.push_back(mag); hog.insert(hog.end(), luvs.begin(), luvs.end()); - CV_Assert(hog.size() == 10); + + step = hog[0].cols; + + // CV_Assert(hog.size() == 10); #endif } - float get(const int x, const int y, const int channel, const cv::Rect& area) const + float get(const int channel, const cv::Rect& area) const { - CV_Assert(channel < HOG_LUV_BINS); + // CV_Assert(channel < HOG_LUV_BINS); const cv::Mat& m = hog[channel]; + int *ptr = ((int*)(m.data)) + offset; - dprintf("feature box %d %d %d %d ", area.x, area.y, area.width, area.height); - dprintf("get for channel %d\n", channel); - dprintf("!! %d\n", m.depth()); - - dprintf("extract feature for: [%d %d] [%d %d] [%d %d] [%d %d]\n", - x + area.x, y + area.y, x + area.width,y + area.y, x + area.width,y + area.height, - x + area.x, y + area.height); - - dprintf("at point %d %d with offset %d\n", x, y, 0); - - int a = m.ptr(y + area.y)[x + area.x]; - int b = m.ptr(y + area.y)[x + area.width]; - int c = m.ptr(y + area.height)[x + area.width]; - int d = m.ptr(y + area.height)[x + area.x]; - - dprintf(" retruved integral values: %d %d %d %d\n", a, b, c, d); + int a = ptr[area.y * step + area.x]; + int b = ptr[area.y * step + area.width]; + int c = ptr[area.height * step + area.width]; + int d = ptr[area.height * step + area.x]; return (a - b + c - d); } @@ -443,8 +432,7 @@ struct cv::SoftCascade::Filds typedef std::vector::iterator octIt_t; - void detectAt(const Level& level, const int dx, const int dy, const ChannelStorage& storage, - std::vector& detections) const + void detectAt(const int dx, const int dy, const Level& level, const ChannelStorage& storage, std::vector& detections) const { dprintf("detect at: %d %d\n", dx, dy); @@ -473,7 +461,7 @@ struct cv::SoftCascade::Filds float threshold = level.rescale(scaledRect, node.threshold,(int)(feature.channel > 6)) * feature.rarea; - float sum = storage.get(dx, dy, feature.channel, scaledRect); + float sum = storage.get(feature.channel, scaledRect); dprintf("root feature %d %f\n",feature.channel, sum); @@ -488,7 +476,7 @@ struct cv::SoftCascade::Filds scaledRect = fLeaf.rect; threshold = level.rescale(scaledRect, leaf.threshold, (int)(fLeaf.channel > 6)) * fLeaf.rarea; - sum = storage.get(dx, dy, fLeaf.channel, scaledRect); + sum = storage.get(fLeaf.channel, scaledRect); int lShift = (next - 1) * 2 + ((sum >= threshold) ? 1 : 0); float impact = leaves[(st * 4) + lShift]; @@ -506,16 +494,13 @@ struct cv::SoftCascade::Filds if (st - stBegin > 50 ) break; #endif - if (detectionScore <= stage.threshold) break; + if (detectionScore <= stage.threshold) return; } dprintf("x %d y %d: %d\n", dx, dy, st - stBegin); + dprintf(" got %d\n", st); - if (st == stEnd) - { - dprintf(" got %d\n", st); - level.markDetection(dx, dy, detectionScore, detections); - } + level.markDetection(dx, dy, detectionScore, detections); } octIt_t fitOctave(const float& logFactor) @@ -738,13 +723,15 @@ void cv::SoftCascade::detectMultiScale(const Mat& image, const std::vector Date: Sat, 6 Oct 2012 21:43:25 +0400 Subject: [PATCH 29/91] add Detection struct to interface --- .../include/opencv2/objdetect/objdetect.hpp | 12 +++++++++++- modules/objdetect/perf/perf_cascadeclassifier.cpp | 4 +++- modules/objdetect/src/softcascade.cpp | 4 ++-- modules/objdetect/test/test_softcascade.cpp | 3 ++- 4 files changed, 18 insertions(+), 5 deletions(-) diff --git a/modules/objdetect/include/opencv2/objdetect/objdetect.hpp b/modules/objdetect/include/opencv2/objdetect/objdetect.hpp index fd48b32ff..3724eaadb 100644 --- a/modules/objdetect/include/opencv2/objdetect/objdetect.hpp +++ b/modules/objdetect/include/opencv2/objdetect/objdetect.hpp @@ -493,6 +493,16 @@ protected: class CV_EXPORTS SoftCascade { public: + + struct CV_EXPORTS Detection + { + cv::Rect rect; + float confidence; + int kind; + + enum {PEDESTRIAN = 0}; + }; + //! An empty cascade will be created. SoftCascade(); @@ -511,7 +521,7 @@ public: virtual ~SoftCascade(); //! return vector of bounding boxes. Each box contains one detected object - virtual void detectMultiScale(const Mat& image, const std::vector& rois, std::vector& objects, + virtual void detectMultiScale(const Mat& image, const std::vector& rois, std::vector& objects, int rejectfactor = 1) const; protected: diff --git a/modules/objdetect/perf/perf_cascadeclassifier.cpp b/modules/objdetect/perf/perf_cascadeclassifier.cpp index cb214154c..271ede007 100644 --- a/modules/objdetect/perf/perf_cascadeclassifier.cpp +++ b/modules/objdetect/perf/perf_cascadeclassifier.cpp @@ -60,13 +60,15 @@ PERF_TEST_P(detect, SoftCascade, testing::Combine(testing::Values(std::string("cv/cascadeandhog/sc_cvpr_2012_to_opencv.xml")), testing::Values(std::string("cv/cascadeandhog/bahnhof/image_00000000_0.png")))) { + typedef cv::SoftCascade::Detection detection_t; cv::Mat colored = imread(getDataPath(get<1>(GetParam()))); ASSERT_FALSE(colored.empty()); cv::SoftCascade cascade; ASSERT_TRUE(cascade.load(getDataPath(get<0>(GetParam())))); - std::vector rois, objectBoxes; + std::vector rois; + std::vector objectBoxes; cascade.detectMultiScale(colored, rois, objectBoxes); TEST_CYCLE() diff --git a/modules/objdetect/src/softcascade.cpp b/modules/objdetect/src/softcascade.cpp index 73639084d..8d1853c72 100644 --- a/modules/objdetect/src/softcascade.cpp +++ b/modules/objdetect/src/softcascade.cpp @@ -685,10 +685,10 @@ bool cv::SoftCascade::load( const string& filename, const float minScale, const return true; } -//#define DEBUG_SHOW_RESULT +#define DEBUG_SHOW_RESULT void cv::SoftCascade::detectMultiScale(const Mat& image, const std::vector& /*rois*/, - std::vector& objects, const int /*rejectfactor*/) const + std::vector& objects, const int /*rejectfactor*/) const { typedef std::vector::const_iterator RIter_t; // only color images are supperted diff --git a/modules/objdetect/test/test_softcascade.cpp b/modules/objdetect/test/test_softcascade.cpp index 9c316fd90..00b45f02d 100644 --- a/modules/objdetect/test/test_softcascade.cpp +++ b/modules/objdetect/test/test_softcascade.cpp @@ -51,6 +51,7 @@ TEST(SoftCascade, readCascade) TEST(SoftCascade, detect) { + typedef cv::SoftCascade::Detection detection_t; std::string xml = cvtest::TS::ptr()->get_data_path() + "cascadeandhog/sc_cvpr_2012_to_opencv.xml"; cv::SoftCascade cascade; ASSERT_TRUE(cascade.load(xml)); @@ -58,7 +59,7 @@ TEST(SoftCascade, detect) cv::Mat colored = cv::imread(cvtest::TS::ptr()->get_data_path() + "cascadeandhog/bahnhof/image_00000000_0.png"); ASSERT_FALSE(colored.empty()); - std::vector objectBoxes; + std::vector objectBoxes; std::vector rois; rois.push_back(cv::Rect(0, 0, 640, 480)); // ASSERT_NO_THROW( From 565174378418b77d380dd09508d29732c4623b93 Mon Sep 17 00:00:00 2001 From: "marina.kolpakova" Date: Sat, 6 Oct 2012 22:22:53 +0400 Subject: [PATCH 30/91] remove debug imshow from code --- .../include/opencv2/objdetect/objdetect.hpp | 2 + modules/objdetect/src/softcascade.cpp | 44 ++++--------------- modules/objdetect/test/test_softcascade.cpp | 35 ++++++++++++--- 3 files changed, 40 insertions(+), 41 deletions(-) diff --git a/modules/objdetect/include/opencv2/objdetect/objdetect.hpp b/modules/objdetect/include/opencv2/objdetect/objdetect.hpp index 3724eaadb..f28d683e5 100644 --- a/modules/objdetect/include/opencv2/objdetect/objdetect.hpp +++ b/modules/objdetect/include/opencv2/objdetect/objdetect.hpp @@ -501,6 +501,8 @@ public: int kind; enum {PEDESTRIAN = 0}; + + Detection(const cv::Rect& r, const float c, int k = PEDESTRIAN) : rect(r), confidence(c), kind(k) {} }; //! An empty cascade will be created. diff --git a/modules/objdetect/src/softcascade.cpp b/modules/objdetect/src/softcascade.cpp index 8d1853c72..cec7741f2 100644 --- a/modules/objdetect/src/softcascade.cpp +++ b/modules/objdetect/src/softcascade.cpp @@ -204,6 +204,7 @@ struct Level enum { R_SHIFT = 1 << 15 }; float scaling[2]; + typedef cv::SoftCascade::Detection detection_t; Level(const Octave& oct, const float scale, const int shrinkage, const int w, const int h) : octave(&oct), origScale(scale), relScale(scale / oct.scale), shrScale (relScale / (float)shrinkage), @@ -215,12 +216,12 @@ struct Level scaleshift = relScale * (1 << 16); } - void markDetection(const int x, const int y, float confidence, std::vector& detections) const + void markDetection(const int x, const int y, float confidence, std::vector& detections) const { int shrinkage = (*octave).shrinkage; cv::Rect rect(cvRound(x * shrinkage), cvRound(y * shrinkage), objSize.width, objSize.height); - detections.push_back(Object(rect, confidence)); + detections.push_back(detection_t(rect, confidence)); } float rescale(cv::Rect& scaledRect, const float threshold, int idx) const @@ -432,7 +433,8 @@ struct cv::SoftCascade::Filds typedef std::vector::iterator octIt_t; - void detectAt(const int dx, const int dy, const Level& level, const ChannelStorage& storage, std::vector& detections) const + void detectAt(const int dx, const int dy, const Level& level, const ChannelStorage& storage, + std::vector& detections) const { dprintf("detect at: %d %d\n", dx, dy); @@ -685,12 +687,11 @@ bool cv::SoftCascade::load( const string& filename, const float minScale, const return true; } -#define DEBUG_SHOW_RESULT - void cv::SoftCascade::detectMultiScale(const Mat& image, const std::vector& /*rois*/, std::vector& objects, const int /*rejectfactor*/) const { typedef std::vector::const_iterator RIter_t; + // only color images are supperted CV_Assert(image.type() == CV_8UC3); @@ -704,49 +705,20 @@ void cv::SoftCascade::detectMultiScale(const Mat& image, const std::vector detections; - typedef std::vector::const_iterator lIt; - int total = 0, l = 0; + for (lIt it = fld.levels.begin(); it != fld.levels.end(); ++it) { const Level& level = *it; -#if defined WITH_DEBUG_OUT - std::cout << "================================ " << l++ << std::endl; -#else - (void)l; -#endif - // int dx = 79; int dy = 76; for (int dy = 0; dy < level.workRect.height; ++dy) { for (int dx = 0; dx < level.workRect.width; ++dx) { storage.offset = dy * storage.step + dx; - fld.detectAt(dx, dy, level, storage, detections); - - total++; + fld.detectAt(dx, dy, level, storage, objects); } } - -#if defined DEBUG_SHOW_RESULT - cv::Mat out = image.clone(); - - printf("TOTAL: %d from %d\n", (int)detections.size(),total) ; - - for(int i = 0; i < (int)detections.size(); ++i) - { - cv::rectangle(out, detections[i].rect, cv::Scalar(255, 0, 0, 255), 1); - } - - cv::imshow("out", out); - cv::waitKey(0); - std::cout << "work rect: " << level.workRect.width << " " << level.workRect.height << std::endl; -#endif - - detections.clear(); } - // std::swap(detections, objects); } \ No newline at end of file diff --git a/modules/objdetect/test/test_softcascade.cpp b/modules/objdetect/test/test_softcascade.cpp index 00b45f02d..59428ea5d 100644 --- a/modules/objdetect/test/test_softcascade.cpp +++ b/modules/objdetect/test/test_softcascade.cpp @@ -59,11 +59,36 @@ TEST(SoftCascade, detect) cv::Mat colored = cv::imread(cvtest::TS::ptr()->get_data_path() + "cascadeandhog/bahnhof/image_00000000_0.png"); ASSERT_FALSE(colored.empty()); - std::vector objectBoxes; + std::vector objects; std::vector rois; rois.push_back(cv::Rect(0, 0, 640, 480)); - // ASSERT_NO_THROW( - // { - cascade.detectMultiScale(colored, rois, objectBoxes); - // }); + + cascade.detectMultiScale(colored, rois, objects); + + std::cout << "detected: " << (int)objects.size() << std::endl; + + cv::Mat out = colored.clone(); + int level = 0, total = 0; + int levelWidth = objects[0].rect.width; + + for(int i = 0 ; i < (int)objects.size(); ++i) + { + if (objects[i].rect.width != levelWidth) + { + std::cout << "Level: " << level << " total " << total << std::endl; + cv::imshow("out", out); + cv::waitKey(0); + + out = colored.clone(); + levelWidth = objects[i].rect.width; + total = 0; + level++; + } + cv::rectangle(out, objects[i].rect, cv::Scalar(255, 0, 0, 255), 1); + std::cout << "detection: " << objects[i].rect.x + << " " << objects[i].rect.y + << " " << objects[i].rect.width + << " " << objects[i].rect.height << std::endl; + total++; + } } \ No newline at end of file From 3d41846c390fdbbe7ed85295bc0187a26af03cf6 Mon Sep 17 00:00:00 2001 From: "marina.kolpakova" Date: Wed, 24 Oct 2012 23:10:15 +0400 Subject: [PATCH 31/91] move frame processing into separate class --- .../include/opencv2/objdetect/objdetect.hpp | 22 +++ modules/objdetect/src/isf.cpp | 155 ++++++++++++++++++ 2 files changed, 177 insertions(+) create mode 100644 modules/objdetect/src/isf.cpp diff --git a/modules/objdetect/include/opencv2/objdetect/objdetect.hpp b/modules/objdetect/include/opencv2/objdetect/objdetect.hpp index f28d683e5..b56d5f1db 100644 --- a/modules/objdetect/include/opencv2/objdetect/objdetect.hpp +++ b/modules/objdetect/include/opencv2/objdetect/objdetect.hpp @@ -543,6 +543,28 @@ private: Filds* filds; }; +class CV_EXPORTS IntegralChannels +{ +public: + //! constrictor form resizing factor. + //! Param shr is a resizing factor. Resize is applied before integral sum computing + IntegralChannels(const int shr) : shrinkage(shr) {} + + //! Appends specified number of hog first order feature integrals into given vector. + //! Param gray is an input 1-chennel gray image. + //! Param integrals is a vector of integrals. Computed from frame frame hog-channels will be appended to it. + //! Param bins is a number of hog-bins + void createHogBins(const cv::Mat gray, std::vector& integrals, int bins) const; + + //! Converts 3-chennel BGR input frame to Luv and append each channel to the integrals. + //! Param frame is an input 3-chennel BGR colored image. + //! Param integrals is a vector of integrals. Computed from frame frame luv-channels will be appended to it. + void createLuvBins(const cv::Mat frame, std::vector& integrals) const; + +private: + int shrinkage; +}; + //////////////// HOG (Histogram-of-Oriented-Gradients) Descriptor and Object Detector ////////////// // struct for detection region of interest (ROI) diff --git a/modules/objdetect/src/isf.cpp b/modules/objdetect/src/isf.cpp new file mode 100644 index 000000000..48bfc89a8 --- /dev/null +++ b/modules/objdetect/src/isf.cpp @@ -0,0 +1,155 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2008-2012, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +#include +#include +#include + + +template +struct Decimate { + int shrinkage; + + Decimate(const int sr) : shrinkage(sr) {} + + void operator()(const cv::Mat& in, cv::Mat& out) const + { + int cols = in.cols / shrinkage; + int rows = in.rows / shrinkage; + out.create(rows, cols, in.type()); + + CV_Assert(cols * shrinkage == in.cols); + CV_Assert(rows * shrinkage == in.rows); + + for (int outIdx_y = 0; outIdx_y < rows; ++outIdx_y) + { + T* outPtr = out.ptr(outIdx_y); + for (int outIdx_x = 0; outIdx_x < cols; ++outIdx_x) + { + // do desimate + int inIdx_y = outIdx_y * shrinkage; + int inIdx_x = outIdx_x * shrinkage; + int sum = 0; + + for (int y = inIdx_y; y < inIdx_y + shrinkage; ++y) + for (int x = inIdx_x; x < inIdx_x + shrinkage; ++x) + sum += in.at(y, x); + + sum /= shrinkage * shrinkage; + outPtr[outIdx_x] = cv::saturate_cast(sum); + } + } + } + +}; + +void cv::IntegralChannels::createHogBins(const cv::Mat gray, std::vector& integrals, int bins) const +{ + CV_Assert(gray.type() == CV_8UC1); + int h = gray.rows; + int w = gray.cols; + CV_Assert(!(w % shrinkage) && !(h % shrinkage)); + + Decimate decimate(shrinkage); + + cv::Mat df_dx, df_dy, mag, angle; + cv::Sobel(gray, df_dx, CV_32F, 1, 0, 3, 0.125); + cv::Sobel(gray, df_dy, CV_32F, 0, 1, 3, 0.125); + + cv::cartToPolar(df_dx, df_dy, mag, angle, true); + mag *= (1.f / sqrt(2)); + + cv::Mat nmag; + mag.convertTo(nmag, CV_8UC1); + + angle /= 60.f; + + std::vector hist; + for (int bin = 0; bin < bins; ++bin) + hist.push_back(cv::Mat::zeros(h, w, CV_8UC1)); + + for (int y = 0; y < h; ++y) + { + uchar* magnitude = nmag.ptr(y); + float* ang = angle.ptr(y); + + for (int x = 0; x < w; ++x) + { + hist[ (int)ang[x] ].ptr(y)[x] = magnitude[x]; + } + } + + for(int i = 0; i < bins; ++i) + { + cv::Mat shrunk, sum; + decimate(hist[i], shrunk); + cv::integral(shrunk, sum, cv::noArray(), CV_32S); + integrals.push_back(sum); + } + + cv::Mat shrMag; + decimate(nmag, shrMag); + cv::integral(shrMag, mag, cv::noArray(), CV_32S); + integrals.push_back(mag); +} + +void cv::IntegralChannels::createLuvBins(const cv::Mat frame, std::vector& integrals) const +{ + CV_Assert(frame.type() == CV_8UC3); + CV_Assert(!(frame.cols % shrinkage) && !(frame.rows % shrinkage)); + + Decimate decimate(shrinkage); + + cv::Mat luv; + cv::cvtColor(frame, luv, CV_BGR2Luv); + + std::vector splited; + split(luv, splited); + + for (size_t i = 0; i < splited.size(); ++i) + { + cv::Mat shrunk, sum; + decimate(splited[i], shrunk); + cv::integral(shrunk, sum, cv::noArray(), CV_32S); + integrals.push_back(sum); + } +} \ No newline at end of file From 2d0fc80c9510fb75556e785f01840b6ee8293172 Mon Sep 17 00:00:00 2001 From: "marina.kolpakova" Date: Thu, 25 Oct 2012 01:56:22 +0400 Subject: [PATCH 32/91] use IntegralChannels class --- modules/objdetect/src/softcascade.cpp | 157 +------------------- modules/objdetect/test/test_softcascade.cpp | 3 +- 2 files changed, 6 insertions(+), 154 deletions(-) diff --git a/modules/objdetect/src/softcascade.cpp b/modules/objdetect/src/softcascade.cpp index cec7741f2..8d79b85e8 100644 --- a/modules/objdetect/src/softcascade.cpp +++ b/modules/objdetect/src/softcascade.cpp @@ -50,21 +50,6 @@ #include #include -// use previous stored integrals for regression testing -// #define USE_REFERENCE_VALUES - -#if defined USE_REFERENCE_VALUES - -namespace { - -char *itoa(long i, char* s, int /*dummy_radix*/) -{ - sprintf(s, "%ld", i); - return s; -} - -#endif - // used for noisy printfs // #define WITH_DEBUG_OUT @@ -235,47 +220,10 @@ struct Level float sarea = (scaledRect.width - scaledRect.x) * (scaledRect.height - scaledRect.y); // compensation areas rounding - return (threshold * scaling[idx] * sarea); + return (sarea == 0.0f)? threshold : (threshold * scaling[idx] * sarea); } }; -template< typename T> -struct Decimate { - int shrinkage; - - Decimate(const int sr) : shrinkage(sr) {} - - void operator()(const cv::Mat& in, cv::Mat& out) const - { - int cols = in.cols / shrinkage; - int rows = in.rows / shrinkage; - out.create(rows, cols, in.type()); - - CV_Assert(cols * shrinkage == in.cols); - CV_Assert(rows * shrinkage == in.rows); - - for (int outIdx_y = 0; outIdx_y < rows; ++outIdx_y) - { - T* outPtr = out.ptr(outIdx_y); - for (int outIdx_x = 0; outIdx_x < cols; ++outIdx_x) - { - // do desimate - int inIdx_y = outIdx_y * shrinkage; - int inIdx_x = outIdx_x * shrinkage; - int sum = 0; - - for (int y = inIdx_y; y < inIdx_y + shrinkage; ++y) - for (int x = inIdx_x; x < inIdx_x + shrinkage; ++x) - sum += in.at(y, x); - - sum /= shrinkage * shrinkage; - outPtr[outIdx_x] = cv::saturate_cast(sum); - } - } - } - -}; - struct ChannelStorage { std::vector hog; @@ -289,111 +237,16 @@ struct ChannelStorage ChannelStorage(const cv::Mat& colored, int shr) : shrinkage(shr) { hog.clear(); - Decimate decimate(shr); - -#if defined USE_REFERENCE_VALUES - char buff[33]; - cv::FileStorage imgs("/home/kellan/testInts.xml", cv::FileStorage::READ); - - for(int i = 0; i < HOG_LUV_BINS; ++i) - { - cv::Mat channel; - imgs[std::string("channel") + itoa(i, buff, 10)] >> channel; - hog.push_back(channel); - } -#else - // add gauss - cv::Mat gauss; - cv::GaussianBlur(colored, gauss, cv::Size(3,3), 0 ,0); - - // convert to luv - cv::Mat luv; - cv::cvtColor(colored, luv, CV_BGR2Luv); - - // split to 3 one channel matrix - std::vector splited, luvs; - split(luv, splited); - - // shrink and integrate - for (int i = 0; i < (int)splited.size(); i++) - { - cv::Mat shrunk, sum; - decimate(splited[i], shrunk); - cv::integral(shrunk, sum, cv::noArray(), CV_32S); - luvs.push_back(sum); - } + cv::IntegralChannels ints(shr); // convert to grey cv::Mat grey; cv::cvtColor(colored, grey, CV_BGR2GRAY); - // get derivative - cv::Mat df_dx, df_dy, mag, angle; - cv::Sobel(grey, df_dx, CV_32F, 1, 0); - cv::Sobel(grey, df_dy, CV_32F, 0, 1); - - // normalize - df_dx /= 4; - df_dy /= 4; - - // calculate magnitude - cv::cartToPolar(df_dx, df_dy, mag, angle, true); - - // normalize to avoid uchar overflow - static const float magnitudeScaling = 1.f / sqrt(2); - mag *= magnitudeScaling; - - // convert to uchar - cv::Mat saturatedMag(grey.rows, grey.cols, CV_8UC1), shrMag; - for (int y = 0; y < grey.rows; ++y) - { - float* rm = mag.ptr(y); - uchar* mg = saturatedMag.ptr(y); - for (int x = 0; x < grey.cols; ++x) - { - mg[x] = cv::saturate_cast(rm[x]); - } - } - - // srink and integrate - decimate(saturatedMag, shrMag); - cv::integral(shrMag, mag, cv::noArray(), CV_32S); - - // create hog channels - angle /= 60.f; - - std::vector hist; - for (int bin = 0; bin < HOG_BINS; ++bin) - { - hist.push_back(cv::Mat::zeros(saturatedMag.rows, saturatedMag.cols, CV_8UC1)); - } - - for (int y = 0; y < saturatedMag.rows; ++y) - { - uchar* magnitude = saturatedMag.ptr(y); - float* ang = angle.ptr(y); - - for (int x = 0; x < saturatedMag.cols; ++x) - { - hist[ (int)ang[x] ].ptr(y)[x] = magnitude[x]; - } - } - - for(int i = 0; i < HOG_BINS; ++i) - { - cv::Mat shrunk, sum; - decimate(hist[i], shrunk); - cv::integral(shrunk, sum, cv::noArray(), CV_32S); - hog.push_back(sum); - } - - hog.push_back(mag); - hog.insert(hog.end(), luvs.begin(), luvs.end()); + ints.createHogBins(grey, hog, 6); + ints.createLuvBins(colored, hog); step = hog[0].cols; - - // CV_Assert(hog.size() == 10); -#endif } float get(const int channel, const cv::Rect& area) const @@ -441,7 +294,7 @@ struct cv::SoftCascade::Filds float detectionScore = 0.f; const Octave& octave = *(level.octave); - int stBegin = octave.index * octave.stages, stEnd = stBegin + octave.stages; + int stBegin = octave.index * octave.stages, stEnd = stBegin + 1024;//octave.stages; dprintf(" octave stages: %d to %d index %d %f level %f\n", stBegin, stEnd, octave.index, octave.scale, level.origScale); diff --git a/modules/objdetect/test/test_softcascade.cpp b/modules/objdetect/test/test_softcascade.cpp index 59428ea5d..811ad2c5e 100644 --- a/modules/objdetect/test/test_softcascade.cpp +++ b/modules/objdetect/test/test_softcascade.cpp @@ -65,7 +65,6 @@ TEST(SoftCascade, detect) cascade.detectMultiScale(colored, rois, objects); - std::cout << "detected: " << (int)objects.size() << std::endl; cv::Mat out = colored.clone(); int level = 0, total = 0; @@ -78,7 +77,6 @@ TEST(SoftCascade, detect) std::cout << "Level: " << level << " total " << total << std::endl; cv::imshow("out", out); cv::waitKey(0); - out = colored.clone(); levelWidth = objects[i].rect.width; total = 0; @@ -91,4 +89,5 @@ TEST(SoftCascade, detect) << " " << objects[i].rect.height << std::endl; total++; } + std::cout << "detected: " << (int)objects.size() << std::endl; } \ No newline at end of file From 7b6da394f0ae87f1119cb1afabb740d7f85c423b Mon Sep 17 00:00:00 2001 From: "marina.kolpakova" Date: Thu, 25 Oct 2012 02:03:46 +0400 Subject: [PATCH 33/91] rename Stage to Weak because there is no such term for Soft Cascades --- modules/objdetect/src/softcascade.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/modules/objdetect/src/softcascade.cpp b/modules/objdetect/src/softcascade.cpp index 8d79b85e8..5e27e8831 100644 --- a/modules/objdetect/src/softcascade.cpp +++ b/modules/objdetect/src/softcascade.cpp @@ -85,17 +85,17 @@ const char *const Octave::SC_OCT_SCALE = "scale"; const char *const Octave::SC_OCT_STAGES = "stageNum"; const char *const Octave::SC_OCT_SHRINKAGE = "shrinkingFactor"; -struct Stage +struct Weak { float threshold; static const char *const SC_STAGE_THRESHOLD; - Stage(){} - Stage(const cv::FileNode& fn) : threshold((float)fn[SC_STAGE_THRESHOLD]){} + Weak(){} + Weak(const cv::FileNode& fn) : threshold((float)fn[SC_STAGE_THRESHOLD]){} }; -const char *const Stage::SC_STAGE_THRESHOLD = "stageThreshold"; +const char *const Weak::SC_STAGE_THRESHOLD = "stageThreshold"; struct Node { @@ -277,7 +277,7 @@ struct cv::SoftCascade::Filds int shrinkage; std::vector octaves; - std::vector stages; + std::vector stages; std::vector nodes; std::vector leaves; std::vector features; @@ -305,7 +305,7 @@ struct cv::SoftCascade::Filds dprintf("index: %d\n", st); - const Stage& stage = stages[st]; + const Weak& stage = stages[st]; { int nId = st * 3; @@ -481,7 +481,7 @@ struct cv::SoftCascade::Filds for (; st != st_end; ++st ) { fns = *st; - stages.push_back(Stage(fns)); + stages.push_back(Weak(fns)); fns = fns[SC_WEEK]; FileNodeIterator ftr = fns.begin(), ft_end = fns.end(); From 40c0c60e2bf8c30968ddf785b484f1a58033a428 Mon Sep 17 00:00:00 2001 From: "marina.kolpakova" Date: Thu, 25 Oct 2012 02:10:20 +0400 Subject: [PATCH 34/91] remove unused struct --- modules/objdetect/src/softcascade.cpp | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/modules/objdetect/src/softcascade.cpp b/modules/objdetect/src/softcascade.cpp index 5e27e8831..a155719bf 100644 --- a/modules/objdetect/src/softcascade.cpp +++ b/modules/objdetect/src/softcascade.cpp @@ -131,16 +131,6 @@ struct Feature const char * const Feature::SC_F_CHANNEL = "channel"; const char * const Feature::SC_F_RECT = "rect"; -struct Object -{ - enum Class{PEDESTRIAN}; - cv::Rect rect; - float confidence; - Class detType; - - Object(const cv::Rect& r, const float c, Class dt = PEDESTRIAN) : rect(r), confidence(c), detType(dt) {} -}; - struct CascadeIntrinsics { static const float lambda = 1.099f, a = 0.89f; From a22ee13620d8539be81bacf6d27bd0659e388e28 Mon Sep 17 00:00:00 2001 From: "marina.kolpakova" Date: Thu, 25 Oct 2012 09:10:11 +0400 Subject: [PATCH 35/91] rename markDetection to addDetection --- modules/objdetect/src/softcascade.cpp | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/modules/objdetect/src/softcascade.cpp b/modules/objdetect/src/softcascade.cpp index a155719bf..c70e80c00 100644 --- a/modules/objdetect/src/softcascade.cpp +++ b/modules/objdetect/src/softcascade.cpp @@ -135,12 +135,9 @@ struct CascadeIntrinsics { static const float lambda = 1.099f, a = 0.89f; - static float getFor(int channel, float scaling) + static float getFor(bool isUp, float scaling) { - CV_Assert(channel < 10); - if (fabs(scaling - 1.f) < FLT_EPSILON) - // if (scaling == 1.f) return 1.f; // according to R. Benenson, M. Mathias, R. Timofte and L. Van Gool's and Dallal's papers @@ -156,8 +153,8 @@ struct CascadeIntrinsics { 0.f, 2.f} // up }; - float a = A[(int)(scaling >= 1)][(int)(channel > 6)]; - float b = B[(int)(scaling >= 1)][(int)(channel > 6)]; + float a = A[(int)(scaling >= 1)][(int)(isUp)]; + float b = B[(int)(scaling >= 1)][(int)(isUp)]; dprintf("scaling: %f %f %f %f\n", scaling, a, b, a * pow(scaling, b)); return a * pow(scaling, b); @@ -170,7 +167,6 @@ struct Level float origScale; float relScale; - float shrScale; // used for marking detection int scaleshift; cv::Size workRect; @@ -182,16 +178,16 @@ struct Level typedef cv::SoftCascade::Detection detection_t; Level(const Octave& oct, const float scale, const int shrinkage, const int w, const int h) - : octave(&oct), origScale(scale), relScale(scale / oct.scale), shrScale (relScale / (float)shrinkage), + : octave(&oct), origScale(scale), relScale(scale / oct.scale), workRect(cv::Size(cvRound(w / (float)shrinkage),cvRound(h / (float)shrinkage))), objSize(cv::Size(cvRound(oct.size.width * relScale), cvRound(oct.size.height * relScale))) { - scaling[0] = CascadeIntrinsics::getFor(0, relScale) / (relScale * relScale); - scaling[1] = CascadeIntrinsics::getFor(9, relScale) / (relScale * relScale); + scaling[0] = CascadeIntrinsics::getFor(false, relScale) / (relScale * relScale); + scaling[1] = CascadeIntrinsics::getFor(true, relScale) / (relScale * relScale); scaleshift = relScale * (1 << 16); } - void markDetection(const int x, const int y, float confidence, std::vector& detections) const + void addDetection(const int x, const int y, float confidence, std::vector& detections) const { int shrinkage = (*octave).shrinkage; cv::Rect rect(cvRound(x * shrinkage), cvRound(y * shrinkage), objSize.width, objSize.height); @@ -345,7 +341,7 @@ struct cv::SoftCascade::Filds dprintf("x %d y %d: %d\n", dx, dy, st - stBegin); dprintf(" got %d\n", st); - level.markDetection(dx, dy, detectionScore, detections); + level.addDetection(dx, dy, detectionScore, detections); } octIt_t fitOctave(const float& logFactor) @@ -400,7 +396,6 @@ struct cv::SoftCascade::Filds << levels[sc].octave->scale << " " << levels[sc].relScale - << " " << levels[sc].shrScale << " [" << levels[sc].objSize.width << " " << levels[sc].objSize.height << "] [" << levels[sc].workRect.width << " " << levels[sc].workRect.height << "]" << std::endl; @@ -533,8 +528,6 @@ bool cv::SoftCascade::load( const string& filename, const float minScale, const void cv::SoftCascade::detectMultiScale(const Mat& image, const std::vector& /*rois*/, std::vector& objects, const int /*rejectfactor*/) const { - typedef std::vector::const_iterator RIter_t; - // only color images are supperted CV_Assert(image.type() == CV_8UC3); @@ -549,7 +542,6 @@ void cv::SoftCascade::detectMultiScale(const Mat& image, const std::vector::const_iterator lIt; - for (lIt it = fld.levels.begin(); it != fld.levels.end(); ++it) { const Level& level = *it; @@ -563,5 +555,4 @@ void cv::SoftCascade::detectMultiScale(const Mat& image, const std::vector Date: Thu, 25 Oct 2012 09:40:16 +0400 Subject: [PATCH 36/91] load SoftCascade from FileStorage --- .../include/opencv2/objdetect/objdetect.hpp | 18 +++++++++++------- .../objdetect/perf/perf_cascadeclassifier.cpp | 3 ++- modules/objdetect/src/softcascade.cpp | 11 +++++------ modules/objdetect/test/test_softcascade.cpp | 6 ++++-- 4 files changed, 22 insertions(+), 16 deletions(-) diff --git a/modules/objdetect/include/opencv2/objdetect/objdetect.hpp b/modules/objdetect/include/opencv2/objdetect/objdetect.hpp index b56d5f1db..85084a90c 100644 --- a/modules/objdetect/include/opencv2/objdetect/objdetect.hpp +++ b/modules/objdetect/include/opencv2/objdetect/objdetect.hpp @@ -500,25 +500,29 @@ public: float confidence; int kind; - enum {PEDESTRIAN = 0}; + enum {PEDESTRIAN = 1}; + //! Create detection from an object bounding rectangle and confidence. Only PEDESTRIAN type carrently supported. + //! Param r is a boundinf rectangle + //! param c is a confidence that object belongs to class k + //! Paral k is an object class Detection(const cv::Rect& r, const float c, int k = PEDESTRIAN) : rect(r), confidence(c), kind(k) {} }; //! An empty cascade will be created. SoftCascade(); - //! Cascade will be created from file for scales from minScale to maxScale. - //! Param filename is a path to xml-serialized cascade. + //! Cascade will be created for scales from minScale to maxScale. + //! Param fs is a serialized sacsade. //! Param minScale is a minimum scale relative to the original size of the image on which cascade will be applyed. //! Param minScale is a maximum scale relative to the original size of the image on which cascade will be applyed. - SoftCascade( const string& filename, const float minScale = 0.4f, const float maxScale = 5.f); + SoftCascade( const cv::FileStorage& fs, const float minScale = 0.4f, const float maxScale = 5.f); - //! cascade will be loaded from file "filename". The previous cascade will be destroyed. - //! Param filename is a path to xml-serialized cascade. + //! cascade will be loaded. The previous cascade will be destroyed. + //! Param fs is a serialized sacsade. //! Param minScale is a minimum scale relative to the original size of the image on which cascade will be applyed. //! Param minScale is a maximum scale relative to the original size of the image on which cascade will be applyed. - bool load( const string& filename, const float minScale = 0.4f, const float maxScale = 5.f); + bool read( const cv::FileStorage& fs, const float minScale = 0.4f, const float maxScale = 5.f); virtual ~SoftCascade(); diff --git a/modules/objdetect/perf/perf_cascadeclassifier.cpp b/modules/objdetect/perf/perf_cascadeclassifier.cpp index 271ede007..bf47d555c 100644 --- a/modules/objdetect/perf/perf_cascadeclassifier.cpp +++ b/modules/objdetect/perf/perf_cascadeclassifier.cpp @@ -65,7 +65,8 @@ PERF_TEST_P(detect, SoftCascade, ASSERT_FALSE(colored.empty()); cv::SoftCascade cascade; - ASSERT_TRUE(cascade.load(getDataPath(get<0>(GetParam())))); + cv::FileStorage fs(getDataPath(get<0>(GetParam())), cv::FileStorage::READ); + ASSERT_TRUE(cascade.read(fs)); std::vector rois; std::vector objectBoxes; diff --git a/modules/objdetect/src/softcascade.cpp b/modules/objdetect/src/softcascade.cpp index c70e80c00..7c735b21d 100644 --- a/modules/objdetect/src/softcascade.cpp +++ b/modules/objdetect/src/softcascade.cpp @@ -499,24 +499,23 @@ struct cv::SoftCascade::Filds cv::SoftCascade::SoftCascade() : filds(0) {} -cv::SoftCascade::SoftCascade( const string& filename, const float minScale, const float maxScale) : filds(0) +cv::SoftCascade::SoftCascade(const cv::FileStorage& fs, const float minScale, const float maxScale) : filds(0) { - load(filename, minScale, maxScale); + read(fs, minScale, maxScale); } cv::SoftCascade::~SoftCascade() { delete filds; } -bool cv::SoftCascade::load( const string& filename, const float minScale, const float maxScale) +bool cv::SoftCascade::read( const cv::FileStorage& fs, const float minScale, const float maxScale) { + if (!fs.isOpened()) return false; + if (filds) delete filds; filds = 0; - cv::FileStorage fs(filename, FileStorage::READ); - if (!fs.isOpened()) return false; - filds = new Filds; Filds& flds = *filds; if (!flds.fill(fs.getFirstTopLevelNode(), minScale, maxScale)) return false; diff --git a/modules/objdetect/test/test_softcascade.cpp b/modules/objdetect/test/test_softcascade.cpp index 811ad2c5e..b75db7371 100644 --- a/modules/objdetect/test/test_softcascade.cpp +++ b/modules/objdetect/test/test_softcascade.cpp @@ -45,7 +45,8 @@ TEST(SoftCascade, readCascade) { std::string xml = cvtest::TS::ptr()->get_data_path() + "cascadeandhog/icf-template.xml"; cv::SoftCascade cascade; - ASSERT_TRUE(cascade.load(xml)); + cv::FileStorage fs(xml, cv::FileStorage::READ); + ASSERT_TRUE(cascade.read(fs)); } @@ -54,7 +55,8 @@ TEST(SoftCascade, detect) typedef cv::SoftCascade::Detection detection_t; std::string xml = cvtest::TS::ptr()->get_data_path() + "cascadeandhog/sc_cvpr_2012_to_opencv.xml"; cv::SoftCascade cascade; - ASSERT_TRUE(cascade.load(xml)); + cv::FileStorage fs(xml, cv::FileStorage::READ); + ASSERT_TRUE(cascade.read(fs)); cv::Mat colored = cv::imread(cvtest::TS::ptr()->get_data_path() + "cascadeandhog/bahnhof/image_00000000_0.png"); ASSERT_FALSE(colored.empty()); From 16dd09ccfc5faf6686f19f628afd39a6671477c3 Mon Sep 17 00:00:00 2001 From: "marina.kolpakova" Date: Thu, 25 Oct 2012 12:22:54 +0400 Subject: [PATCH 37/91] move scale related parameters to SoftCascade constructor --- .../include/opencv2/objdetect/objdetect.hpp | 17 ++++++++++------- modules/objdetect/src/softcascade.cpp | 9 +++++---- modules/objdetect/test/test_softcascade.cpp | 1 + 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/modules/objdetect/include/opencv2/objdetect/objdetect.hpp b/modules/objdetect/include/opencv2/objdetect/objdetect.hpp index 85084a90c..53b2b1107 100644 --- a/modules/objdetect/include/opencv2/objdetect/objdetect.hpp +++ b/modules/objdetect/include/opencv2/objdetect/objdetect.hpp @@ -510,19 +510,18 @@ public: }; //! An empty cascade will be created. - SoftCascade(); + //! Param minScale is a minimum scale relative to the original size of the image on which cascade will be applyed. + //! 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. + SoftCascade( const float minScale = 0.4f, const float maxScale = 5.f, const int scales = 55); //! Cascade will be created for scales from minScale to maxScale. //! Param fs is a serialized sacsade. - //! Param minScale is a minimum scale relative to the original size of the image on which cascade will be applyed. - //! Param minScale is a maximum scale relative to the original size of the image on which cascade will be applyed. - SoftCascade( const cv::FileStorage& fs, const float minScale = 0.4f, const float maxScale = 5.f); + SoftCascade( const cv::FileStorage& fs); //! cascade will be loaded. The previous cascade will be destroyed. //! Param fs is a serialized sacsade. - //! Param minScale is a minimum scale relative to the original size of the image on which cascade will be applyed. - //! Param minScale is a maximum scale relative to the original size of the image on which cascade will be applyed. - bool read( const cv::FileStorage& fs, const float minScale = 0.4f, const float maxScale = 5.f); + bool read( const cv::FileStorage& fs); virtual ~SoftCascade(); @@ -545,6 +544,10 @@ protected: private: struct Filds; Filds* filds; + + float minScale; + float maxScale; + int scales; }; class CV_EXPORTS IntegralChannels diff --git a/modules/objdetect/src/softcascade.cpp b/modules/objdetect/src/softcascade.cpp index 7c735b21d..4cf72e3cd 100644 --- a/modules/objdetect/src/softcascade.cpp +++ b/modules/objdetect/src/softcascade.cpp @@ -497,18 +497,19 @@ struct cv::SoftCascade::Filds } }; -cv::SoftCascade::SoftCascade() : filds(0) {} +cv::SoftCascade::SoftCascade(const float mins, const float maxs, const int nsc) +: filds(0), minScale(mins), maxScale(maxs), scales(nsc) {} -cv::SoftCascade::SoftCascade(const cv::FileStorage& fs, const float minScale, const float maxScale) : filds(0) +cv::SoftCascade::SoftCascade(const cv::FileStorage& fs) : filds(0) { - read(fs, minScale, maxScale); + read(fs); } cv::SoftCascade::~SoftCascade() { delete filds; } -bool cv::SoftCascade::read( const cv::FileStorage& fs, const float minScale, const float maxScale) +bool cv::SoftCascade::read( const cv::FileStorage& fs) { if (!fs.isOpened()) return false; diff --git a/modules/objdetect/test/test_softcascade.cpp b/modules/objdetect/test/test_softcascade.cpp index b75db7371..aa72a9719 100644 --- a/modules/objdetect/test/test_softcascade.cpp +++ b/modules/objdetect/test/test_softcascade.cpp @@ -92,4 +92,5 @@ TEST(SoftCascade, detect) total++; } std::cout << "detected: " << (int)objects.size() << std::endl; + ASSERT_EQ((int)objects.size(), 1501); } \ No newline at end of file From 2e8ed773831abbd1c20d0fc19a67d55a65ec7a28 Mon Sep 17 00:00:00 2001 From: "marina.kolpakova" Date: Thu, 25 Oct 2012 14:50:48 +0400 Subject: [PATCH 38/91] get rid of hard-coded values --- .../include/opencv2/objdetect/objdetect.hpp | 12 --------- modules/objdetect/src/softcascade.cpp | 27 +++++++++++-------- 2 files changed, 16 insertions(+), 23 deletions(-) diff --git a/modules/objdetect/include/opencv2/objdetect/objdetect.hpp b/modules/objdetect/include/opencv2/objdetect/objdetect.hpp index 53b2b1107..cfc4f22f0 100644 --- a/modules/objdetect/include/opencv2/objdetect/objdetect.hpp +++ b/modules/objdetect/include/opencv2/objdetect/objdetect.hpp @@ -529,18 +529,6 @@ public: virtual void detectMultiScale(const Mat& image, const std::vector& rois, std::vector& objects, int rejectfactor = 1) const; -protected: - enum { BOOST = 0 }; - enum - { - FRAME_WIDTH = 640, - FRAME_HEIGHT = 480, - TOTAL_SCALES = 55, - CLASSIFIERS = 5, - ORIG_OBJECT_WIDTH = 64, - ORIG_OBJECT_HEIGHT = 128 - }; - private: struct Filds; Filds* filds; diff --git a/modules/objdetect/src/softcascade.cpp b/modules/objdetect/src/softcascade.cpp index 4cf72e3cd..c919fe2d0 100644 --- a/modules/objdetect/src/softcascade.cpp +++ b/modules/objdetect/src/softcascade.cpp @@ -270,6 +270,10 @@ struct cv::SoftCascade::Filds std::vector levels; + cv::Size frameSize; + + enum { BOOST = 0 }; + typedef std::vector::iterator octIt_t; void detectAt(const int dx, const int dy, const Level& level, const ChannelStorage& storage, @@ -364,8 +368,11 @@ struct cv::SoftCascade::Filds } // compute levels of full pyramid - void calcLevels(int frameW, int frameH, int scales) + void calcLevels(const cv::Size& curr, int scales) { + if (frameSize == curr) return; + frameSize = curr; + CV_Assert(scales > 1); levels.clear(); float logFactor = (log(maxScale) - log(minScale)) / (scales -1); @@ -373,8 +380,8 @@ struct cv::SoftCascade::Filds float scale = minScale; for (int sc = 0; sc < scales; ++sc) { - int width = std::max(0.0f, frameW - (origObjWidth * scale)); - int height = std::max(0.0f, frameH - (origObjHeight * scale)); + int width = std::max(0.0f, frameSize.width - (origObjWidth * scale)); + int height = std::max(0.0f, frameSize.height - (origObjHeight * scale)); float logScale = log(scale); octIt_t fit = fitOctave(logScale); @@ -434,11 +441,8 @@ struct cv::SoftCascade::Filds string featureTypeStr = (string)root[SC_FEATURE_TYPE]; CV_Assert(featureTypeStr == SC_ICF); - origObjWidth = (int)root[SC_ORIG_W]; - CV_Assert(origObjWidth == SoftCascade::ORIG_OBJECT_WIDTH); - + origObjWidth = (int)root[SC_ORIG_W]; origObjHeight = (int)root[SC_ORIG_H]; - CV_Assert(origObjHeight == SoftCascade::ORIG_OBJECT_HEIGHT); // for each octave (~ one cascade in classic OpenCV xml) FileNode fn = root[SC_OCTAVES]; @@ -451,7 +455,7 @@ struct cv::SoftCascade::Filds for (; it != it_end; ++it) { FileNode fns = *it; - Octave octave(octIndex, cv::Size(SoftCascade::ORIG_OBJECT_WIDTH, SoftCascade::ORIG_OBJECT_HEIGHT), fns); + Octave octave(octIndex, cv::Size(origObjWidth, origObjHeight), fns); CV_Assert(octave.stages > 0); octaves.push_back(octave); @@ -520,7 +524,7 @@ bool cv::SoftCascade::read( const cv::FileStorage& fs) filds = new Filds; Filds& flds = *filds; if (!flds.fill(fs.getFirstTopLevelNode(), minScale, maxScale)) return false; - flds.calcLevels(FRAME_WIDTH, FRAME_HEIGHT, TOTAL_SCALES); + // flds.calcLevels(FRAME_WIDTH, FRAME_HEIGHT, scales); return true; } @@ -534,9 +538,10 @@ void cv::SoftCascade::detectMultiScale(const Mat& image, const std::vector Date: Thu, 1 Nov 2012 06:11:09 +0400 Subject: [PATCH 39/91] brief soft cascade interface description --- .../include/opencv2/objdetect/objdetect.hpp | 22 ++++++++++++++----- modules/objdetect/src/softcascade.cpp | 2 +- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/modules/objdetect/include/opencv2/objdetect/objdetect.hpp b/modules/objdetect/include/opencv2/objdetect/objdetect.hpp index cfc4f22f0..e0799f9b1 100644 --- a/modules/objdetect/include/opencv2/objdetect/objdetect.hpp +++ b/modules/objdetect/include/opencv2/objdetect/objdetect.hpp @@ -488,25 +488,31 @@ protected: Ptr maskGenerator; }; -// ======================== soft cascade version ===================== // - +/** + * \class SoftCascade + * \brief Implement soft (stageless) cascade. + */ class CV_EXPORTS SoftCascade { public: + /** + * \class Detection + * \brief Soft cascade detector result represintation. + */ struct CV_EXPORTS Detection { - cv::Rect rect; - float confidence; - int kind; - enum {PEDESTRIAN = 1}; //! Create detection from an object bounding rectangle and confidence. Only PEDESTRIAN type carrently supported. //! Param r is a boundinf rectangle //! param c is a confidence that object belongs to class k //! Paral k is an object class + Detection(const cv::Rect& r, const float c, int k = PEDESTRIAN) : rect(r), confidence(c), kind(k) {} + cv::Rect rect; + float confidence; + int kind; }; //! An empty cascade will be created. @@ -538,6 +544,10 @@ private: int scales; }; +/** + * \class IntegralChannels + * \brief Create channel integrals for Soft Cascade detector. + */ class CV_EXPORTS IntegralChannels { public: diff --git a/modules/objdetect/src/softcascade.cpp b/modules/objdetect/src/softcascade.cpp index c919fe2d0..f3625f5d0 100644 --- a/modules/objdetect/src/softcascade.cpp +++ b/modules/objdetect/src/softcascade.cpp @@ -55,7 +55,7 @@ #if defined WITH_DEBUG_OUT # define dprintf(format, ...) \ - do { printf(format, __VA_ARGS__); } while (0) + do { printf(format, ##__VA_ARGS__); } while (0) #else # define dprintf(format, ...) #endif From 3cb9afb4e760ccf1b20731c6def12437129ca81d Mon Sep 17 00:00:00 2001 From: "marina.kolpakova" Date: Thu, 1 Nov 2012 14:26:28 +0400 Subject: [PATCH 40/91] test update because changed Sobel Normalization --- modules/objdetect/test/test_softcascade.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/objdetect/test/test_softcascade.cpp b/modules/objdetect/test/test_softcascade.cpp index aa72a9719..dfa02c02b 100644 --- a/modules/objdetect/test/test_softcascade.cpp +++ b/modules/objdetect/test/test_softcascade.cpp @@ -92,5 +92,5 @@ TEST(SoftCascade, detect) total++; } std::cout << "detected: " << (int)objects.size() << std::endl; - ASSERT_EQ((int)objects.size(), 1501); + ASSERT_EQ((int)objects.size(), 1469); } \ No newline at end of file From ff8417db006279db294d4c6810880300c2502f21 Mon Sep 17 00:00:00 2001 From: "marina.kolpakova" Date: Thu, 1 Nov 2012 15:43:50 +0400 Subject: [PATCH 41/91] remove input frame size constraints --- .../objdetect/perf/perf_cascadeclassifier.cpp | 18 ++++++- modules/objdetect/src/isf.cpp | 48 ++----------------- modules/objdetect/src/softcascade.cpp | 18 +------ modules/objdetect/test/test_softcascade.cpp | 48 +++++++++---------- 4 files changed, 45 insertions(+), 87 deletions(-) diff --git a/modules/objdetect/perf/perf_cascadeclassifier.cpp b/modules/objdetect/perf/perf_cascadeclassifier.cpp index bf47d555c..f91f2f8ec 100644 --- a/modules/objdetect/perf/perf_cascadeclassifier.cpp +++ b/modules/objdetect/perf/perf_cascadeclassifier.cpp @@ -56,6 +56,18 @@ PERF_TEST_P(ImageName_MinSize, CascadeClassifierLBPFrontalFace, typedef std::tr1::tuple fixture; typedef perf::TestBaseWithParam detect; + +namespace { + typedef cv::SoftCascade::Detection detection_t; + + void extractRacts(std::vector objectBoxes, vector rects) + { + rects.clear(); + for (int i = 0; i < (int)objectBoxes.size(); ++i) + rects.push_back(objectBoxes[i].rect); + } +} + PERF_TEST_P(detect, SoftCascade, testing::Combine(testing::Values(std::string("cv/cascadeandhog/sc_cvpr_2012_to_opencv.xml")), testing::Values(std::string("cv/cascadeandhog/bahnhof/image_00000000_0.png")))) @@ -76,5 +88,9 @@ PERF_TEST_P(detect, SoftCascade, { cascade.detectMultiScale(colored, rois, objectBoxes); } - SANITY_CHECK(objectBoxes); + + vector rects; + extractRacts(objectBoxes, rects); + std::sort(rects.begin(), rects.end(), comparators::RectLess()); + SANITY_CHECK(rects); } diff --git a/modules/objdetect/src/isf.cpp b/modules/objdetect/src/isf.cpp index 48bfc89a8..bbf4f27c0 100644 --- a/modules/objdetect/src/isf.cpp +++ b/modules/objdetect/src/isf.cpp @@ -44,44 +44,6 @@ #include #include - -template -struct Decimate { - int shrinkage; - - Decimate(const int sr) : shrinkage(sr) {} - - void operator()(const cv::Mat& in, cv::Mat& out) const - { - int cols = in.cols / shrinkage; - int rows = in.rows / shrinkage; - out.create(rows, cols, in.type()); - - CV_Assert(cols * shrinkage == in.cols); - CV_Assert(rows * shrinkage == in.rows); - - for (int outIdx_y = 0; outIdx_y < rows; ++outIdx_y) - { - T* outPtr = out.ptr(outIdx_y); - for (int outIdx_x = 0; outIdx_x < cols; ++outIdx_x) - { - // do desimate - int inIdx_y = outIdx_y * shrinkage; - int inIdx_x = outIdx_x * shrinkage; - int sum = 0; - - for (int y = inIdx_y; y < inIdx_y + shrinkage; ++y) - for (int x = inIdx_x; x < inIdx_x + shrinkage; ++x) - sum += in.at(y, x); - - sum /= shrinkage * shrinkage; - outPtr[outIdx_x] = cv::saturate_cast(sum); - } - } - } - -}; - void cv::IntegralChannels::createHogBins(const cv::Mat gray, std::vector& integrals, int bins) const { CV_Assert(gray.type() == CV_8UC1); @@ -89,8 +51,6 @@ void cv::IntegralChannels::createHogBins(const cv::Mat gray, std::vector decimate(shrinkage); - cv::Mat df_dx, df_dy, mag, angle; cv::Sobel(gray, df_dx, CV_32F, 1, 0, 3, 0.125); cv::Sobel(gray, df_dy, CV_32F, 0, 1, 3, 0.125); @@ -121,13 +81,13 @@ void cv::IntegralChannels::createHogBins(const cv::Mat gray, std::vector decimate(shrinkage); - cv::Mat luv; cv::cvtColor(frame, luv, CV_BGR2Luv); @@ -148,7 +106,7 @@ void cv::IntegralChannels::createLuvBins(const cv::Mat frame, std::vectorscale - << " " - << levels[sc].relScale - << " [" << levels[sc].objSize.width - << " " << levels[sc].objSize.height << "] [" - << levels[sc].workRect.width << " " << levels[sc].workRect.height << "]" << std::endl; } } @@ -523,10 +513,7 @@ bool cv::SoftCascade::read( const cv::FileStorage& fs) filds = new Filds; Filds& flds = *filds; - if (!flds.fill(fs.getFirstTopLevelNode(), minScale, maxScale)) return false; - // flds.calcLevels(FRAME_WIDTH, FRAME_HEIGHT, scales); - - return true; + return flds.fill(fs.getFirstTopLevelNode(), minScale, maxScale); } void cv::SoftCascade::detectMultiScale(const Mat& image, const std::vector& /*rois*/, @@ -535,9 +522,6 @@ void cv::SoftCascade::detectMultiScale(const Mat& image, const std::vector Date: Wed, 7 Nov 2012 13:49:09 +0800 Subject: [PATCH 42/91] fix the compilation bug of main.cpp in perf test and accuracy test on ocl module. It caused by the incompatibility of command line parser class in core.hpp between master branch and 2.4 branch. --- modules/ocl/perf/main.cpp | 54 +++++++++------------------------------ modules/ocl/test/main.cpp | 22 ++++++++-------- 2 files changed, 23 insertions(+), 53 deletions(-) diff --git a/modules/ocl/perf/main.cpp b/modules/ocl/perf/main.cpp index fb8013635..663bc197a 100644 --- a/modules/ocl/perf/main.cpp +++ b/modules/ocl/perf/main.cpp @@ -79,77 +79,47 @@ int main(int argc, char **argv) TS::ptr()->init("ocl"); InitGoogleTest(&argc, argv); const char *keys = - - "{ h | help | false | print help message }" - - "{ w | workdir | ../../../samples/c/| set working directory }" - - "{ t | type | gpu | set device type:cpu or gpu}" - - "{ p | platform | 0 | set platform id }" - - "{ d | device | 0 | set device id }"; - - + "{ h | false | print help message }" + "{ w | ../../../samples/c/| set working directory i.e. -w=C:\\}" + "{ t | gpu | set device type:i.e. -t=cpu or gpu}" + "{ p | 0 | set platform id i.e. -p=0}" + "{ d | 0 | set device id i.e. -d=0}"; CommandLineParser cmd(argc, argv, keys); - - if (cmd.get("help")) - + if (cmd.get("h")=="true") { - cout << "Avaible options besides goole test option:" << endl; - - cmd.printParams(); + cmd.printMessage(); + return 0; } - - workdir = cmd.get("workdir"); - - string type = cmd.get("type"); - - unsigned int pid = cmd.get("platform"); - - int device = cmd.get("device"); - - + workdir = cmd.get("w"); + string type = cmd.get("t"); + unsigned int pid = cmd.get("p"); + int device = cmd.get("d"); print_info(); int flag = CVCL_DEVICE_TYPE_GPU; if(type == "cpu") - { - flag = CVCL_DEVICE_TYPE_CPU; - } std::vector oclinfo; int devnums = getDevice(oclinfo); if(devnums <= device || device < 0) - { - std::cout << "device invalid\n"; - return -1; - } if(pid >= oclinfo.size()) - { - std::cout << "platform invalid\n"; - return -1; - } if(pid != 0 || device != 0) - { - setDevice(oclinfo[pid], device); - } cout << "Device type:" << type << endl << "Device name:" << oclinfo[pid].DeviceName[device] << endl; diff --git a/modules/ocl/test/main.cpp b/modules/ocl/test/main.cpp index 856828d6a..d3273f7fe 100644 --- a/modules/ocl/test/main.cpp +++ b/modules/ocl/test/main.cpp @@ -79,23 +79,23 @@ int main(int argc, char **argv) TS::ptr()->init("ocl"); InitGoogleTest(&argc, argv); const char *keys = - "{ h | help | false | print help message }" - "{ w | workdir | ../../../samples/c/| set working directory }" - "{ t | type | gpu | set device type:cpu or gpu}" - "{ p | platform | 0 | set platform id }" - "{ d | device | 0 | set device id }"; + "{ h | false | print help message }" + "{ w | ../../../samples/c/| set working directory i.e. -w=C:\\}" + "{ t | gpu | set device type:i.e. -t=cpu or gpu}" + "{ p | 0 | set platform id i.e. -p=0}" + "{ d | 0 | set device id i.e. -d=0}"; CommandLineParser cmd(argc, argv, keys); - if (cmd.get("help")) + if (cmd.get("h")=="true") { cout << "Avaible options besides goole test option:" << endl; - cmd.printParams(); + cmd.printMessage(); return 0; } - workdir = cmd.get("workdir"); - string type = cmd.get("type"); - unsigned int pid = cmd.get("platform"); - int device = cmd.get("device"); + workdir = cmd.get("w"); + string type = cmd.get("t"); + unsigned int pid = cmd.get("p"); + int device = cmd.get("d"); print_info(); int flag = CVCL_DEVICE_TYPE_GPU; From 95b7f5c46cf935581e32d56b408324869378b8ca Mon Sep 17 00:00:00 2001 From: Alexander Smorkalov Date: Wed, 7 Nov 2012 13:27:33 +0400 Subject: [PATCH 43/91] Face Detection sample namespace replaced on org.opencv.facedetect for consistency with Google Play. --- .../face-detection/AndroidManifest.xml | 2 +- .../jni/DetectionBasedTracker_jni.cpp | 50 +++++++++---------- .../jni/DetectionBasedTracker_jni.h | 12 ++--- .../DetectionBasedTracker.java | 2 +- .../{fd => facedetect}/FdActivity.java | 2 +- .../samples/{fd => facedetect}/FpsMeter.java | 2 +- 6 files changed, 35 insertions(+), 35 deletions(-) rename samples/android/face-detection/src/org/opencv/samples/{fd => facedetect}/DetectionBasedTracker.java (96%) rename samples/android/face-detection/src/org/opencv/samples/{fd => facedetect}/FdActivity.java (99%) rename samples/android/face-detection/src/org/opencv/samples/{fd => facedetect}/FpsMeter.java (97%) diff --git a/samples/android/face-detection/AndroidManifest.xml b/samples/android/face-detection/AndroidManifest.xml index eaa90dfd0..a52dc660e 100644 --- a/samples/android/face-detection/AndroidManifest.xml +++ b/samples/android/face-detection/AndroidManifest.xml @@ -1,6 +1,6 @@ diff --git a/samples/android/face-detection/jni/DetectionBasedTracker_jni.cpp b/samples/android/face-detection/jni/DetectionBasedTracker_jni.cpp index 33ee8e7a5..417fea522 100644 --- a/samples/android/face-detection/jni/DetectionBasedTracker_jni.cpp +++ b/samples/android/face-detection/jni/DetectionBasedTracker_jni.cpp @@ -65,15 +65,15 @@ struct DetectorAgregator } }; -JNIEXPORT jlong JNICALL Java_org_opencv_samples_fd_DetectionBasedTracker_nativeCreateObject +JNIEXPORT jlong JNICALL Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeCreateObject (JNIEnv * jenv, jclass, jstring jFileName, jint faceSize) { - LOGD("Java_org_opencv_samples_fd_DetectionBasedTracker_nativeCreateObject enter"); + LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeCreateObject enter"); const char* jnamestr = jenv->GetStringUTFChars(jFileName, NULL); string stdFileName(jnamestr); jlong result = 0; - LOGD("Java_org_opencv_samples_fd_DetectionBasedTracker_nativeCreateObject"); + LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeCreateObject"); try { @@ -98,18 +98,18 @@ JNIEXPORT jlong JNICALL Java_org_opencv_samples_fd_DetectionBasedTracker_nativeC { LOGD("nativeCreateObject catched unknown exception"); jclass je = jenv->FindClass("java/lang/Exception"); - jenv->ThrowNew(je, "Unknown exception in JNI code {Java_org_opencv_samples_fd_DetectionBasedTracker_nativeCreateObject(...)}"); + jenv->ThrowNew(je, "Unknown exception in JNI code {Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeCreateObject(...)}"); return 0; } - LOGD("Java_org_opencv_samples_fd_DetectionBasedTracker_nativeCreateObject exit"); + LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeCreateObject exit"); return result; } -JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBasedTracker_nativeDestroyObject +JNIEXPORT void JNICALL Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeDestroyObject (JNIEnv * jenv, jclass, jlong thiz) { - LOGD("Java_org_opencv_samples_fd_DetectionBasedTracker_nativeDestroyObject"); + LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeDestroyObject"); try { @@ -131,15 +131,15 @@ JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBasedTracker_nativeDe { LOGD("nativeDestroyObject catched unknown exception"); jclass je = jenv->FindClass("java/lang/Exception"); - jenv->ThrowNew(je, "Unknown exception in JNI code {Java_org_opencv_samples_fd_DetectionBasedTracker_nativeDestroyObject(...)}"); + jenv->ThrowNew(je, "Unknown exception in JNI code {Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeDestroyObject(...)}"); } - LOGD("Java_org_opencv_samples_fd_DetectionBasedTracker_nativeDestroyObject exit"); + LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeDestroyObject exit"); } -JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBasedTracker_nativeStart +JNIEXPORT void JNICALL Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeStart (JNIEnv * jenv, jclass, jlong thiz) { - LOGD("Java_org_opencv_samples_fd_DetectionBasedTracker_nativeStart"); + LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeStart"); try { @@ -157,15 +157,15 @@ JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBasedTracker_nativeSt { LOGD("nativeStart catched unknown exception"); jclass je = jenv->FindClass("java/lang/Exception"); - jenv->ThrowNew(je, "Unknown exception in JNI code {Java_org_opencv_samples_fd_DetectionBasedTracker_nativeStart(...)}"); + jenv->ThrowNew(je, "Unknown exception in JNI code {Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeStart(...)}"); } - LOGD("Java_org_opencv_samples_fd_DetectionBasedTracker_nativeStart exit"); + LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeStart exit"); } -JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBasedTracker_nativeStop +JNIEXPORT void JNICALL Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeStop (JNIEnv * jenv, jclass, jlong thiz) { - LOGD("Java_org_opencv_samples_fd_DetectionBasedTracker_nativeStop"); + LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeStop"); try { @@ -183,15 +183,15 @@ JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBasedTracker_nativeSt { LOGD("nativeStop catched unknown exception"); jclass je = jenv->FindClass("java/lang/Exception"); - jenv->ThrowNew(je, "Unknown exception in JNI code {Java_org_opencv_samples_fd_DetectionBasedTracker_nativeStop(...)}"); + jenv->ThrowNew(je, "Unknown exception in JNI code {Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeStop(...)}"); } - LOGD("Java_org_opencv_samples_fd_DetectionBasedTracker_nativeStop exit"); + LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeStop exit"); } -JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBasedTracker_nativeSetFaceSize +JNIEXPORT void JNICALL Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeSetFaceSize (JNIEnv * jenv, jclass, jlong thiz, jint faceSize) { - LOGD("Java_org_opencv_samples_fd_DetectionBasedTracker_nativeSetFaceSize -- BEGIN"); + LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeSetFaceSize -- BEGIN"); try { @@ -213,16 +213,16 @@ JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBasedTracker_nativeSe { LOGD("nativeSetFaceSize catched unknown exception"); jclass je = jenv->FindClass("java/lang/Exception"); - jenv->ThrowNew(je, "Unknown exception in JNI code {Java_org_opencv_samples_fd_DetectionBasedTracker_nativeSetFaceSize(...)}"); + jenv->ThrowNew(je, "Unknown exception in JNI code {Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeSetFaceSize(...)}"); } - LOGD("Java_org_opencv_samples_fd_DetectionBasedTracker_nativeSetFaceSize -- END"); + LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeSetFaceSize -- END"); } -JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBasedTracker_nativeDetect +JNIEXPORT void JNICALL Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeDetect (JNIEnv * jenv, jclass, jlong thiz, jlong imageGray, jlong faces) { - LOGD("Java_org_opencv_samples_fd_DetectionBasedTracker_nativeDetect"); + LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeDetect"); try { @@ -243,7 +243,7 @@ JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBasedTracker_nativeDe { LOGD("nativeDetect catched unknown exception"); jclass je = jenv->FindClass("java/lang/Exception"); - jenv->ThrowNew(je, "Unknown exception in JNI code {Java_org_opencv_samples_fd_DetectionBasedTracker_nativeDetect(...)}"); + jenv->ThrowNew(je, "Unknown exception in JNI code {Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeDetect(...)}"); } - LOGD("Java_org_opencv_samples_fd_DetectionBasedTracker_nativeDetect END"); + LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeDetect END"); } diff --git a/samples/android/face-detection/jni/DetectionBasedTracker_jni.h b/samples/android/face-detection/jni/DetectionBasedTracker_jni.h index 7ae94c3dd..7e0541d81 100644 --- a/samples/android/face-detection/jni/DetectionBasedTracker_jni.h +++ b/samples/android/face-detection/jni/DetectionBasedTracker_jni.h @@ -12,7 +12,7 @@ extern "C" { * Method: nativeCreateObject * Signature: (Ljava/lang/String;F)J */ -JNIEXPORT jlong JNICALL Java_org_opencv_samples_fd_DetectionBasedTracker_nativeCreateObject +JNIEXPORT jlong JNICALL Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeCreateObject (JNIEnv *, jclass, jstring, jint); /* @@ -20,7 +20,7 @@ JNIEXPORT jlong JNICALL Java_org_opencv_samples_fd_DetectionBasedTracker_nativeC * Method: nativeDestroyObject * Signature: (J)V */ -JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBasedTracker_nativeDestroyObject +JNIEXPORT void JNICALL Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeDestroyObject (JNIEnv *, jclass, jlong); /* @@ -28,7 +28,7 @@ JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBasedTracker_nativeDe * Method: nativeStart * Signature: (J)V */ -JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBasedTracker_nativeStart +JNIEXPORT void JNICALL Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeStart (JNIEnv *, jclass, jlong); /* @@ -36,7 +36,7 @@ JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBasedTracker_nativeSt * Method: nativeStop * Signature: (J)V */ -JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBasedTracker_nativeStop +JNIEXPORT void JNICALL Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeStop (JNIEnv *, jclass, jlong); /* @@ -44,7 +44,7 @@ JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBasedTracker_nativeSt * Method: nativeSetFaceSize * Signature: (JI)V */ - JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBasedTracker_nativeSetFaceSize + JNIEXPORT void JNICALL Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeSetFaceSize (JNIEnv *, jclass, jlong, jint); /* @@ -52,7 +52,7 @@ JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBasedTracker_nativeSt * Method: nativeDetect * Signature: (JJJ)V */ -JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBasedTracker_nativeDetect +JNIEXPORT void JNICALL Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeDetect (JNIEnv *, jclass, jlong, jlong, jlong); #ifdef __cplusplus diff --git a/samples/android/face-detection/src/org/opencv/samples/fd/DetectionBasedTracker.java b/samples/android/face-detection/src/org/opencv/samples/facedetect/DetectionBasedTracker.java similarity index 96% rename from samples/android/face-detection/src/org/opencv/samples/fd/DetectionBasedTracker.java rename to samples/android/face-detection/src/org/opencv/samples/facedetect/DetectionBasedTracker.java index 9e4600543..6179f1bdc 100644 --- a/samples/android/face-detection/src/org/opencv/samples/fd/DetectionBasedTracker.java +++ b/samples/android/face-detection/src/org/opencv/samples/facedetect/DetectionBasedTracker.java @@ -1,4 +1,4 @@ -package org.opencv.samples.fd; +package org.opencv.samples.facedetect; import org.opencv.core.Mat; import org.opencv.core.MatOfRect; diff --git a/samples/android/face-detection/src/org/opencv/samples/fd/FdActivity.java b/samples/android/face-detection/src/org/opencv/samples/facedetect/FdActivity.java similarity index 99% rename from samples/android/face-detection/src/org/opencv/samples/fd/FdActivity.java rename to samples/android/face-detection/src/org/opencv/samples/facedetect/FdActivity.java index 9470a8fd1..2b949629c 100644 --- a/samples/android/face-detection/src/org/opencv/samples/fd/FdActivity.java +++ b/samples/android/face-detection/src/org/opencv/samples/facedetect/FdActivity.java @@ -1,4 +1,4 @@ -package org.opencv.samples.fd; +package org.opencv.samples.facedetect; import java.io.File; import java.io.FileOutputStream; diff --git a/samples/android/face-detection/src/org/opencv/samples/fd/FpsMeter.java b/samples/android/face-detection/src/org/opencv/samples/facedetect/FpsMeter.java similarity index 97% rename from samples/android/face-detection/src/org/opencv/samples/fd/FpsMeter.java rename to samples/android/face-detection/src/org/opencv/samples/facedetect/FpsMeter.java index 2c8f3bc7b..2438bf89a 100644 --- a/samples/android/face-detection/src/org/opencv/samples/fd/FpsMeter.java +++ b/samples/android/face-detection/src/org/opencv/samples/facedetect/FpsMeter.java @@ -1,4 +1,4 @@ -package org.opencv.samples.fd; +package org.opencv.samples.facedetect; import java.text.DecimalFormat; From a0be7b57f53ea26cffe8b4560dcf647b450d5a72 Mon Sep 17 00:00:00 2001 From: Vladislav Vinogradov Date: Wed, 7 Nov 2012 17:13:19 +0400 Subject: [PATCH 44/91] fixed bug in gpu::PyrLKOpticalFlow::dense vector index out of range --- modules/gpu/src/pyrlk.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/modules/gpu/src/pyrlk.cpp b/modules/gpu/src/pyrlk.cpp index fc585f4de..9b6ab0821 100644 --- a/modules/gpu/src/pyrlk.cpp +++ b/modules/gpu/src/pyrlk.cpp @@ -200,6 +200,9 @@ void cv::gpu::PyrLKOpticalFlow::dense(const GpuMat& prevImg, const GpuMat& nextI pyrDown(nextPyr_[level - 1], nextPyr_[level]); } + uPyr_.resize(2); + vPyr_.resize(2); + ensureSizeIsEnough(prevImg.size(), CV_32FC1, uPyr_[0]); ensureSizeIsEnough(prevImg.size(), CV_32FC1, vPyr_[0]); ensureSizeIsEnough(prevImg.size(), CV_32FC1, uPyr_[1]); From 4a1c4a98621577b02b43cff9afe33dab50faccf2 Mon Sep 17 00:00:00 2001 From: "marina.kolpakova" Date: Mon, 5 Nov 2012 22:42:08 +0400 Subject: [PATCH 45/91] soft cascade become Algorithm --- .../include/opencv2/objdetect/objdetect.hpp | 63 +++++++------ .../objdetect/perf/perf_cascadeclassifier.cpp | 17 ++-- modules/objdetect/src/objdetect_init.cpp | 23 ++++- modules/objdetect/src/softcascade.cpp | 32 +++---- modules/objdetect/test/test_softcascade.cpp | 94 ++++++++++--------- 5 files changed, 122 insertions(+), 107 deletions(-) diff --git a/modules/objdetect/include/opencv2/objdetect/objdetect.hpp b/modules/objdetect/include/opencv2/objdetect/objdetect.hpp index e0799f9b1..84f41e149 100644 --- a/modules/objdetect/include/opencv2/objdetect/objdetect.hpp +++ b/modules/objdetect/include/opencv2/objdetect/objdetect.hpp @@ -488,52 +488,52 @@ protected: Ptr maskGenerator; }; -/** - * \class SoftCascade - * \brief Implement soft (stageless) cascade. - */ -class CV_EXPORTS SoftCascade + +// Implementation of soft (stageless) cascaded detector. +class CV_EXPORTS SCascade : public Algorithm { public: - /** - * \class Detection - * \brief Soft cascade detector result represintation. - */ + // Representation of detectors result. struct CV_EXPORTS Detection { + // Default object type. enum {PEDESTRIAN = 1}; - //! Create detection from an object bounding rectangle and confidence. Only PEDESTRIAN type carrently supported. - //! Param r is a boundinf rectangle - //! param c is a confidence that object belongs to class k - //! Paral k is an object class + // Creates Detection from an object bounding box and confidence. + // Param b is a bounding box + // Param c is a confidence that object belongs to class k + // Paral k is an object class + Detection(const cv::Rect& b, const float c, int k = PEDESTRIAN) : bb(b), confidence(c), kind(k) {} - Detection(const cv::Rect& r, const float c, int k = PEDESTRIAN) : rect(r), confidence(c), kind(k) {} - cv::Rect rect; + cv::Rect bb; float confidence; int kind; }; - //! An empty cascade will be created. - //! Param minScale is a minimum scale relative to the original size of the image on which cascade will be applyed. - //! 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. - SoftCascade( const float minScale = 0.4f, const float maxScale = 5.f, const int scales = 55); + // An empty cascade will be created. + // Param minScale is a minimum scale relative to the original size of the image on which cascade will be applyed. + // 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 float minScale = 0.4f, const float maxScale = 5.f, const int scales = 55, const int rejfactor = 1); - //! Cascade will be created for scales from minScale to maxScale. - //! Param fs is a serialized sacsade. - SoftCascade( const cv::FileStorage& fs); + virtual ~SCascade(); - //! cascade will be loaded. The previous cascade will be destroyed. - //! Param fs is a serialized sacsade. - bool read( const cv::FileStorage& fs); + cv::AlgorithmInfo* info() const; - virtual ~SoftCascade(); + // Load cascade from FileNode. + // Param fn is a root node for cascade. Should be . + virtual bool load(const FileNode& fn); - //! return vector of bounding boxes. Each box contains one detected object - virtual void detectMultiScale(const Mat& image, const std::vector& rois, std::vector& objects, - int rejectfactor = 1) const; + // Load cascade config. + 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(const Mat& image, const std::vector& rois, std::vector& objects) const; private: struct Filds; @@ -542,8 +542,11 @@ private: float minScale; float maxScale; int scales; + int rejfactor; }; +CV_EXPORTS bool initModule_objdetect(void); + /** * \class IntegralChannels * \brief Create channel integrals for Soft Cascade detector. diff --git a/modules/objdetect/perf/perf_cascadeclassifier.cpp b/modules/objdetect/perf/perf_cascadeclassifier.cpp index f91f2f8ec..cc068e8ea 100644 --- a/modules/objdetect/perf/perf_cascadeclassifier.cpp +++ b/modules/objdetect/perf/perf_cascadeclassifier.cpp @@ -58,35 +58,36 @@ typedef perf::TestBaseWithParam detect; namespace { - typedef cv::SoftCascade::Detection detection_t; + typedef cv::SCascade::Detection detection_t; void extractRacts(std::vector objectBoxes, vector rects) { rects.clear(); for (int i = 0; i < (int)objectBoxes.size(); ++i) - rects.push_back(objectBoxes[i].rect); + rects.push_back(objectBoxes[i].bb); } } -PERF_TEST_P(detect, SoftCascade, +PERF_TEST_P(detect, SCascade, testing::Combine(testing::Values(std::string("cv/cascadeandhog/sc_cvpr_2012_to_opencv.xml")), testing::Values(std::string("cv/cascadeandhog/bahnhof/image_00000000_0.png")))) { - typedef cv::SoftCascade::Detection detection_t; + typedef cv::SCascade::Detection Detection; cv::Mat colored = imread(getDataPath(get<1>(GetParam()))); ASSERT_FALSE(colored.empty()); - cv::SoftCascade cascade; + cv::SCascade cascade; cv::FileStorage fs(getDataPath(get<0>(GetParam())), cv::FileStorage::READ); - ASSERT_TRUE(cascade.read(fs)); + ASSERT_TRUE(fs.isOpened()); + ASSERT_TRUE(cascade.load(fs.getFirstTopLevelNode())); std::vector rois; std::vector objectBoxes; - cascade.detectMultiScale(colored, rois, objectBoxes); + cascade.detect(colored, rois, objectBoxes); TEST_CYCLE() { - cascade.detectMultiScale(colored, rois, objectBoxes); + cascade.detect(colored, rois, objectBoxes); } vector rects; diff --git a/modules/objdetect/src/objdetect_init.cpp b/modules/objdetect/src/objdetect_init.cpp index 317867a59..a6ce81e80 100644 --- a/modules/objdetect/src/objdetect_init.cpp +++ b/modules/objdetect/src/objdetect_init.cpp @@ -7,11 +7,11 @@ // copy or use the software. // // -// License Agreement +// License Agreement // For Open Source Computer Vision Library // // Copyright (C) 2000-2008, Intel Corporation, all rights reserved. -// Copyright (C) 2009, Willow Garage Inc., all rights reserved. +// Copyright (C) 2008-2012, Willow Garage Inc., all rights reserved. // Third party copyrights are property of their respective owners. // // Redistribution and use in source and binary forms, with or without modification, @@ -40,4 +40,21 @@ // //M*/ -#include "precomp.hpp" +#include + +namespace cv +{ + +CV_INIT_ALGORITHM(SCascade, "CascadeDetector.SCascade", + obj.info()->addParam(obj, "minScale", obj.minScale)); + // obj.info()->addParam(obj, "maxScale", obj.maxScale); + // obj.info()->addParam(obj, "scales", obj.scales); + // obj.info()->addParam(obj, "rejfactor", obj.rejfactor)); + +bool initModule_objdetect(void) +{ + Ptr sc = createSCascade(); + return sc->info() != 0; +} + +} \ No newline at end of file diff --git a/modules/objdetect/src/softcascade.cpp b/modules/objdetect/src/softcascade.cpp index ec1899a4b..5b4b03169 100644 --- a/modules/objdetect/src/softcascade.cpp +++ b/modules/objdetect/src/softcascade.cpp @@ -175,7 +175,7 @@ struct Level enum { R_SHIFT = 1 << 15 }; float scaling[2]; - typedef cv::SoftCascade::Detection detection_t; + typedef cv::SCascade::Detection detection_t; Level(const Octave& oct, const float scale, const int shrinkage, const int w, const int h) : octave(&oct), origScale(scale), relScale(scale / oct.scale), @@ -252,7 +252,7 @@ struct ChannelStorage } -struct cv::SoftCascade::Filds +struct cv::SCascade::Filds { float minScale; float maxScale; @@ -491,33 +491,25 @@ struct cv::SoftCascade::Filds } }; -cv::SoftCascade::SoftCascade(const float mins, const float maxs, const int nsc) -: filds(0), minScale(mins), maxScale(maxs), scales(nsc) {} +cv::SCascade::SCascade(const float mins, const float maxs, const int nsc, const int rej) +: filds(0), minScale(mins), maxScale(maxs), scales(nsc), rejfactor(rej) {} -cv::SoftCascade::SoftCascade(const cv::FileStorage& fs) : filds(0) +cv::SCascade::~SCascade() { delete filds;} + +void cv::SCascade::read(const FileNode& fn) { - read(fs); -} -cv::SoftCascade::~SoftCascade() -{ - delete filds; + Algorithm::read(fn); } -bool cv::SoftCascade::read( const cv::FileStorage& fs) +bool cv::SCascade::load(const FileNode& fn) { - if (!fs.isOpened()) return false; - - if (filds) - delete filds; - filds = 0; + if (filds) delete filds; filds = new Filds; - Filds& flds = *filds; - return flds.fill(fs.getFirstTopLevelNode(), minScale, maxScale); + return filds->fill(fn, minScale, maxScale); } -void cv::SoftCascade::detectMultiScale(const Mat& image, const std::vector& /*rois*/, - std::vector& objects, const int /*rejectfactor*/) const +void cv::SCascade::detect(const Mat& image, const std::vector& /*rois*/, std::vector& objects) const { // only color images are supperted CV_Assert(image.type() == CV_8UC3); diff --git a/modules/objdetect/test/test_softcascade.cpp b/modules/objdetect/test/test_softcascade.cpp index 4711c3ca0..b1f8b2da4 100644 --- a/modules/objdetect/test/test_softcascade.cpp +++ b/modules/objdetect/test/test_softcascade.cpp @@ -1,31 +1,31 @@ /*M/////////////////////////////////////////////////////////////////////////////////////// // -// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. // -// By downloading, copying, installing or using the software you agree to this license. -// If you do not agree to this license, do not download, install, -// copy or use the software. +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. // // -// License Agreement -// For Open Source Computer Vision Library +// License Agreement +// For Open Source Computer Vision Library // // Copyright (C) 2000-2008, Intel Corporation, all rights reserved. -// Copyright (C) 2008-2011, Willow Garage Inc., all rights reserved. +// Copyright (C) 2008-2012, Willow Garage Inc., all rights reserved. // Third party copyrights are property of their respective owners. // // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: // -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. // -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. // -// * The name of the copyright holders may not be used to endorse or promote products -// derived from this software without specific prior written permission. +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. // // This software is provided by the copyright holders and contributors "as is" and // any express or implied warranties, including, but not limited to, the implied @@ -37,60 +37,62 @@ // and on any theory of liability, whether in contract, strict liability, // or tort (including negligence or otherwise) arising in any way out of // the use of this software, even if advised of the possibility of such damage. +// //M*/ #include "test_precomp.hpp" -TEST(SoftCascade, readCascade) +TEST(SCascade, readCascade) { std::string xml = cvtest::TS::ptr()->get_data_path() + "cascadeandhog/icf-template.xml"; - cv::SoftCascade cascade; + cv::SCascade cascade; cv::FileStorage fs(xml, cv::FileStorage::READ); - ASSERT_TRUE(cascade.read(fs)); + ASSERT_TRUE(fs.isOpened()); + ASSERT_TRUE(cascade.load(fs.getFirstTopLevelNode())); } -TEST(SoftCascade, detect) +TEST(SCascade, detect) { - typedef cv::SoftCascade::Detection detection_t; + typedef cv::SCascade::Detection Detection; std::string xml = cvtest::TS::ptr()->get_data_path() + "cascadeandhog/sc_cvpr_2012_to_opencv.xml"; - cv::SoftCascade cascade; + cv::SCascade cascade; cv::FileStorage fs(xml, cv::FileStorage::READ); - ASSERT_TRUE(cascade.read(fs)); + 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()); - std::vector objects; + std::vector objects; std::vector rois; rois.push_back(cv::Rect(0, 0, 640, 480)); - cascade.detectMultiScale(colored, rois, objects); + cascade.detect(colored, rois, objects); - // cv::Mat out = colored.clone(); - // int level = 0, total = 0; - // int levelWidth = objects[0].rect.width; + 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].rect.width != levelWidth) - // { - // std::cout << "Level: " << level << " total " << total << std::endl; - // cv::imshow("out", out); - // cv::waitKey(0); - // out = colored.clone(); - // levelWidth = objects[i].rect.width; - // total = 0; - // level++; - // } - // cv::rectangle(out, objects[i].rect, cv::Scalar(255, 0, 0, 255), 1); - // std::cout << "detection: " << objects[i].rect.x - // << " " << objects[i].rect.y - // << " " << objects[i].rect.width - // << " " << objects[i].rect.height << std::endl; - // total++; - // } - // std::cout << "detected: " << (int)objects.size() << std::endl; + 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(), 3668); } \ No newline at end of file From 65543c53f6b93ffaf681e364a4f4a3280f357367 Mon Sep 17 00:00:00 2001 From: "marina.kolpakova" Date: Mon, 5 Nov 2012 22:56:23 +0400 Subject: [PATCH 46/91] update test according to resize usage --- modules/objdetect/test/test_softcascade.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/objdetect/test/test_softcascade.cpp b/modules/objdetect/test/test_softcascade.cpp index b1f8b2da4..f8dec6b45 100644 --- a/modules/objdetect/test/test_softcascade.cpp +++ b/modules/objdetect/test/test_softcascade.cpp @@ -94,5 +94,5 @@ TEST(SCascade, detect) total++; } std::cout << "detected: " << (int)objects.size() << std::endl; - ASSERT_EQ((int)objects.size(), 3668); + ASSERT_EQ((int)objects.size(), 3498); } \ No newline at end of file From 6a3a72393867e8377523fd23ef8ae8c54ea8e626 Mon Sep 17 00:00:00 2001 From: "marina.kolpakova" Date: Mon, 5 Nov 2012 23:28:37 +0400 Subject: [PATCH 47/91] refactor integral channels --- .../include/opencv2/objdetect/objdetect.hpp | 49 +++++++++---------- modules/objdetect/src/{isf.cpp => icf.cpp} | 22 +++++---- modules/objdetect/src/softcascade.cpp | 7 +-- 3 files changed, 39 insertions(+), 39 deletions(-) rename modules/objdetect/src/{isf.cpp => icf.cpp} (86%) diff --git a/modules/objdetect/include/opencv2/objdetect/objdetect.hpp b/modules/objdetect/include/opencv2/objdetect/objdetect.hpp index 84f41e149..4d6db66f2 100644 --- a/modules/objdetect/include/opencv2/objdetect/objdetect.hpp +++ b/modules/objdetect/include/opencv2/objdetect/objdetect.hpp @@ -511,6 +511,29 @@ public: int kind; }; + // Create channel integrals for Soft Cascade detector. + class CV_EXPORTS Channels + { + public: + // constrictor form resizing factor. + // Param shr is a resizing factor. Resize is applied before the computing integral sum + Channels(const int shrinkage); + + // Appends specified number of HOG first-order features integrals into given vector. + // Param gray is an input 1-channel gray image. + // Param integrals is a vector of integrals. Hog-channels will be appended to it. + // Param bins is a number of hog-bins + void appendHogBins(const cv::Mat gray, std::vector& integrals, int bins) const; + + // Converts 3-channel BGR input frame in Luv and appends each channel to the integrals. + // Param frame is an input 3-channel BGR colored image. + // Param integrals is a vector of integrals. Computed from the frame luv-channels will be appended to it. + void appendLuvBins(const cv::Mat frame, std::vector& integrals) const; + + private: + int shrinkage; + }; + // An empty cascade will be created. // Param minScale is a minimum scale relative to the original size of the image on which cascade will be applyed. // Param minScale is a maximum scale relative to the original size of the image on which cascade will be applyed. @@ -547,32 +570,6 @@ private: CV_EXPORTS bool initModule_objdetect(void); -/** - * \class IntegralChannels - * \brief Create channel integrals for Soft Cascade detector. - */ -class CV_EXPORTS IntegralChannels -{ -public: - //! constrictor form resizing factor. - //! Param shr is a resizing factor. Resize is applied before integral sum computing - IntegralChannels(const int shr) : shrinkage(shr) {} - - //! Appends specified number of hog first order feature integrals into given vector. - //! Param gray is an input 1-chennel gray image. - //! Param integrals is a vector of integrals. Computed from frame frame hog-channels will be appended to it. - //! Param bins is a number of hog-bins - void createHogBins(const cv::Mat gray, std::vector& integrals, int bins) const; - - //! Converts 3-chennel BGR input frame to Luv and append each channel to the integrals. - //! Param frame is an input 3-chennel BGR colored image. - //! Param integrals is a vector of integrals. Computed from frame frame luv-channels will be appended to it. - void createLuvBins(const cv::Mat frame, std::vector& integrals) const; - -private: - int shrinkage; -}; - //////////////// HOG (Histogram-of-Oriented-Gradients) Descriptor and Object Detector ////////////// // struct for detection region of interest (ROI) diff --git a/modules/objdetect/src/isf.cpp b/modules/objdetect/src/icf.cpp similarity index 86% rename from modules/objdetect/src/isf.cpp rename to modules/objdetect/src/icf.cpp index bbf4f27c0..b6bd113d1 100644 --- a/modules/objdetect/src/isf.cpp +++ b/modules/objdetect/src/icf.cpp @@ -44,7 +44,9 @@ #include #include -void cv::IntegralChannels::createHogBins(const cv::Mat gray, std::vector& integrals, int bins) const +cv::SCascade::Channels::Channels(int shr) : shrinkage(shr) {} + +void cv::SCascade::Channels::appendHogBins(const cv::Mat gray, std::vector& integrals, int bins) const { CV_Assert(gray.type() == CV_8UC1); int h = gray.rows; @@ -52,11 +54,11 @@ void cv::IntegralChannels::createHogBins(const cv::Mat gray, std::vector& integrals) const +void cv::SCascade::Channels::appendLuvBins(const cv::Mat frame, std::vector& integrals) const { CV_Assert(frame.type() == CV_8UC3); CV_Assert(!(frame.cols % shrinkage) && !(frame.rows % shrinkage)); - cv::Mat luv; + cv::Mat luv, shrunk; cv::cvtColor(frame, luv, CV_BGR2Luv); + cv::resize(luv, shrunk, cv::Size(), 1.0 / shrinkage, 1.0 / shrinkage, CV_INTER_AREA); std::vector splited; - split(luv, splited); + split(shrunk, splited); for (size_t i = 0; i < splited.size(); ++i) { - cv::Mat shrunk, sum; - cv::resize(splited[i], shrunk, cv::Size(), 1.0 / shrinkage, 1.0 / shrinkage, CV_INTER_AREA); - cv::integral(shrunk, sum, cv::noArray(), CV_32S); + cv::Mat sum; + cv::integral(splited[i], sum, cv::noArray(), CV_32S); integrals.push_back(sum); } } \ No newline at end of file diff --git a/modules/objdetect/src/softcascade.cpp b/modules/objdetect/src/softcascade.cpp index 5b4b03169..37ab09166 100644 --- a/modules/objdetect/src/softcascade.cpp +++ b/modules/objdetect/src/softcascade.cpp @@ -223,14 +223,15 @@ struct ChannelStorage ChannelStorage(const cv::Mat& colored, int shr) : shrinkage(shr) { hog.clear(); - cv::IntegralChannels ints(shr); + hog.reserve(10); + cv::SCascade::Channels ints(shr); // convert to grey cv::Mat grey; cv::cvtColor(colored, grey, CV_BGR2GRAY); - ints.createHogBins(grey, hog, 6); - ints.createLuvBins(colored, hog); + ints.appendHogBins(grey, hog, 6); + ints.appendLuvBins(colored, hog); step = hog[0].cols; } From 157ab66ab908b44d9f72438a651461a796ce52ca Mon Sep 17 00:00:00 2001 From: "marina.kolpakova" Date: Tue, 6 Nov 2012 01:30:20 +0400 Subject: [PATCH 48/91] add ROI support --- .../include/opencv2/objdetect/objdetect.hpp | 4 +- .../objdetect/perf/perf_cascadeclassifier.cpp | 5 +- modules/objdetect/src/softcascade.cpp | 54 +++++++-- modules/objdetect/test/test_softcascade.cpp | 108 ++++++++++++++---- 4 files changed, 135 insertions(+), 36 deletions(-) diff --git a/modules/objdetect/include/opencv2/objdetect/objdetect.hpp b/modules/objdetect/include/opencv2/objdetect/objdetect.hpp index 4d6db66f2..8c1f29298 100644 --- a/modules/objdetect/include/opencv2/objdetect/objdetect.hpp +++ b/modules/objdetect/include/opencv2/objdetect/objdetect.hpp @@ -556,9 +556,11 @@ public: // 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(const Mat& image, const std::vector& rois, std::vector& objects) const; + virtual void detect(InputArray image, InputArray rois, std::vector& objects) const; private: + void detectNoRoi(const Mat& image, std::vector& objects) const; + struct Filds; Filds* filds; diff --git a/modules/objdetect/perf/perf_cascadeclassifier.cpp b/modules/objdetect/perf/perf_cascadeclassifier.cpp index cc068e8ea..f52bd59af 100644 --- a/modules/objdetect/perf/perf_cascadeclassifier.cpp +++ b/modules/objdetect/perf/perf_cascadeclassifier.cpp @@ -81,13 +81,12 @@ PERF_TEST_P(detect, SCascade, ASSERT_TRUE(fs.isOpened()); ASSERT_TRUE(cascade.load(fs.getFirstTopLevelNode())); - std::vector rois; std::vector objectBoxes; - cascade.detect(colored, rois, objectBoxes); + cascade.detect(colored, cv::noArray(), objectBoxes); TEST_CYCLE() { - cascade.detect(colored, rois, objectBoxes); + cascade.detect(colored, cv::noArray(), objectBoxes); } vector rects; diff --git a/modules/objdetect/src/softcascade.cpp b/modules/objdetect/src/softcascade.cpp index 37ab09166..2f7e69713 100644 --- a/modules/objdetect/src/softcascade.cpp +++ b/modules/objdetect/src/softcascade.cpp @@ -510,16 +510,9 @@ bool cv::SCascade::load(const FileNode& fn) return filds->fill(fn, minScale, maxScale); } -void cv::SCascade::detect(const Mat& image, const std::vector& /*rois*/, std::vector& objects) const +void cv::SCascade::detectNoRoi(const cv::Mat& image, std::vector& objects) const { - // only color images are supperted - CV_Assert(image.type() == CV_8UC3); - Filds& fld = *filds; - fld.calcLevels(image.size(), scales); - - objects.clear(); - // create integrals ChannelStorage storage(image, fld.shrinkage); @@ -537,4 +530,49 @@ void cv::SCascade::detect(const Mat& image, const std::vector& /*rois* } } } +} + +void cv::SCascade::detect(cv::InputArray _image, cv::InputArray _rois, std::vector& objects) const +{ + // only color images are supperted + cv::Mat image = _image.getMat(); + CV_Assert(image.type() == CV_8UC3); + + Filds& fld = *filds; + fld.calcLevels(image.size(), scales); + + objects.clear(); + + if (_rois.kind() == cv::_InputArray::NONE) + return detectNoRoi(image, objects); + + cv::Mat roi = _rois.getMat(); + cv::Mat mask(image.rows / fld.shrinkage, image.cols / fld.shrinkage, CV_8UC1); + + mask.setTo(cv::Scalar::all(0)); + cv::Rect* r = roi.ptr(0); + for (int i = 0; i < (int)roi.cols; ++i) + cv::Mat(mask, cv::Rect(r[i].x / fld.shrinkage, r[i].y / fld.shrinkage, r[i].width / fld.shrinkage , r[i].height / fld.shrinkage)).setTo(cv::Scalar::all(1)); + + // create integrals + ChannelStorage storage(image, fld.shrinkage); + + typedef std::vector::const_iterator lIt; + for (lIt it = fld.levels.begin(); it != fld.levels.end(); ++it) + { + const Level& level = *it; + + for (int dy = 0; dy < level.workRect.height; ++dy) + { + uchar* m = mask.ptr(dy); + for (int dx = 0; dx < level.workRect.width; ++dx) + { + if (m[dx]) + { + storage.offset = dy * storage.step + dx; + fld.detectAt(dx, dy, level, storage, objects); + } + } + } + } } \ No newline at end of file diff --git a/modules/objdetect/test/test_softcascade.cpp b/modules/objdetect/test/test_softcascade.cpp index f8dec6b45..d33d5892b 100644 --- a/modules/objdetect/test/test_softcascade.cpp +++ b/modules/objdetect/test/test_softcascade.cpp @@ -63,36 +63,96 @@ TEST(SCascade, detect) cv::Mat colored = cv::imread(cvtest::TS::ptr()->get_data_path() + "cascadeandhog/bahnhof/image_00000000_0.png"); ASSERT_FALSE(colored.empty()); + 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, detectRoi) +{ + 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()); + std::vector objects; std::vector rois; 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; - 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; + // 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, detectNoRoi) +{ + 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()); + + std::vector objects; + std::vector rois; + + cascade.detect(colored, rois, objects); + + ASSERT_EQ((int)objects.size(), 0); } \ No newline at end of file From 4207552e19e7758e5bda06e10b3d66293a2d6e11 Mon Sep 17 00:00:00 2001 From: "marina.kolpakova" Date: Tue, 6 Nov 2012 02:41:26 +0400 Subject: [PATCH 49/91] add object init --- modules/objdetect/src/objdetect_init.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/objdetect/src/objdetect_init.cpp b/modules/objdetect/src/objdetect_init.cpp index a6ce81e80..d53c9480d 100644 --- a/modules/objdetect/src/objdetect_init.cpp +++ b/modules/objdetect/src/objdetect_init.cpp @@ -46,10 +46,10 @@ namespace cv { CV_INIT_ALGORITHM(SCascade, "CascadeDetector.SCascade", - obj.info()->addParam(obj, "minScale", obj.minScale)); - // obj.info()->addParam(obj, "maxScale", obj.maxScale); - // obj.info()->addParam(obj, "scales", obj.scales); - // obj.info()->addParam(obj, "rejfactor", obj.rejfactor)); + obj.info()->addParam(obj, "minScale", obj.minScale); + obj.info()->addParam(obj, "maxScale", obj.maxScale); + obj.info()->addParam(obj, "scales", obj.scales); + obj.info()->addParam(obj, "rejfactor", obj.rejfactor)); bool initModule_objdetect(void) { From 31a073ca668eb4332e5c15ab04952d62345aa3ab Mon Sep 17 00:00:00 2001 From: "marina.kolpakova" Date: Wed, 7 Nov 2012 01:50:33 +0400 Subject: [PATCH 50/91] documentation --- modules/objdetect/doc/objdetect.rst | 1 + modules/objdetect/doc/soft_cascade.rst | 89 ++++++++++++++++++++++++++ 2 files changed, 90 insertions(+) create mode 100644 modules/objdetect/doc/soft_cascade.rst diff --git a/modules/objdetect/doc/objdetect.rst b/modules/objdetect/doc/objdetect.rst index 4bab781b8..381742e50 100644 --- a/modules/objdetect/doc/objdetect.rst +++ b/modules/objdetect/doc/objdetect.rst @@ -8,4 +8,5 @@ objdetect. Object Detection :maxdepth: 2 cascade_classification + soft_cascade latent_svm diff --git a/modules/objdetect/doc/soft_cascade.rst b/modules/objdetect/doc/soft_cascade.rst new file mode 100644 index 000000000..0ba756601 --- /dev/null +++ b/modules/objdetect/doc/soft_cascade.rst @@ -0,0 +1,89 @@ +Soft Cascade Classifier +====================== + +.. highlight:: cpp + +Soft Cascade Classifier for Object Detection +---------------------------------------------------------- + +Cascade detectors have been shown to operate extremely rapidly, with high accuracy, and have important applications in different spheres. The initial goal for this cascade implementation was the fast and accurate pedestrian detector but it also useful in general. Soft cascade is trained with AdaBoost. But instead of training sequence of stages, the soft cascade is trained as a one long stage of T weak classifiers. Soft cascade is formulated as follows: + +.. math:: + \texttt{H}(x) = \sum _{\texttt{t}=1..\texttt{T}} {\texttt{s}_t(x)} + +where :math:`\texttt{s}_t(x) = \alpha_t\texttt{h}_t(x)` are the set of thresholded weak classifiers selected during AdaBoost training scaled by the associated weights. Let + +.. math:: + \texttt{H}_t(x) = \sum _{\texttt{i}=1..\texttt{t}} {\texttt{s}_i(x)} + +be the partial sum of sample responses before :math:`t`-the weak classifier will be applied. The funtcion :math:`\texttt{H}_t(x)` of :math:`t` for sample :math:`x` named *sample trace*. +After each weak classifier evaluation, the sample trace at the point :math:`t` is compared with the rejection threshold :math:`r_t`. The sequence of :math:`r_t` named *rejection trace*. + +The sample has been rejected if it fall rejection threshold. So stageless cascade allows to reject not-object sample as soon as possible. Another meaning of the sample trace is a confidence with that sample recognized as desired object. At each :math:`t` that confidence depend on all previous weak classifier. This feature of soft cascade is resulted in more accurate detection. The original formulation of soft cascade can be found in [BJ05]_. + +.. [BJ05] Lubomir Bourdev and Jonathan Brandt. tRobust Object Detection Via Soft Cascade. IEEE CVPR, 2005. +.. [BMTG12] Rodrigo Benenson, Markus Mathias, Radu Timofte and Luc Van Gool. Pedestrian detection at 100 frames per second. IEEE CVPR, 2012. + + +SCascade +---------------- +.. ocv:class:: SCascade + +Implementation of soft (stageless) cascaded detector. :: + + class CV_EXPORTS SCascade : public Algorithm + { + public: + SCascade(const float minScale = 0.4f, const float maxScale = 5.f, const int scales = 55, const int rejfactor = 1); + virtual ~SCascade(); + cv::AlgorithmInfo* info() const; + virtual bool load(const FileNode& fn); + virtual void detect(InputArray image, InputArray rois, std::vector& objects) const; + }; + + +SCascade::SCascade +-------------------------- +An empty cascade will be created. + +.. ocv:function:: bool SCascade::SCascade(const float minScale = 0.4f, const float maxScale = 5.f, const int scales = 55, const int rejfactor = 1) + + :param minScale: a minimum scale relative to the original size of the image on which cascade will be applyed. + + :param maxScale: a maximum scale relative to the original size of the image on which cascade will be applyed. + + :param scales: a number of scales from minScale to maxScale. + + :param rejfactor: used for non maximum suppression. + + + +SCascade::~SCascade +--------------------------- +Destructor for SCascade. + +.. ocv:function:: SCascade::~SCascade() + + + +SCascade::load +-------------------------- +Load cascade from FileNode. + +.. ocv:function:: bool SCascade::load(const FileNode& fn) + + :param fn: File node from which the soft cascade are read. + + + +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 + + :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 From 5fb9f48360e4630233b8a8f57aa496702582ef96 Mon Sep 17 00:00:00 2001 From: "marina.kolpakova" Date: Wed, 7 Nov 2012 02:21:48 +0400 Subject: [PATCH 51/91] fix angle scaling --- modules/objdetect/src/icf.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/objdetect/src/icf.cpp b/modules/objdetect/src/icf.cpp index b6bd113d1..885cebdd7 100644 --- a/modules/objdetect/src/icf.cpp +++ b/modules/objdetect/src/icf.cpp @@ -63,7 +63,7 @@ void cv::SCascade::Channels::appendHogBins(const cv::Mat gray, std::vector hist; for (int bin = 0; bin < bins; ++bin) From 465687216108ae2b4a2f94a250e83bf131ca4502 Mon Sep 17 00:00:00 2001 From: "marina.kolpakova" Date: Wed, 7 Nov 2012 02:27:07 +0400 Subject: [PATCH 52/91] fixed typo --- .../include/opencv2/objdetect/objdetect.hpp | 4 ++-- modules/objdetect/src/softcascade.cpp | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/modules/objdetect/include/opencv2/objdetect/objdetect.hpp b/modules/objdetect/include/opencv2/objdetect/objdetect.hpp index 8c1f29298..e3307c995 100644 --- a/modules/objdetect/include/opencv2/objdetect/objdetect.hpp +++ b/modules/objdetect/include/opencv2/objdetect/objdetect.hpp @@ -561,8 +561,8 @@ public: private: void detectNoRoi(const Mat& image, std::vector& objects) const; - struct Filds; - Filds* filds; + struct Fields; + Fields* fields; float minScale; float maxScale; diff --git a/modules/objdetect/src/softcascade.cpp b/modules/objdetect/src/softcascade.cpp index 2f7e69713..afe1304ed 100644 --- a/modules/objdetect/src/softcascade.cpp +++ b/modules/objdetect/src/softcascade.cpp @@ -253,7 +253,7 @@ struct ChannelStorage } -struct cv::SCascade::Filds +struct cv::SCascade::Fields { float minScale; float maxScale; @@ -493,9 +493,9 @@ struct cv::SCascade::Filds }; cv::SCascade::SCascade(const float mins, const float maxs, const int nsc, const int rej) -: filds(0), minScale(mins), maxScale(maxs), scales(nsc), rejfactor(rej) {} +: fields(0), minScale(mins), maxScale(maxs), scales(nsc), rejfactor(rej) {} -cv::SCascade::~SCascade() { delete filds;} +cv::SCascade::~SCascade() { delete fields;} void cv::SCascade::read(const FileNode& fn) { @@ -504,15 +504,15 @@ void cv::SCascade::read(const FileNode& fn) bool cv::SCascade::load(const FileNode& fn) { - if (filds) delete filds; + if (fields) delete fields; - filds = new Filds; - return filds->fill(fn, minScale, maxScale); + fields = new Fields; + return fields->fill(fn, minScale, maxScale); } void cv::SCascade::detectNoRoi(const cv::Mat& image, std::vector& objects) const { - Filds& fld = *filds; + Fields& fld = *fields; // create integrals ChannelStorage storage(image, fld.shrinkage); @@ -538,7 +538,7 @@ void cv::SCascade::detect(cv::InputArray _image, cv::InputArray _rois, std::vect cv::Mat image = _image.getMat(); CV_Assert(image.type() == CV_8UC3); - Filds& fld = *filds; + Fields& fld = *fields; fld.calcLevels(image.size(), scales); objects.clear(); From f1e36043e66930178c7eecb7ce3fcd34f07945ea Mon Sep 17 00:00:00 2001 From: "marina.kolpakova" Date: Wed, 7 Nov 2012 03:14:15 +0400 Subject: [PATCH 53/91] clean code --- modules/objdetect/src/icf.cpp | 2 - modules/objdetect/src/softcascade.cpp | 161 +++++++------------------- 2 files changed, 43 insertions(+), 120 deletions(-) diff --git a/modules/objdetect/src/icf.cpp b/modules/objdetect/src/icf.cpp index 885cebdd7..a41ae7a32 100644 --- a/modules/objdetect/src/icf.cpp +++ b/modules/objdetect/src/icf.cpp @@ -41,8 +41,6 @@ //M*/ #include -#include -#include cv::SCascade::Channels::Channels(int shr) : shrinkage(shr) {} diff --git a/modules/objdetect/src/softcascade.cpp b/modules/objdetect/src/softcascade.cpp index afe1304ed..c00e4e6ef 100644 --- a/modules/objdetect/src/softcascade.cpp +++ b/modules/objdetect/src/softcascade.cpp @@ -41,29 +41,16 @@ //M*/ #include -#include -#include - -#include -#include -#include -#include -#include - -// used for noisy printfs -// #define WITH_DEBUG_OUT - -#if defined WITH_DEBUG_OUT -# define dprintf(format, ...) \ - do { printf(format, ##__VA_ARGS__); } while (0) -#else -# define dprintf(format, ...) -#endif namespace { struct Octave { + Octave(const int i, cv::Size origObjSize, const cv::FileNode& fn) + : index(i), scale((float)fn[SC_OCT_SCALE]), stages((int)fn[SC_OCT_STAGES]), + size(cvRound(origObjSize.width * scale), cvRound(origObjSize.height * scale)), + shrinkage((int)fn[SC_OCT_SHRINKAGE]) {} + int index; float scale; int stages; @@ -73,49 +60,32 @@ struct Octave static const char *const SC_OCT_SCALE; static const char *const SC_OCT_STAGES; static const char *const SC_OCT_SHRINKAGE; - - Octave(const int i, cv::Size origObjSize, const cv::FileNode& fn) - : index(i), scale((float)fn[SC_OCT_SCALE]), stages((int)fn[SC_OCT_STAGES]), - size(cvRound(origObjSize.width * scale), cvRound(origObjSize.height * scale)), - shrinkage((int)fn[SC_OCT_SHRINKAGE]) - {} }; -const char *const Octave::SC_OCT_SCALE = "scale"; -const char *const Octave::SC_OCT_STAGES = "stageNum"; -const char *const Octave::SC_OCT_SHRINKAGE = "shrinkingFactor"; struct Weak { + Weak(){} + Weak(const cv::FileNode& fn) : threshold((float)fn[SC_STAGE_THRESHOLD]){} + float threshold; static const char *const SC_STAGE_THRESHOLD; - - Weak(){} - Weak(const cv::FileNode& fn) : threshold((float)fn[SC_STAGE_THRESHOLD]){} }; -const char *const Weak::SC_STAGE_THRESHOLD = "stageThreshold"; struct Node { - int feature; - float threshold; - Node(){} Node(const int offset, cv::FileNodeIterator& fIt) : feature((int)(*(fIt +=2)++) + offset), threshold((float)(*(fIt++))){} + + int feature; + float threshold; }; struct Feature { - int channel; - cv::Rect rect; - float rarea; - - static const char * const SC_F_CHANNEL; - static const char * const SC_F_RECT; - Feature() {} Feature(const cv::FileNode& fn) : channel((int)fn[SC_F_CHANNEL]) { @@ -126,40 +96,22 @@ struct Feature // 1 / area rarea = 1.f / ((rect.width - rect.x) * (rect.height - rect.y)); } + + int channel; + cv::Rect rect; + float rarea; + + static const char *const SC_F_CHANNEL; + static const char *const SC_F_RECT; + }; -const char * const Feature::SC_F_CHANNEL = "channel"; -const char * const Feature::SC_F_RECT = "rect"; - -struct CascadeIntrinsics -{ - static const float lambda = 1.099f, a = 0.89f; - - static float getFor(bool isUp, float scaling) - { - if (fabs(scaling - 1.f) < FLT_EPSILON) - return 1.f; - - // according to R. Benenson, M. Mathias, R. Timofte and L. Van Gool's and Dallal's papers - static const float A[2][2] = - { //channel <= 6, otherwise - { 0.89f, 1.f}, // down - { 1.00f, 1.f} // up - }; - - static const float B[2][2] = - { //channel <= 6, otherwise - { 1.099f / log(2), 2.f}, // down - { 0.f, 2.f} // up - }; - - float a = A[(int)(scaling >= 1)][(int)(isUp)]; - float b = B[(int)(scaling >= 1)][(int)(isUp)]; - - dprintf("scaling: %f %f %f %f\n", scaling, a, b, a * pow(scaling, b)); - return a * pow(scaling, b); - } -}; +const char *const Octave::SC_OCT_SCALE = "scale"; +const char *const Octave::SC_OCT_STAGES = "stageNum"; +const char *const Octave::SC_OCT_SHRINKAGE = "shrinkingFactor"; +const char *const Weak::SC_STAGE_THRESHOLD = "stageThreshold"; +const char *const Feature::SC_F_CHANNEL = "channel"; +const char *const Feature::SC_F_RECT = "rect"; struct Level { @@ -172,37 +124,36 @@ struct Level cv::Size workRect; cv::Size objSize; - enum { R_SHIFT = 1 << 15 }; - - float scaling[2]; - typedef cv::SCascade::Detection detection_t; + float scaling[2]; // 0-th for channels <= 6, 1-st otherwise + typedef cv::SCascade::Detection Detection; Level(const Octave& oct, const float scale, const int shrinkage, const int w, const int h) : octave(&oct), origScale(scale), relScale(scale / oct.scale), workRect(cv::Size(cvRound(w / (float)shrinkage),cvRound(h / (float)shrinkage))), objSize(cv::Size(cvRound(oct.size.width * relScale), cvRound(oct.size.height * relScale))) { - scaling[0] = CascadeIntrinsics::getFor(false, relScale) / (relScale * relScale); - scaling[1] = CascadeIntrinsics::getFor(true, relScale) / (relScale * relScale); + scaling[0] = ((relScale >= 1.f)? 1.f : (0.89f * pow(relScale, 1.099f / log(2)))) / (relScale * relScale); + scaling[1] = 1.f; scaleshift = relScale * (1 << 16); } - void addDetection(const int x, const int y, float confidence, std::vector& detections) const + void addDetection(const int x, const int y, float confidence, std::vector& detections) const { int shrinkage = (*octave).shrinkage; cv::Rect rect(cvRound(x * shrinkage), cvRound(y * shrinkage), objSize.width, objSize.height); - detections.push_back(detection_t(rect, confidence)); + detections.push_back(Detection(rect, confidence)); } float rescale(cv::Rect& scaledRect, const float threshold, int idx) const { +#define SSHIFT(a) ((a) + (1 << 15)) >> 16 // rescale - scaledRect.x = (scaleshift * scaledRect.x + R_SHIFT) >> 16; - scaledRect.y = (scaleshift * scaledRect.y + R_SHIFT) >> 16; - scaledRect.width = (scaleshift * scaledRect.width + R_SHIFT) >> 16; - scaledRect.height = (scaleshift * scaledRect.height + R_SHIFT) >> 16; - + scaledRect.x = SSHIFT(scaleshift * scaledRect.x); + scaledRect.y = SSHIFT(scaleshift * scaledRect.y); + scaledRect.width = SSHIFT(scaleshift * scaledRect.width); + scaledRect.height = SSHIFT(scaleshift * scaledRect.height); +#undef SSHIFT float sarea = (scaledRect.width - scaledRect.x) * (scaledRect.height - scaledRect.y); // compensation areas rounding @@ -219,7 +170,6 @@ struct ChannelStorage enum {HOG_BINS = 6, HOG_LUV_BINS = 10}; - ChannelStorage() {} ChannelStorage(const cv::Mat& colored, int shr) : shrinkage(shr) { hog.clear(); @@ -264,7 +214,7 @@ struct cv::SCascade::Fields int shrinkage; std::vector octaves; - std::vector stages; + std::vector stages; std::vector nodes; std::vector leaves; std::vector features; @@ -273,29 +223,19 @@ struct cv::SCascade::Fields cv::Size frameSize; - enum { BOOST = 0 }; - typedef std::vector::iterator octIt_t; void detectAt(const int dx, const int dy, const Level& level, const ChannelStorage& storage, std::vector& detections) const { - dprintf("detect at: %d %d\n", dx, dy); - float detectionScore = 0.f; const Octave& octave = *(level.octave); int stBegin = octave.index * octave.stages, stEnd = stBegin + 1024;//octave.stages; - dprintf(" octave stages: %d to %d index %d %f level %f\n", - stBegin, stEnd, octave.index, octave.scale, level.origScale); - int st = stBegin; for(; st < stEnd; ++st) { - - dprintf("index: %d\n", st); - const Weak& stage = stages[st]; { int nId = st * 3; @@ -309,12 +249,8 @@ struct cv::SCascade::Fields float sum = storage.get(feature.channel, scaledRect); - dprintf("root feature %d %f\n",feature.channel, sum); - int next = (sum >= threshold)? 2 : 1; - dprintf("go: %d (%f >= %f)\n\n" ,next, sum, threshold); - // leaves const Node& leaf = nodes[nId + next]; const Feature& fLeaf = features[leaf.feature]; @@ -327,25 +263,12 @@ struct cv::SCascade::Fields int lShift = (next - 1) * 2 + ((sum >= threshold) ? 1 : 0); float impact = leaves[(st * 4) + lShift]; - dprintf("decided: %d (%f >= %f) %d %f\n\n" ,next, sum, threshold, lShift, impact); - detectionScore += impact; } - dprintf("extracted stage:\n"); - dprintf("ct %f\n", stage.threshold); - dprintf("computed score %f\n\n", detectionScore); - -#if defined WITH_DEBUG_OUT - if (st - stBegin > 50 ) break; -#endif - if (detectionScore <= stage.threshold) return; } - dprintf("x %d y %d: %d\n", dx, dy, st - stBegin); - dprintf(" got %d\n", st); - level.addDetection(dx, dy, detectionScore, detections); } @@ -546,16 +469,18 @@ void cv::SCascade::detect(cv::InputArray _image, cv::InputArray _rois, std::vect if (_rois.kind() == cv::_InputArray::NONE) return detectNoRoi(image, objects); + int shr = fld.shrinkage; + cv::Mat roi = _rois.getMat(); - cv::Mat mask(image.rows / fld.shrinkage, image.cols / fld.shrinkage, CV_8UC1); + cv::Mat mask(image.rows / shr, image.cols / shr, CV_8UC1); mask.setTo(cv::Scalar::all(0)); cv::Rect* r = roi.ptr(0); for (int i = 0; i < (int)roi.cols; ++i) - cv::Mat(mask, cv::Rect(r[i].x / fld.shrinkage, r[i].y / fld.shrinkage, r[i].width / fld.shrinkage , r[i].height / fld.shrinkage)).setTo(cv::Scalar::all(1)); + cv::Mat(mask, cv::Rect(r[i].x / shr, r[i].y / shr, r[i].width / shr , r[i].height / shr)).setTo(cv::Scalar::all(1)); // create integrals - ChannelStorage storage(image, fld.shrinkage); + ChannelStorage storage(image, shr); typedef std::vector::const_iterator lIt; for (lIt it = fld.levels.begin(); it != fld.levels.end(); ++it) From 1022094dc09895c2e6039e95754cc42e22c29f38 Mon Sep 17 00:00:00 2001 From: "marina.kolpakova" Date: Wed, 7 Nov 2012 04:20:35 +0400 Subject: [PATCH 54/91] fix levels computing --- modules/objdetect/src/softcascade.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/modules/objdetect/src/softcascade.cpp b/modules/objdetect/src/softcascade.cpp index c00e4e6ef..6c03ae1be 100644 --- a/modules/objdetect/src/softcascade.cpp +++ b/modules/objdetect/src/softcascade.cpp @@ -46,7 +46,7 @@ namespace { struct Octave { - Octave(const int i, cv::Size origObjSize, const cv::FileNode& fn) + Octave(const int i, const cv::Size& origObjSize, const cv::FileNode& fn) : index(i), scale((float)fn[SC_OCT_SCALE]), stages((int)fn[SC_OCT_STAGES]), size(cvRound(origObjSize.width * scale), cvRound(origObjSize.height * scale)), shrinkage((int)fn[SC_OCT_SHRINKAGE]) {} @@ -207,6 +207,7 @@ struct cv::SCascade::Fields { float minScale; float maxScale; + int scales; int origObjWidth; int origObjHeight; @@ -292,12 +293,14 @@ struct cv::SCascade::Fields } // compute levels of full pyramid - void calcLevels(const cv::Size& curr, int scales) + void calcLevels(const cv::Size& curr, float mins, float maxs, int total) { - if (frameSize == curr) return; - frameSize = curr; - + if (frameSize == curr && maxs == maxScale && mins == minScale && total == scales) return; CV_Assert(scales > 1); + + frameSize = curr; + maxScale = maxs; minScale = mins; scales = total; + levels.clear(); float logFactor = (log(maxScale) - log(minScale)) / (scales -1); @@ -323,11 +326,8 @@ struct cv::SCascade::Fields } } - bool fill(const FileNode &root, const float mins, const float maxs) + bool fill(const FileNode &root) { - minScale = mins; - maxScale = maxs; - // cascade properties static const char *const SC_STAGE_TYPE = "stageType"; static const char *const SC_BOOST = "BOOST"; @@ -430,7 +430,7 @@ bool cv::SCascade::load(const FileNode& fn) if (fields) delete fields; fields = new Fields; - return fields->fill(fn, minScale, maxScale); + return fields->fill(fn); } void cv::SCascade::detectNoRoi(const cv::Mat& image, std::vector& objects) const @@ -462,7 +462,7 @@ void cv::SCascade::detect(cv::InputArray _image, cv::InputArray _rois, std::vect CV_Assert(image.type() == CV_8UC3); Fields& fld = *fields; - fld.calcLevels(image.size(), scales); + fld.calcLevels(image.size(),minScale, maxScale, scales); objects.clear(); From f93cffaa0dd3263137ba3ff0d0fc52dd02422faa Mon Sep 17 00:00:00 2001 From: "marina.kolpakova" Date: Thu, 8 Nov 2012 00:08:43 +0400 Subject: [PATCH 55/91] fix compilation under win --- modules/objdetect/src/icf.cpp | 2 +- modules/objdetect/src/softcascade.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/objdetect/src/icf.cpp b/modules/objdetect/src/icf.cpp index a41ae7a32..0401a0623 100644 --- a/modules/objdetect/src/icf.cpp +++ b/modules/objdetect/src/icf.cpp @@ -56,7 +56,7 @@ void cv::SCascade::Channels::appendHogBins(const cv::Mat gray, std::vector= 1.f)? 1.f : (0.89f * pow(relScale, 1.099f / log(2)))) / (relScale * relScale); + scaling[0] = ((relScale >= 1.f)? 1.f : (0.89f * pow(relScale, 1.099f / log(2.f)))) / (relScale * relScale); scaling[1] = 1.f; scaleshift = relScale * (1 << 16); } From e379771c039592e4ef879118b9bd194452162d08 Mon Sep 17 00:00:00 2001 From: "marina.kolpakova" Date: Thu, 8 Nov 2012 02:16:04 +0400 Subject: [PATCH 56/91] git warning --- modules/objdetect/include/opencv2/objdetect/objdetect.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/objdetect/include/opencv2/objdetect/objdetect.hpp b/modules/objdetect/include/opencv2/objdetect/objdetect.hpp index e3307c995..0a07e32f3 100644 --- a/modules/objdetect/include/opencv2/objdetect/objdetect.hpp +++ b/modules/objdetect/include/opencv2/objdetect/objdetect.hpp @@ -411,7 +411,7 @@ protected: enum { DO_CANNY_PRUNING = 1, SCALE_IMAGE = 2, FIND_BIGGEST_OBJECT = 4, DO_ROUGH_SEARCH = 8 }; - friend struct CascadeClassifierInvoker; + friend class CascadeClassifierInvoker; template friend int predictOrdered( CascadeClassifier& cascade, Ptr &featureEvaluator, double& weight); From 8a3e89799964caa01e958e852f04a7e9a675f627 Mon Sep 17 00:00:00 2001 From: "marina.kolpakova" Date: Thu, 8 Nov 2012 02:33:19 +0400 Subject: [PATCH 57/91] min and max params become double --- .../objdetect/include/opencv2/objdetect/objdetect.hpp | 11 ++++++----- modules/objdetect/src/icf.cpp | 4 ++-- modules/objdetect/src/softcascade.cpp | 6 +++--- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/modules/objdetect/include/opencv2/objdetect/objdetect.hpp b/modules/objdetect/include/opencv2/objdetect/objdetect.hpp index 0a07e32f3..98c4f0a79 100644 --- a/modules/objdetect/include/opencv2/objdetect/objdetect.hpp +++ b/modules/objdetect/include/opencv2/objdetect/objdetect.hpp @@ -523,12 +523,12 @@ public: // Param gray is an input 1-channel gray image. // Param integrals is a vector of integrals. Hog-channels will be appended to it. // Param bins is a number of hog-bins - void appendHogBins(const cv::Mat gray, std::vector& integrals, int bins) const; + void appendHogBins(const cv::Mat& gray, std::vector& integrals, int bins) const; // Converts 3-channel BGR input frame in Luv and appends each channel to the integrals. // Param frame is an input 3-channel BGR colored image. // Param integrals is a vector of integrals. Computed from the frame luv-channels will be appended to it. - void appendLuvBins(const cv::Mat frame, std::vector& integrals) const; + void appendLuvBins(const cv::Mat& frame, std::vector& integrals) const; private: int shrinkage; @@ -539,7 +539,7 @@ 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 float minScale = 0.4f, const float maxScale = 5.f, const int scales = 55, const int rejfactor = 1); + SCascade(const double minScale = 0.4, const double maxScale = 5., const int scales = 55, const int rejfactor = 1); virtual ~SCascade(); @@ -564,8 +564,9 @@ private: struct Fields; Fields* fields; - float minScale; - float maxScale; + double minScale; + double maxScale; + int scales; int rejfactor; }; diff --git a/modules/objdetect/src/icf.cpp b/modules/objdetect/src/icf.cpp index 0401a0623..416e5ffff 100644 --- a/modules/objdetect/src/icf.cpp +++ b/modules/objdetect/src/icf.cpp @@ -44,7 +44,7 @@ cv::SCascade::Channels::Channels(int shr) : shrinkage(shr) {} -void cv::SCascade::Channels::appendHogBins(const cv::Mat gray, std::vector& integrals, int bins) const +void cv::SCascade::Channels::appendHogBins(const cv::Mat& gray, std::vector& integrals, int bins) const { CV_Assert(gray.type() == CV_8UC1); int h = gray.rows; @@ -92,7 +92,7 @@ void cv::SCascade::Channels::appendHogBins(const cv::Mat gray, std::vector& integrals) const +void cv::SCascade::Channels::appendLuvBins(const cv::Mat& frame, std::vector& integrals) const { CV_Assert(frame.type() == CV_8UC3); CV_Assert(!(frame.cols % shrinkage) && !(frame.rows % shrinkage)); diff --git a/modules/objdetect/src/softcascade.cpp b/modules/objdetect/src/softcascade.cpp index 985655a36..134fa9b2c 100644 --- a/modules/objdetect/src/softcascade.cpp +++ b/modules/objdetect/src/softcascade.cpp @@ -296,10 +296,10 @@ struct cv::SCascade::Fields void calcLevels(const cv::Size& curr, float mins, float maxs, int total) { if (frameSize == curr && maxs == maxScale && mins == minScale && total == scales) return; - CV_Assert(scales > 1); frameSize = curr; maxScale = maxs; minScale = mins; scales = total; + CV_Assert(scales > 1); levels.clear(); float logFactor = (log(maxScale) - log(minScale)) / (scales -1); @@ -415,7 +415,7 @@ struct cv::SCascade::Fields } }; -cv::SCascade::SCascade(const float mins, const float maxs, const int nsc, const int rej) +cv::SCascade::SCascade(const double mins, const double maxs, const int nsc, const int rej) : fields(0), minScale(mins), maxScale(maxs), scales(nsc), rejfactor(rej) {} cv::SCascade::~SCascade() { delete fields;} @@ -462,7 +462,7 @@ void cv::SCascade::detect(cv::InputArray _image, cv::InputArray _rois, std::vect CV_Assert(image.type() == CV_8UC3); Fields& fld = *fields; - fld.calcLevels(image.size(),minScale, maxScale, scales); + fld.calcLevels(image.size(),(float) minScale, (float)maxScale, (float)scales); objects.clear(); From 91634719877a6c33b40253e30e8e572c63fa0487 Mon Sep 17 00:00:00 2001 From: Vadim Pisarevsky Date: Thu, 8 Nov 2012 14:09:43 +0400 Subject: [PATCH 58/91] improved accuracy of 3x3 invert on poorly-conditioned matrices (bug #2525) --- modules/core/src/lapack.cpp | 67 +++++++-------------------------- modules/core/test/test_math.cpp | 15 ++++++++ 2 files changed, 28 insertions(+), 54 deletions(-) diff --git a/modules/core/src/lapack.cpp b/modules/core/src/lapack.cpp index 4d179022e..1abffa8b3 100644 --- a/modules/core/src/lapack.cpp +++ b/modules/core/src/lapack.cpp @@ -954,7 +954,7 @@ double cv::invert( InputArray _src, OutputArray _dst, int method ) size_t esz = CV_ELEM_SIZE(type); int m = src.rows, n = src.cols; - if( method == DECOMP_SVD ) + if( method == DECOMP_SVD ) { int nm = std::min(m, n); @@ -1101,62 +1101,21 @@ double cv::invert( InputArray _src, OutputArray _dst, int method ) result = true; d = 1./d; - #if CV_SSE2 - if(USE_SSE2) - { - __m128 det =_mm_set1_ps((float)d); - __m128 s0 = _mm_loadu_ps((const float*)srcdata);//s0 = Sf(0,0) Sf(0,1) Sf(0,2) *** - __m128 s1 = _mm_loadu_ps((const float*)(srcdata+srcstep));//s1 = Sf(1,0) Sf(1,1) Sf(1,2) *** - __m128 s2 = _mm_set_ps(0.f, Sf(2,2), Sf(2,1), Sf(2,0)); //s2 = Sf(2,0) Sf(2,1) Sf(2,2) *** + t[0] = (float)(((double)Sf(1,1) * Sf(2,2) - (double)Sf(1,2) * Sf(2,1)) * d); + t[1] = (float)(((double)Sf(0,2) * Sf(2,1) - (double)Sf(0,1) * Sf(2,2)) * d); + t[2] = (float)(((double)Sf(0,1) * Sf(1,2) - (double)Sf(0,2) * Sf(1,1)) * d); - __m128 r0 = _mm_shuffle_ps(s1,s1,_MM_SHUFFLE(3,0,2,1)); //r0 = Sf(1,1) Sf(1,2) Sf(1,0) *** - __m128 r1 = _mm_shuffle_ps(s2,s2,_MM_SHUFFLE(3,1,0,2)); //r1 = Sf(2,2) Sf(2,0) Sf(2,1) *** - __m128 r2 = _mm_shuffle_ps(s2,s2,_MM_SHUFFLE(3,0,2,1)); //r2 = Sf(2,1) Sf(2,2) Sf(2,0) *** + t[3] = (float)(((double)Sf(1,2) * Sf(2,0) - (double)Sf(1,0) * Sf(2,2)) * d); + t[4] = (float)(((double)Sf(0,0) * Sf(2,2) - (double)Sf(0,2) * Sf(2,0)) * d); + t[5] = (float)(((double)Sf(0,2) * Sf(1,0) - (double)Sf(0,0) * Sf(1,2)) * d); - __m128 t0 = _mm_mul_ps(s0, r0);//t0 = Sf(0,0)*Sf(1,1) Sf(0,1)*Sf(1,2) Sf(0,2)*Sf(1,0) *** - __m128 t1 = _mm_mul_ps(s0, r1);//t1 = Sf(0,0)*Sf(2,2) Sf(0,1)*Sf(2,0) Sf(0,2)*Sf(2,1) *** - __m128 t2 = _mm_mul_ps(s1, r2);//t2 = Sf(1,0)*Sf(2,1) Sf(1,1)*Sf(2,2) Sf(1,2)*Sf(2,0) *** + t[6] = (float)(((double)Sf(1,0) * Sf(2,1) - (double)Sf(1,1) * Sf(2,0)) * d); + t[7] = (float)(((double)Sf(0,1) * Sf(2,0) - (double)Sf(0,0) * Sf(2,1)) * d); + t[8] = (float)(((double)Sf(0,0) * Sf(1,1) - (double)Sf(0,1) * Sf(1,0)) * d); - __m128 r3 = _mm_shuffle_ps(s0,s0,_MM_SHUFFLE(3,0,2,1));//r3 = Sf(0,1) Sf(0,2) Sf(0,0) *** - __m128 r4 = _mm_shuffle_ps(s0,s0,_MM_SHUFFLE(3,1,0,2));//r4 = Sf(0,2) Sf(0,0) Sf(0,1) *** - - __m128 t00 = _mm_mul_ps(s1, r3);//t00 = Sf(1,0)*Sf(0,1) Sf(1,1)*Sf(0,2) Sf(1,2)*Sf(0,0) *** - __m128 t11 = _mm_mul_ps(s2, r4);//t11 = Sf(2,0)*Sf(0,2) Sf(2,1)*Sf(0,0) Sf(2,2)*Sf(0,1) *** - __m128 t22 = _mm_mul_ps(s2, r0);//t22 = Sf(2,0)*Sf(1,1) Sf(2,1)*Sf(1,2) Sf(2,2)*Sf(1,0) *** - - t0 = _mm_mul_ps(_mm_sub_ps(t0,t00), det);//Sf(0,0)*Sf(1,1) Sf(0,1)*Sf(1,2) Sf(0,2)*Sf(1,0) *** - //-Sf(1,0)*Sf(0,1) -Sf(1,1)*Sf(0,2) -Sf(1,2)*Sf(0,0) - t1 = _mm_mul_ps(_mm_sub_ps(t1,t11), det);//Sf(0,0)*Sf(2,2) Sf(0,1)*Sf(2,0) Sf(0,2)*Sf(2,1) *** - //-Sf(2,0)*Sf(0,2) -Sf(2,1)*Sf(0,0) -Sf(2,2)*Sf(0,1) - t2 = _mm_mul_ps(_mm_sub_ps(t2,t22), det);//Sf(1,0)*Sf(2,1) Sf(1,1)*Sf(2,2) Sf(1,2)*Sf(2,0) *** - //-Sf(2,0)*Sf(1,1) -Sf(2,1)*Sf(1,2) -Sf(2,2)*Sf(1,0) - _mm_store_ps(t, t0); - _mm_store_ps(t+4, t1); - _mm_store_ps(t+8, t2); - - Df(0,0) = t[9]; Df(0,1) = t[6]; Df(0,2) = t[1]; - Df(1,0) = t[10]; Df(1,1) = t[4]; Df(1,2) = t[2]; - Df(2,0) = t[8]; Df(2,1) = t[5]; Df(2,2) = t[0]; - } - else - #endif - { - t[0] = (float)(((double)Sf(1,1) * Sf(2,2) - (double)Sf(1,2) * Sf(2,1)) * d); - t[1] = (float)(((double)Sf(0,2) * Sf(2,1) - (double)Sf(0,1) * Sf(2,2)) * d); - t[2] = (float)(((double)Sf(0,1) * Sf(1,2) - (double)Sf(0,2) * Sf(1,1)) * d); - - t[3] = (float)(((double)Sf(1,2) * Sf(2,0) - (double)Sf(1,0) * Sf(2,2)) * d); - t[4] = (float)(((double)Sf(0,0) * Sf(2,2) - (double)Sf(0,2) * Sf(2,0)) * d); - t[5] = (float)(((double)Sf(0,2) * Sf(1,0) - (double)Sf(0,0) * Sf(1,2)) * d); - - t[6] = (float)(((double)Sf(1,0) * Sf(2,1) - (double)Sf(1,1) * Sf(2,0)) * d); - t[7] = (float)(((double)Sf(0,1) * Sf(2,0) - (double)Sf(0,0) * Sf(2,1)) * d); - t[8] = (float)(((double)Sf(0,0) * Sf(1,1) - (double)Sf(0,1) * Sf(1,0)) * d); - - Df(0,0) = t[0]; Df(0,1) = t[1]; Df(0,2) = t[2]; - Df(1,0) = t[3]; Df(1,1) = t[4]; Df(1,2) = t[5]; - Df(2,0) = t[6]; Df(2,1) = t[7]; Df(2,2) = t[8]; - } + Df(0,0) = t[0]; Df(0,1) = t[1]; Df(0,2) = t[2]; + Df(1,0) = t[3]; Df(1,1) = t[4]; Df(1,2) = t[5]; + Df(2,0) = t[6]; Df(2,1) = t[7]; Df(2,2) = t[8]; } } else diff --git a/modules/core/test/test_math.cpp b/modules/core/test/test_math.cpp index dfc58b72f..120396131 100644 --- a/modules/core/test/test_math.cpp +++ b/modules/core/test/test_math.cpp @@ -2453,6 +2453,21 @@ REGISTER_TYPED_TEST_CASE_P(Core_CheckRange, Negative, Positive, Bounds, Zero); typedef ::testing::Types mat_data_types; INSTANTIATE_TYPED_TEST_CASE_P(Negative_Test, Core_CheckRange, mat_data_types); +TEST(Core_Invert, small) +{ + cv::Mat a = (cv::Mat_(3,3) << 2.42104644730331, 1.81444796521479, -3.98072565304758, 0, 7.08389214348967e-3, 5.55326770986007e-3, 0,0, 7.44556154284261e-3); + //cv::randu(a, -1, 1); + + cv::Mat b = a.t()*a; + cv::Mat c, i = Mat_::eye(3, 3); + cv::invert(b, c, cv::DECOMP_LU); //std::cout << b*c << std::endl; + ASSERT_LT( cv::norm(b*c, i, CV_C), 0.1 ); + cv::invert(b, c, cv::DECOMP_SVD); //std::cout << b*c << std::endl; + ASSERT_LT( cv::norm(b*c, i, CV_C), 0.1 ); + cv::invert(b, c, cv::DECOMP_CHOLESKY); //std::cout << b*c << std::endl; + ASSERT_LT( cv::norm(b*c, i, CV_C), 0.1 ); +} + ///////////////////////////////////////////////////////////////////////////////////////////////////// TEST(Core_CovarMatrix, accuracy) { Core_CovarMatrixTest test; test.safe_run(); } From 7ef378b230eaa3363b1af94b42cbe8be7065370c Mon Sep 17 00:00:00 2001 From: mikle Date: Fri, 2 Nov 2012 18:27:26 +0600 Subject: [PATCH 59/91] Android tutorial updated. HelloWorld sample ported on new framework. --- .../dev_with_OCV_on_Android.rst | 257 +++++------------- 1 file changed, 75 insertions(+), 182 deletions(-) diff --git a/doc/tutorials/introduction/android_binary_package/dev_with_OCV_on_Android.rst b/doc/tutorials/introduction/android_binary_package/dev_with_OCV_on_Android.rst index f7f0c4718..52f739361 100644 --- a/doc/tutorials/introduction/android_binary_package/dev_with_OCV_on_Android.rst +++ b/doc/tutorials/introduction/android_binary_package/dev_with_OCV_on_Android.rst @@ -270,105 +270,6 @@ It will be capable of accessing camera output, processing it and displaying the #. Set name, target, package and minSDKVersion accordingly. -#. Create a new class (*File -> New -> Class*). Name it for example: *HelloOpenCVView*. - - .. image:: images/dev_OCV_new_class.png - :alt: Add a new class. - :align: center - - * It should extend *SurfaceView* class. - * It also should implement *SurfaceHolder.Callback*, *Runnable*. - -#. Edit *HelloOpenCVView* class. - - * Add an *import* line for *android.content.context*. - - * Modify autogenerated stubs: *HelloOpenCVView*, *surfaceCreated*, *surfaceDestroyed* and *surfaceChanged*. - - .. code-block:: java - :linenos: - - package com.hello.opencv.test; - - import android.content.Context; - - public class HelloOpenCVView extends SurfaceView implements Callback, Runnable { - - public HelloOpenCVView(Context context) { - super(context); - getHolder().addCallback(this); - } - - public void surfaceCreated(SurfaceHolder holder) { - (new Thread(this)).start(); - } - - public void surfaceDestroyed(SurfaceHolder holder) { - cameraRelease(); - } - - public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { - cameraSetup(width, height); - } - - //... - - * Add *cameraOpen*, *cameraRelease* and *cameraSetup* voids as shown below. - - * Also, don't forget to add the public void *run()* as follows: - - .. code-block:: java - :linenos: - - public void run() { - // TODO: loop { getFrame(), processFrame(), drawFrame() } - } - - public boolean cameraOpen() { - return false; //TODO: open camera - } - - private void cameraRelease() { - // TODO release camera - } - - private void cameraSetup(int width, int height) { - // TODO setup camera - } - -#. Create a new *Activity* (*New -> Other -> Android -> Android Activity*) and name it, for example: *HelloOpenCVActivity*. For this activity define *onCreate*, *onResume* and *onPause* voids. - - .. code-block:: java - :linenos: - - public void onCreate (Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - mView = new HelloOpenCVView(this); - setContentView (mView); - } - - protected void onPause() { - super.onPause(); - mView.cameraRelease(); - } - - protected void onResume() { - super.onResume(); - if( !mView.cameraOpen() ) { - // MessageBox and exit app - AlertDialog ad = new AlertDialog.Builder(this).create(); - ad.setCancelable(false); // This blocks the "BACK" button - ad.setMessage("Fatal error: can't open camera!"); - ad.setButton("OK", new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - dialog.dismiss(); - finish(); - } - }); - ad.show(); - } - } - #. Add the following permissions to the AndroidManifest.xml file: .. code-block:: xml @@ -386,98 +287,90 @@ It will be capable of accessing camera output, processing it and displaying the :alt: Reference OpenCV library. :align: center -#. We now need some code to handle the camera. Update the *HelloOpenCVView* class as follows: +#. Create new view layout for your application, lets name it hello_opencv.xml, and add the following to it: + + .. code-block:: xml + :linenos: + + + + + + + +#. Remove default auto generated layout, if exists. + +#. Create a new *Activity* (*New -> Other -> Android -> Android Activity*) and name it, for example: *HelloOpenCVActivity*. Add *CvCameraViewListener* interface to *implementes* section of *HelloOpenCVActivity* class. Add the following code to activity implementation: .. code-block:: java :linenos: - private VideoCapture mCamera; + public class Sample1Java extends Activity implements CvCameraViewListener { + + private CameraBridgeViewBase mOpenCvCameraView; - public boolean cameraOpen() { - synchronized (this) { - cameraRelease(); - mCamera = new VideoCapture(Highgui.CV_CAP_ANDROID); - if (!mCamera.isOpened()) { - mCamera.release(); - mCamera = null; - Log.e("HelloOpenCVView", "Failed to open native camera"); - return false; - } - } - return true; - } + private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) { + @Override + public void onManagerConnected(int status) { + switch (status) { + case LoaderCallbackInterface.SUCCESS: { + Log.i(TAG, "OpenCV loaded successfully"); + mOpenCvCameraView.enableView(); + } break; + default: + super.onManagerConnected(status); + } + } + }; - public void cameraRelease() { - synchronized(this) { - if (mCamera != null) { - mCamera.release(); - mCamera = null; - } - } - } + /** Called when the activity is first created. */ + @Override + public void onCreate(Bundle savedInstanceState) { + Log.i(TAG, "called onCreate"); + super.onCreate(savedInstanceState); + requestWindowFeature(Window.FEATURE_NO_TITLE); + getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + setContentView(R.layout.hello_opencv); + mOpenCvCameraView = (CameraBridgeViewBase) findViewById(R.id.java_surface_view); + mOpenCvCameraView.setVisibility(SurfaceView.VISIBLE); + mOpenCvCameraView.setCvCameraViewListener(this); + } - private void cameraSetup(int width, int height) { - synchronized (this) { - if (mCamera != null && mCamera.isOpened()) { - List sizes = mCamera.getSupportedPreviewSizes(); - int mFrameWidth = width; - int mFrameHeight = height; - { // selecting optimal camera preview size - double minDiff = Double.MAX_VALUE; - for (Size size : sizes) { - if (Math.abs(size.height - height) < minDiff) { - mFrameWidth = (int) size.width; - mFrameHeight = (int) size.height; - minDiff = Math.abs(size.height - height); - } - } - } - mCamera.set(Highgui.CV_CAP_PROP_FRAME_WIDTH, mFrameWidth); - mCamera.set(Highgui.CV_CAP_PROP_FRAME_HEIGHT, mFrameHeight); - } - } - } + @Override + public void onPause() + { + if (mOpenCvCameraView != null) + mOpenCvCameraView.disableView(); + super.onPause(); + } -#. The last step would be to update the *run()* void in *HelloOpenCVView* class as follows: + @Override + public void onResume() + { + super.onResume(); + OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_3, this, mLoaderCallback); + } - .. code-block:: java - :linenos: + public void onDestroy() { + super.onDestroy(); + if (mOpenCvCameraView != null) + mOpenCvCameraView.disableView(); + } - public void run() { - while (true) { - Bitmap bmp = null; - synchronized (this) { - if (mCamera == null) - break; - if (!mCamera.grab()) - break; + public void onCameraViewStarted(int width, int height) { + } - bmp = processFrame(mCamera); - } - if (bmp != null) { - Canvas canvas = getHolder().lockCanvas(); - if (canvas != null) { - canvas.drawBitmap(bmp, (canvas.getWidth() - bmp.getWidth()) / 2, - (canvas.getHeight() - bmp.getHeight()) / 2, null); - getHolder().unlockCanvasAndPost(canvas); + public void onCameraViewStopped() { + } - } - bmp.recycle(); - } - } - } - - protected Bitmap processFrame(VideoCapture capture) { - Mat mRgba = new Mat(); - capture.retrieve(mRgba, Highgui.CV_CAP_ANDROID_COLOR_FRAME_RGBA); - //process mRgba - Bitmap bmp = Bitmap.createBitmap(mRgba.cols(), mRgba.rows(), Bitmap.Config.ARGB_8888); - try { - Utils.matToBitmap(mRgba, bmp); - } catch(Exception e) { - Log.e("processFrame", "Utils.matToBitmap() throws an exception: " + e.getMessage()); - bmp.recycle(); - bmp = null; - } - return bmp; - } + public Mat onCameraFrame(Mat inputFrame) { + return inputFrame; + } + } From 2e54e2a5863eb38bedd2bcaf1dbb455655096932 Mon Sep 17 00:00:00 2001 From: Vadim Pisarevsky Date: Thu, 8 Nov 2012 16:15:04 +0400 Subject: [PATCH 60/91] fixed problem with LBPHFaceRecognizer::update() without breaking binary compatibility. --- modules/contrib/src/facerec.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/modules/contrib/src/facerec.cpp b/modules/contrib/src/facerec.cpp index 7a8ab7420..fbf124a48 100644 --- a/modules/contrib/src/facerec.cpp +++ b/modules/contrib/src/facerec.cpp @@ -300,7 +300,13 @@ public: //------------------------------------------------------------------------------ // FaceRecognizer //------------------------------------------------------------------------------ -void FaceRecognizer::update(InputArrayOfArrays, InputArray) { +void FaceRecognizer::update(InputArrayOfArrays src, InputArray labels ) { + if( dynamic_cast(this) != 0 ) + { + dynamic_cast(this)->update( src, labels ); + return; + } + string error_msg = format("This FaceRecognizer (%s) does not support updating, you have to use FaceRecognizer::train to update it.", this->name().c_str()); CV_Error(CV_StsNotImplemented, error_msg); } From 665bf430d5ea585fbf6b18e7fc2b02ea2ed2f2da Mon Sep 17 00:00:00 2001 From: "marina.kolpakova" Date: Fri, 9 Nov 2012 00:07:32 +0400 Subject: [PATCH 61/91] fix warnings under win --- modules/objdetect/src/softcascade.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/modules/objdetect/src/softcascade.cpp b/modules/objdetect/src/softcascade.cpp index 134fa9b2c..bfda83426 100644 --- a/modules/objdetect/src/softcascade.cpp +++ b/modules/objdetect/src/softcascade.cpp @@ -134,7 +134,7 @@ struct Level { scaling[0] = ((relScale >= 1.f)? 1.f : (0.89f * pow(relScale, 1.099f / log(2.f)))) / (relScale * relScale); scaling[1] = 1.f; - scaleshift = relScale * (1 << 16); + scaleshift = static_cast(relScale * (1 << 16)); } void addDetection(const int x, const int y, float confidence, std::vector& detections) const @@ -154,7 +154,7 @@ struct Level scaledRect.width = SSHIFT(scaleshift * scaledRect.width); scaledRect.height = SSHIFT(scaleshift * scaledRect.height); #undef SSHIFT - float sarea = (scaledRect.width - scaledRect.x) * (scaledRect.height - scaledRect.y); + float sarea = static_cast((scaledRect.width - scaledRect.x) * (scaledRect.height - scaledRect.y)); // compensation areas rounding return (sarea == 0.0f)? threshold : (threshold * scaling[idx] * sarea); @@ -197,7 +197,7 @@ struct ChannelStorage int c = ptr[area.height * step + area.width]; int d = ptr[area.height * step + area.x]; - return (a - b + c - d); + return static_cast(a - b + c - d); } }; @@ -307,8 +307,8 @@ struct cv::SCascade::Fields float scale = minScale; for (int sc = 0; sc < scales; ++sc) { - int width = std::max(0.0f, frameSize.width - (origObjWidth * scale)); - int height = std::max(0.0f, frameSize.height - (origObjHeight * scale)); + int width = static_cast(std::max(0.0f, frameSize.width - (origObjWidth * scale))); + int height = static_cast(std::max(0.0f, frameSize.height - (origObjHeight * scale))); float logScale = log(scale); octIt_t fit = fitOctave(logScale); @@ -462,7 +462,7 @@ void cv::SCascade::detect(cv::InputArray _image, cv::InputArray _rois, std::vect CV_Assert(image.type() == CV_8UC3); Fields& fld = *fields; - fld.calcLevels(image.size(),(float) minScale, (float)maxScale, (float)scales); + fld.calcLevels(image.size(),(float) minScale, (float)maxScale, scales); objects.clear(); From 91a9923dcf89af8492d116fb12ab5aeaf1b679f7 Mon Sep 17 00:00:00 2001 From: Alexander Smorkalov Date: Fri, 9 Nov 2012 09:40:19 +0400 Subject: [PATCH 62/91] Face detection package name replaced on org.opencv.facedetect for consistency with Google Play package. --- .../face-detection/AndroidManifest.xml | 2 +- .../jni/DetectionBasedTracker_jni.cpp | 36 +++++++++---------- .../jni/DetectionBasedTracker_jni.h | 12 +++---- .../DetectionBasedTracker.java | 2 +- .../{fd => facedetect}/FdActivity.java | 2 +- .../samples/{fd => facedetect}/FpsMeter.java | 2 +- 6 files changed, 28 insertions(+), 28 deletions(-) rename samples/android/face-detection/src/org/opencv/samples/{fd => facedetect}/DetectionBasedTracker.java (96%) rename samples/android/face-detection/src/org/opencv/samples/{fd => facedetect}/FdActivity.java (99%) rename samples/android/face-detection/src/org/opencv/samples/{fd => facedetect}/FpsMeter.java (97%) diff --git a/samples/android/face-detection/AndroidManifest.xml b/samples/android/face-detection/AndroidManifest.xml index eaa90dfd0..a52dc660e 100644 --- a/samples/android/face-detection/AndroidManifest.xml +++ b/samples/android/face-detection/AndroidManifest.xml @@ -1,6 +1,6 @@ diff --git a/samples/android/face-detection/jni/DetectionBasedTracker_jni.cpp b/samples/android/face-detection/jni/DetectionBasedTracker_jni.cpp index 976f1683c..2ade0ca98 100644 --- a/samples/android/face-detection/jni/DetectionBasedTracker_jni.cpp +++ b/samples/android/face-detection/jni/DetectionBasedTracker_jni.cpp @@ -18,10 +18,10 @@ inline void vector_Rect_to_Mat(vector& v_rect, Mat& mat) mat = Mat(v_rect, true); } -JNIEXPORT jlong JNICALL Java_org_opencv_samples_fd_DetectionBasedTracker_nativeCreateObject +JNIEXPORT jlong JNICALL Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeCreateObject (JNIEnv * jenv, jclass, jstring jFileName, jint faceSize) { - LOGD("Java_org_opencv_samples_fd_DetectionBasedTracker_nativeCreateObject enter"); + LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeCreateObject enter"); const char* jnamestr = jenv->GetStringUTFChars(jFileName, NULL); string stdFileName(jnamestr); jlong result = 0; @@ -49,14 +49,14 @@ JNIEXPORT jlong JNICALL Java_org_opencv_samples_fd_DetectionBasedTracker_nativeC return 0; } - LOGD("Java_org_opencv_samples_fd_DetectionBasedTracker_nativeCreateObject exit"); + LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeCreateObject exit"); return result; } -JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBasedTracker_nativeDestroyObject +JNIEXPORT void JNICALL Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeDestroyObject (JNIEnv * jenv, jclass, jlong thiz) { - LOGD("Java_org_opencv_samples_fd_DetectionBasedTracker_nativeDestroyObject enter"); + LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeDestroyObject enter"); try { if(thiz != 0) @@ -79,13 +79,13 @@ JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBasedTracker_nativeDe jclass je = jenv->FindClass("java/lang/Exception"); jenv->ThrowNew(je, "Unknown exception in JNI code {highgui::VideoCapture_n_1VideoCapture__()}"); } - LOGD("Java_org_opencv_samples_fd_DetectionBasedTracker_nativeDestroyObject exit"); + LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeDestroyObject exit"); } -JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBasedTracker_nativeStart +JNIEXPORT void JNICALL Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeStart (JNIEnv * jenv, jclass, jlong thiz) { - LOGD("Java_org_opencv_samples_fd_DetectionBasedTracker_nativeStart enter"); + LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeStart enter"); try { ((DetectionBasedTracker*)thiz)->run(); @@ -104,13 +104,13 @@ JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBasedTracker_nativeSt jclass je = jenv->FindClass("java/lang/Exception"); jenv->ThrowNew(je, "Unknown exception in JNI code {highgui::VideoCapture_n_1VideoCapture__()}"); } - LOGD("Java_org_opencv_samples_fd_DetectionBasedTracker_nativeStart exit"); + LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeStart exit"); } -JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBasedTracker_nativeStop +JNIEXPORT void JNICALL Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeStop (JNIEnv * jenv, jclass, jlong thiz) { - LOGD("Java_org_opencv_samples_fd_DetectionBasedTracker_nativeStop enter"); + LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeStop enter"); try { ((DetectionBasedTracker*)thiz)->stop(); @@ -129,13 +129,13 @@ JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBasedTracker_nativeSt jclass je = jenv->FindClass("java/lang/Exception"); jenv->ThrowNew(je, "Unknown exception in JNI code {highgui::VideoCapture_n_1VideoCapture__()}"); } - LOGD("Java_org_opencv_samples_fd_DetectionBasedTracker_nativeStop exit"); + LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeStop exit"); } -JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBasedTracker_nativeSetFaceSize +JNIEXPORT void JNICALL Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeSetFaceSize (JNIEnv * jenv, jclass, jlong thiz, jint faceSize) { - LOGD("Java_org_opencv_samples_fd_DetectionBasedTracker_nativeSetFaceSize enter"); + LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeSetFaceSize enter"); try { if (faceSize > 0) @@ -160,14 +160,14 @@ JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBasedTracker_nativeSe jclass je = jenv->FindClass("java/lang/Exception"); jenv->ThrowNew(je, "Unknown exception in JNI code {highgui::VideoCapture_n_1VideoCapture__()}"); } - LOGD("Java_org_opencv_samples_fd_DetectionBasedTracker_nativeSetFaceSize exit"); + LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeSetFaceSize exit"); } -JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBasedTracker_nativeDetect +JNIEXPORT void JNICALL Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeDetect (JNIEnv * jenv, jclass, jlong thiz, jlong imageGray, jlong faces) { - LOGD("Java_org_opencv_samples_fd_DetectionBasedTracker_nativeDetect enter"); + LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeDetect enter"); try { vector RectFaces; @@ -189,5 +189,5 @@ JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBasedTracker_nativeDe jclass je = jenv->FindClass("java/lang/Exception"); jenv->ThrowNew(je, "Unknown exception in JNI code {highgui::VideoCapture_n_1VideoCapture__()}"); } - LOGD("Java_org_opencv_samples_fd_DetectionBasedTracker_nativeDetect exit"); + LOGD("Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeDetect exit"); } \ No newline at end of file diff --git a/samples/android/face-detection/jni/DetectionBasedTracker_jni.h b/samples/android/face-detection/jni/DetectionBasedTracker_jni.h index 7ae94c3dd..7e0541d81 100644 --- a/samples/android/face-detection/jni/DetectionBasedTracker_jni.h +++ b/samples/android/face-detection/jni/DetectionBasedTracker_jni.h @@ -12,7 +12,7 @@ extern "C" { * Method: nativeCreateObject * Signature: (Ljava/lang/String;F)J */ -JNIEXPORT jlong JNICALL Java_org_opencv_samples_fd_DetectionBasedTracker_nativeCreateObject +JNIEXPORT jlong JNICALL Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeCreateObject (JNIEnv *, jclass, jstring, jint); /* @@ -20,7 +20,7 @@ JNIEXPORT jlong JNICALL Java_org_opencv_samples_fd_DetectionBasedTracker_nativeC * Method: nativeDestroyObject * Signature: (J)V */ -JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBasedTracker_nativeDestroyObject +JNIEXPORT void JNICALL Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeDestroyObject (JNIEnv *, jclass, jlong); /* @@ -28,7 +28,7 @@ JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBasedTracker_nativeDe * Method: nativeStart * Signature: (J)V */ -JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBasedTracker_nativeStart +JNIEXPORT void JNICALL Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeStart (JNIEnv *, jclass, jlong); /* @@ -36,7 +36,7 @@ JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBasedTracker_nativeSt * Method: nativeStop * Signature: (J)V */ -JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBasedTracker_nativeStop +JNIEXPORT void JNICALL Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeStop (JNIEnv *, jclass, jlong); /* @@ -44,7 +44,7 @@ JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBasedTracker_nativeSt * Method: nativeSetFaceSize * Signature: (JI)V */ - JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBasedTracker_nativeSetFaceSize + JNIEXPORT void JNICALL Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeSetFaceSize (JNIEnv *, jclass, jlong, jint); /* @@ -52,7 +52,7 @@ JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBasedTracker_nativeSt * Method: nativeDetect * Signature: (JJJ)V */ -JNIEXPORT void JNICALL Java_org_opencv_samples_fd_DetectionBasedTracker_nativeDetect +JNIEXPORT void JNICALL Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeDetect (JNIEnv *, jclass, jlong, jlong, jlong); #ifdef __cplusplus diff --git a/samples/android/face-detection/src/org/opencv/samples/fd/DetectionBasedTracker.java b/samples/android/face-detection/src/org/opencv/samples/facedetect/DetectionBasedTracker.java similarity index 96% rename from samples/android/face-detection/src/org/opencv/samples/fd/DetectionBasedTracker.java rename to samples/android/face-detection/src/org/opencv/samples/facedetect/DetectionBasedTracker.java index 9e4600543..6179f1bdc 100644 --- a/samples/android/face-detection/src/org/opencv/samples/fd/DetectionBasedTracker.java +++ b/samples/android/face-detection/src/org/opencv/samples/facedetect/DetectionBasedTracker.java @@ -1,4 +1,4 @@ -package org.opencv.samples.fd; +package org.opencv.samples.facedetect; import org.opencv.core.Mat; import org.opencv.core.MatOfRect; diff --git a/samples/android/face-detection/src/org/opencv/samples/fd/FdActivity.java b/samples/android/face-detection/src/org/opencv/samples/facedetect/FdActivity.java similarity index 99% rename from samples/android/face-detection/src/org/opencv/samples/fd/FdActivity.java rename to samples/android/face-detection/src/org/opencv/samples/facedetect/FdActivity.java index 9470a8fd1..2b949629c 100644 --- a/samples/android/face-detection/src/org/opencv/samples/fd/FdActivity.java +++ b/samples/android/face-detection/src/org/opencv/samples/facedetect/FdActivity.java @@ -1,4 +1,4 @@ -package org.opencv.samples.fd; +package org.opencv.samples.facedetect; import java.io.File; import java.io.FileOutputStream; diff --git a/samples/android/face-detection/src/org/opencv/samples/fd/FpsMeter.java b/samples/android/face-detection/src/org/opencv/samples/facedetect/FpsMeter.java similarity index 97% rename from samples/android/face-detection/src/org/opencv/samples/fd/FpsMeter.java rename to samples/android/face-detection/src/org/opencv/samples/facedetect/FpsMeter.java index 2c8f3bc7b..2438bf89a 100644 --- a/samples/android/face-detection/src/org/opencv/samples/fd/FpsMeter.java +++ b/samples/android/face-detection/src/org/opencv/samples/facedetect/FpsMeter.java @@ -1,4 +1,4 @@ -package org.opencv.samples.fd; +package org.opencv.samples.facedetect; import java.text.DecimalFormat; From e5ffbf949814ef1810367878d6d3b367be5fe701 Mon Sep 17 00:00:00 2001 From: Andrey Kamaev Date: Fri, 9 Nov 2012 07:53:31 +0400 Subject: [PATCH 63/91] Fix stream output operator for Vec This fixes output for 8U and 8S vector depths. They were mistakenly printed as characters instead of numbers. --- .../core/include/opencv2/core/operations.hpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/modules/core/include/opencv2/core/operations.hpp b/modules/core/include/opencv2/core/operations.hpp index 4b6e60616..847daf8c2 100644 --- a/modules/core/include/opencv2/core/operations.hpp +++ b/modules/core/include/opencv2/core/operations.hpp @@ -3873,10 +3873,21 @@ template inline std::ostream& operator<<(std::ostream& out, const template inline std::ostream& operator<<(std::ostream& out, const Vec<_Tp, n>& vec) { out << "["; - for (int i = 0; i < n - 1; ++i) { - out << vec[i] << ", "; + + if(Vec<_Tp, n>::depth < CV_32F) + { + for (int i = 0; i < n - 1; ++i) { + out << (int)vec[i] << ", "; + } + out << (int)vec[n-1] << "]"; + } + else + { + for (int i = 0; i < n - 1; ++i) { + out << vec[i] << ", "; + } + out << vec[n-1] << "]"; } - out << vec[n-1] << "]"; return out; } From 8c9c2b3a032b6e50f9f0513c7d745d2f0d6cf4b3 Mon Sep 17 00:00:00 2001 From: Andrey Kamaev Date: Thu, 8 Nov 2012 02:11:27 +0400 Subject: [PATCH 64/91] Fix build on Windows with OpenGl enabled There was missing windows.h include in OpenGL interop code. --- modules/core/src/opengl_interop.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/modules/core/src/opengl_interop.cpp b/modules/core/src/opengl_interop.cpp index bf767148c..3cbec2c01 100644 --- a/modules/core/src/opengl_interop.cpp +++ b/modules/core/src/opengl_interop.cpp @@ -45,6 +45,14 @@ #include "opencv2/core/opengl_interop.hpp" #include "opencv2/core/gpumat.hpp" +#if defined WIN32 || defined _WIN32 || defined WINCE +#include +#undef small +#undef min +#undef max +#undef abs +#endif + #ifdef HAVE_OPENGL #ifdef __APPLE__ #include From 0a4ed2bc018d7b32b9d5f9b42ed51092c1dbba0d Mon Sep 17 00:00:00 2001 From: Andrey Kamaev Date: Thu, 8 Nov 2012 03:15:43 +0400 Subject: [PATCH 65/91] Fix Windows build warnings --- modules/core/test/test_mat.cpp | 8 ++++---- modules/core/test/test_math.cpp | 2 +- samples/cpp/tvl1_optical_flow.cpp | 10 +++++----- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/modules/core/test/test_mat.cpp b/modules/core/test/test_mat.cpp index e30da7258..cf045e720 100644 --- a/modules/core/test/test_mat.cpp +++ b/modules/core/test/test_mat.cpp @@ -863,17 +863,17 @@ template int calcDiffElemCountImpl(const vector& mv, const Mat& m) { int diffElemCount = 0; - const size_t mChannels = m.channels(); + const int mChannels = m.channels(); for(int y = 0; y < m.rows; y++) { for(int x = 0; x < m.cols; x++) { const ElemType* mElem = &m.at(y,x*mChannels); - size_t loc = 0; + int loc = 0; for(size_t i = 0; i < mv.size(); i++) { const size_t mvChannel = mv[i].channels(); - const ElemType* mvElem = &mv[i].at(y,x*mvChannel); + const ElemType* mvElem = &mv[i].at(y,x*(int)mvChannel); for(size_t li = 0; li < mvChannel; li++) if(mElem[loc + li] != mvElem[li]) diffElemCount++; @@ -1020,7 +1020,7 @@ public: protected: virtual int run_case(int depth, size_t channels, const Size& size, RNG& rng) { - Mat src(size, CV_MAKETYPE(depth, channels)); + Mat src(size, CV_MAKETYPE(depth, (int)channels)); rng.fill(src, RNG::UNIFORM, 0, 100, true); vector dst; diff --git a/modules/core/test/test_math.cpp b/modules/core/test/test_math.cpp index 5dd845062..91ac425d5 100644 --- a/modules/core/test/test_math.cpp +++ b/modules/core/test/test_math.cpp @@ -2421,7 +2421,7 @@ protected: } Mat diff = abs(anglesInDegrees - resInDeg); - int errDegCount = diff.total() - countNonZero((diff < maxAngleDiff) | ((360 - diff) < maxAngleDiff)); + size_t errDegCount = diff.total() - countNonZero((diff < maxAngleDiff) | ((360 - diff) < maxAngleDiff)); if(errDegCount > 0) { ts->printf(cvtest::TS::LOG, "There are incorrect result angles (in degrees) (part of them is %f)\n", diff --git a/samples/cpp/tvl1_optical_flow.cpp b/samples/cpp/tvl1_optical_flow.cpp index db4bc0b2d..d9a57a216 100644 --- a/samples/cpp/tvl1_optical_flow.cpp +++ b/samples/cpp/tvl1_optical_flow.cpp @@ -55,7 +55,7 @@ static Vec3b computeColor(float fx, float fy) } const float rad = sqrt(fx * fx + fy * fy); - const float a = atan2(-fy, -fx) / CV_PI; + const float a = atan2(-fy, -fx) / (float)CV_PI; const float fk = (a + 1.0f) / 2.0f * (NCOLS - 1); const int k0 = static_cast(fk); @@ -66,8 +66,8 @@ static Vec3b computeColor(float fx, float fy) for (int b = 0; b < 3; b++) { - const float col0 = colorWheel[k0][b] / 255.0; - const float col1 = colorWheel[k1][b] / 255.0; + const float col0 = colorWheel[k0][b] / 255.f; + const float col1 = colorWheel[k1][b] / 255.f; float col = (1 - f) * col0 + f * col1; @@ -76,7 +76,7 @@ static Vec3b computeColor(float fx, float fy) else col *= .75; // out of range - pix[2 - b] = static_cast(255.0 * col); + pix[2 - b] = static_cast(255.f * col); } return pix; @@ -175,7 +175,7 @@ int main(int argc, const char* argv[]) Mat_ flow; OpticalFlowDual_TVL1 tvl1; - const double start = getTickCount(); + const double start = (double)getTickCount(); tvl1(frame0, frame1, flow); const double timeSec = (getTickCount() - start) / getTickFrequency(); cout << "calcOpticalFlowDual_TVL1 : " << timeSec << " sec" << endl; From b131dfeecd18d23270b39f9aedeb3e4d2fc02de0 Mon Sep 17 00:00:00 2001 From: Andrey Kamaev Date: Wed, 7 Nov 2012 18:21:20 +0400 Subject: [PATCH 66/91] Build tutorial codes together with other samples These codes should be included into regular builds. --- modules/highgui/src/window.cpp | 50 ++++++++++ samples/cpp/CMakeLists.txt | 10 +- samples/cpp/Qt_sample/main.cpp | 52 ++++++---- .../HighGUI/AddingImagesTrackbar.cpp | 8 +- .../HighGUI/BasicLinearTransformsTrackbar.cpp | 8 +- .../video-input-psnr-ssim.cpp | 96 ++++++++++--------- .../HighGUI/video-write/video-write.cpp | 66 +++++++------ .../Histograms_Matching/EqualizeHist_Demo.cpp | 6 +- .../MatchTemplate_Demo.cpp | 8 +- .../calcBackProject_Demo1.cpp | 4 +- .../calcBackProject_Demo2.cpp | 4 +- .../Histograms_Matching/calcHist_Demo.cpp | 2 +- .../tutorial_code/ImgProc/AddingImages.cpp | 9 +- .../ImgProc/BasicLinearTransforms.cpp | 5 +- .../tutorial_code/ImgProc/Morphology_1.cpp | 7 +- .../tutorial_code/ImgProc/Morphology_2.cpp | 4 +- .../cpp/tutorial_code/ImgProc/Pyramids.cpp | 6 +- .../cpp/tutorial_code/ImgProc/Smoothing.cpp | 6 +- .../cpp/tutorial_code/ImgProc/Threshold.cpp | 10 +- .../ImgTrans/CannyDetector_Demo.cpp | 6 +- .../ImgTrans/Geometric_Transforms_Demo.cpp | 18 ++-- .../ImgTrans/HoughCircle_Demo.cpp | 2 +- .../ImgTrans/HoughLines_Demo.cpp | 8 +- .../tutorial_code/ImgTrans/Laplace_Demo.cpp | 6 +- .../cpp/tutorial_code/ImgTrans/Remap_Demo.cpp | 22 ++--- .../cpp/tutorial_code/ImgTrans/Sobel_Demo.cpp | 6 +- .../ImgTrans/copyMakeBorder_demo.cpp | 9 +- .../tutorial_code/ImgTrans/filter2D_demo.cpp | 6 +- .../ShapeDescriptors/findContours_demo.cpp | 8 +- .../generalContours_demo1.cpp | 10 +- .../generalContours_demo2.cpp | 10 +- .../ShapeDescriptors/hull_demo.cpp | 12 +-- .../ShapeDescriptors/moments_demo.cpp | 20 ++-- .../pointPolygonTest_demo.cpp | 18 ++-- .../TrackingMotion/cornerDetector_Demo.cpp | 8 +- .../TrackingMotion/cornerHarris_Demo.cpp | 6 +- .../TrackingMotion/cornerSubPix_Demo.cpp | 8 +- .../goodFeaturesToTrack_Demo.cpp | 6 +- .../camera_calibration/camera_calibration.cpp | 56 +++++------ .../calib3d/stereoBM/SBM_Sample.cpp | 2 +- .../tutorial_code/contrib/retina_tutorial.cpp | 2 +- .../tutorial_code/core/Matrix/Drawing_1.cpp | 52 +++++----- .../tutorial_code/core/Matrix/Drawing_2.cpp | 5 +- .../discrete_fourier_transform.cpp | 2 +- .../file_input_output/file_input_output.cpp | 8 +- .../how_to_scan_images/how_to_scan_images.cpp | 4 +- .../interoperability_with_OpenCV_1.cpp | 2 +- .../mat_mask_operations.cpp | 2 +- .../mat_the_basic_image_container.cpp | 6 +- .../features2D/SURF_FlannMatcher.cpp | 2 +- .../features2D/SURF_Homography.cpp | 13 +-- .../features2D/SURF_descriptor.cpp | 4 +- .../features2D/SURF_detector.cpp | 2 +- .../gpu-basics-similarity.cpp | 20 ++-- .../windows_visual_studio_Opencv/Test.cpp | 8 +- .../ml/non_linear_svms/non_linear_svms.cpp | 2 +- .../objectDetection/objectDetection.cpp | 16 ++-- .../objectDetection/objectDetection2.cpp | 16 ++-- 58 files changed, 420 insertions(+), 354 deletions(-) diff --git a/modules/highgui/src/window.cpp b/modules/highgui/src/window.cpp index 9fe9bc781..e6b3b1f7a 100644 --- a/modules/highgui/src/window.cpp +++ b/modules/highgui/src/window.cpp @@ -571,6 +571,56 @@ int cv::createButton(const string& button_name, ButtonCallback on_change, void* return cvCreateButton(button_name.c_str(), on_change, userdata, button_type , initial_button_state ); } +#else + +CvFont cv::fontQt(const string&, int, Scalar, int, int, int) +{ + CV_Error(CV_StsNotImplemented, "The library is compiled without QT support"); + return CvFont(); +} + +void cv::addText( const Mat&, const string&, Point, CvFont) +{ + CV_Error(CV_StsNotImplemented, "The library is compiled without QT support"); +} + +void cv::displayStatusBar(const string&, const string&, int) +{ + CV_Error(CV_StsNotImplemented, "The library is compiled without QT support"); +} + +void cv::displayOverlay(const string&, const string&, int ) +{ + CV_Error(CV_StsNotImplemented, "The library is compiled without QT support"); +} + +int cv::startLoop(int (*)(int argc, char *argv[]), int , char**) +{ + CV_Error(CV_StsNotImplemented, "The library is compiled without QT support"); + return 0; +} + +void cv::stopLoop() +{ + CV_Error(CV_StsNotImplemented, "The library is compiled without QT support"); +} + +void cv::saveWindowParameters(const string&) +{ + CV_Error(CV_StsNotImplemented, "The library is compiled without QT support"); +} + +void cv::loadWindowParameters(const string&) +{ + CV_Error(CV_StsNotImplemented, "The library is compiled without QT support"); +} + +int cv::createButton(const string&, ButtonCallback, void*, int , bool ) +{ + CV_Error(CV_StsNotImplemented, "The library is compiled without QT support"); + return 0; +} + #endif #if defined WIN32 || defined _WIN32 // see window_w32.cpp diff --git a/samples/cpp/CMakeLists.txt b/samples/cpp/CMakeLists.txt index c2b49a75e..1ed0d2c6f 100644 --- a/samples/cpp/CMakeLists.txt +++ b/samples/cpp/CMakeLists.txt @@ -53,7 +53,15 @@ if(BUILD_EXAMPLES AND OCV_DEPENDENCIES_FOUND) endif() ENDMACRO() - file(GLOB cpp_samples RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp) + file(GLOB_RECURSE cpp_samples RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp) + + if(NOT HAVE_OPENGL) + ocv_list_filterout(cpp_samples Qt_sample) + endif() + + if(NOT HAVE_opencv_gpu) + ocv_list_filterout(cpp_samples "/gpu/") + endif() foreach(sample_filename ${cpp_samples}) get_filename_component(sample ${sample_filename} NAME_WE) diff --git a/samples/cpp/Qt_sample/main.cpp b/samples/cpp/Qt_sample/main.cpp index 1576f6e82..f987de471 100644 --- a/samples/cpp/Qt_sample/main.cpp +++ b/samples/cpp/Qt_sample/main.cpp @@ -4,14 +4,29 @@ #include #include - #include -#include + +#if defined WIN32 || defined _WIN32 || defined WINCE + #include + #undef small + #undef min + #undef max + #undef abs +#endif + +#ifdef __APPLE__ + #include +#else + #include +#endif + #include #include + using namespace std; using namespace cv; -void help() + +static void help() { cout << "\nThis demo demonstrates the use of the Qt enhanced version of the highgui GUI interface\n" " and dang if it doesn't throw in the use of of the POSIT 3D tracking algorithm too\n" @@ -29,7 +44,7 @@ void help() #define FOCAL_LENGTH 600 #define CUBE_SIZE 10 -void renderCube(float size) +static void renderCube(float size) { glBegin(GL_QUADS); // Front Face @@ -72,7 +87,7 @@ void renderCube(float size) } -void on_opengl(void* param) +static void on_opengl(void* param) { //Draw the object with the estimated pose glLoadIdentity(); @@ -87,7 +102,7 @@ void on_opengl(void* param) glDisable( GL_LIGHTING ); } -void initPOSIT(std::vector *modelPoints) +static void initPOSIT(std::vector *modelPoints) { //Create the model pointss modelPoints->push_back(cvPoint3D32f(0.0f, 0.0f, 0.0f)); //The first must be (0,0,0) @@ -96,7 +111,7 @@ void initPOSIT(std::vector *modelPoints) modelPoints->push_back(cvPoint3D32f(0.0f, CUBE_SIZE, 0.0f)); } -void foundCorners(vector *srcImagePoints,IplImage* source, IplImage* grayImage) +static void foundCorners(vector *srcImagePoints,IplImage* source, IplImage* grayImage) { cvCvtColor(source,grayImage,CV_RGB2GRAY); cvSmooth( grayImage, grayImage,CV_GAUSSIAN,11); @@ -116,12 +131,12 @@ void foundCorners(vector *srcImagePoints,IplImage* source, IplImag if (contours.size() == srcImagePoints_temp.size()) { - for(int i = 0 ; i *srcImagePoints,IplImage* source, IplImag //< y = 3 //get point 0; - int index = 0; - for(int i = 1 ; i srcImagePoints_temp.at(index).y) index = i; @@ -144,7 +159,7 @@ void foundCorners(vector *srcImagePoints,IplImage* source, IplImag //get point 1; index = 0; - for(int i = 1 ; i srcImagePoints_temp.at(index).x) index = i; @@ -153,7 +168,7 @@ void foundCorners(vector *srcImagePoints,IplImage* source, IplImag //get point 2; index = 0; - for(int i = 1 ; i *srcImagePoints,IplImage* source, IplImag //get point 3; index = 0; - for(int i = 1 ; i *srcImagePoints,IplImage* source, IplImag Mat Msource = source; stringstream ss; - for(int i = 0 ; iat(i),5,CV_RGB(255,0,0)); @@ -185,7 +200,7 @@ void foundCorners(vector *srcImagePoints,IplImage* source, IplImag } -void createOpenGLMatrixFrom(float *posePOSIT,const CvMatr32f &rotationMatrix, const CvVect32f &translationVector) +static void createOpenGLMatrixFrom(float *posePOSIT,const CvMatr32f &rotationMatrix, const CvVect32f &translationVector) { @@ -206,8 +221,9 @@ void createOpenGLMatrixFrom(float *posePOSIT,const CvMatr32f &rotationMatrix, co posePOSIT[15] = 1.0; } -int main(int argc, char *argv[]) +int main(void) { + help(); CvCapture* video = cvCaptureFromFile("cube4.avi"); CV_Assert(video); @@ -220,7 +236,7 @@ int main(int argc, char *argv[]) //For debug //cvNamedWindow("tempGray",CV_WINDOW_AUTOSIZE); float OpenGLMatrix[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; - cvCreateOpenGLCallback("POSIT",on_opengl,OpenGLMatrix); + cvSetOpenGlDrawCallback("POSIT",on_opengl,OpenGLMatrix); vector modelPoints; initPOSIT(&modelPoints); diff --git a/samples/cpp/tutorial_code/HighGUI/AddingImagesTrackbar.cpp b/samples/cpp/tutorial_code/HighGUI/AddingImagesTrackbar.cpp index a7acc6eed..eb858a472 100644 --- a/samples/cpp/tutorial_code/HighGUI/AddingImagesTrackbar.cpp +++ b/samples/cpp/tutorial_code/HighGUI/AddingImagesTrackbar.cpp @@ -4,8 +4,8 @@ * @author OpenCV team */ -#include -#include +#include "opencv2/highgui/highgui.hpp" +#include using namespace cv; @@ -24,7 +24,7 @@ Mat dst; * @function on_trackbar * @brief Callback for trackbar */ -void on_trackbar( int, void* ) +static void on_trackbar( int, void* ) { alpha = (double) alpha_slider/alpha_slider_max ; @@ -40,7 +40,7 @@ void on_trackbar( int, void* ) * @function main * @brief Main function */ -int main( int argc, char** argv ) +int main( void ) { /// Read image ( same size, same type ) src1 = imread("../images/LinuxLogo.jpg"); diff --git a/samples/cpp/tutorial_code/HighGUI/BasicLinearTransformsTrackbar.cpp b/samples/cpp/tutorial_code/HighGUI/BasicLinearTransformsTrackbar.cpp index 230b01d59..b344c96e0 100644 --- a/samples/cpp/tutorial_code/HighGUI/BasicLinearTransformsTrackbar.cpp +++ b/samples/cpp/tutorial_code/HighGUI/BasicLinearTransformsTrackbar.cpp @@ -5,8 +5,7 @@ * @author OpenCV team */ -#include -#include +#include "opencv2/highgui/highgui.hpp" using namespace cv; @@ -18,13 +17,12 @@ int beta; /**< Simple brightness control*/ /** Matrices to store images */ Mat image; -Mat new_image; /** * @function on_trackbar * @brief Called whenever any of alpha or beta changes */ -void on_trackbar( int, void* ) +static void on_trackbar( int, void* ) { Mat new_image = Mat::zeros( image.size(), image.type() ); @@ -44,7 +42,7 @@ void on_trackbar( int, void* ) * @function main * @brief Main function */ -int main( int argc, char** argv ) +int main( int, char** argv ) { /// Read image given by user image = imread( argv[1] ); diff --git a/samples/cpp/tutorial_code/HighGUI/video-input-psnr-ssim/video-input-psnr-ssim.cpp b/samples/cpp/tutorial_code/HighGUI/video-input-psnr-ssim/video-input-psnr-ssim.cpp index a81d9c2b3..56f6e7dfa 100644 --- a/samples/cpp/tutorial_code/HighGUI/video-input-psnr-ssim/video-input-psnr-ssim.cpp +++ b/samples/cpp/tutorial_code/HighGUI/video-input-psnr-ssim/video-input-psnr-ssim.cpp @@ -1,10 +1,10 @@ -#include // for standard I/O +#include // for standard I/O #include // for strings #include // for controlling float print precision #include // string to number conversion -#include // Gaussian Blur #include // Basic OpenCV structures (cv::Mat, Scalar) +#include // Gaussian Blur #include // OpenCV window I/O using namespace std; @@ -13,55 +13,57 @@ using namespace cv; double getPSNR ( const Mat& I1, const Mat& I2); Scalar getMSSIM( const Mat& I1, const Mat& I2); -void help() +static void help() { cout - << "\n--------------------------------------------------------------------------" << endl - << "This program shows how to read a video file with OpenCV. In addition, it tests the" - << " similarity of two input videos first with PSNR, and for the frames below a PSNR " << endl - << "trigger value, also with MSSIM."<< endl - << "Usage:" << endl + << "------------------------------------------------------------------------------" << endl + << "This program shows how to read a video file with OpenCV. In addition, it " + << "tests the similarity of two input videos first with PSNR, and for the frames " + << "below a PSNR trigger value, also with MSSIM." << endl + << "Usage:" << endl << "./video-source referenceVideo useCaseTestVideo PSNR_Trigger_Value Wait_Between_Frames " << endl - << "--------------------------------------------------------------------------" << endl + << "--------------------------------------------------------------------------" << endl << endl; } -int main(int argc, char *argv[], char *window_name) + +int main(int argc, char *argv[]) { help(); + if (argc != 5) { cout << "Not enough parameters" << endl; return -1; } + stringstream conv; - const string sourceReference = argv[1],sourceCompareWith = argv[2]; + const string sourceReference = argv[1], sourceCompareWith = argv[2]; int psnrTriggerValue, delay; - conv << argv[3] << endl << argv[4]; // put in the strings - conv >> psnrTriggerValue >> delay;// take out the numbers + conv << argv[3] << endl << argv[4]; // put in the strings + conv >> psnrTriggerValue >> delay; // take out the numbers char c; - int frameNum = -1; // Frame counter + int frameNum = -1; // Frame counter - VideoCapture captRefrnc(sourceReference), - captUndTst(sourceCompareWith); + VideoCapture captRefrnc(sourceReference), captUndTst(sourceCompareWith); - if ( !captRefrnc.isOpened()) + if (!captRefrnc.isOpened()) { cout << "Could not open reference " << sourceReference << endl; return -1; } - if( !captUndTst.isOpened()) + if (!captUndTst.isOpened()) { cout << "Could not open case test " << sourceCompareWith << endl; return -1; } Size refS = Size((int) captRefrnc.get(CV_CAP_PROP_FRAME_WIDTH), - (int) captRefrnc.get(CV_CAP_PROP_FRAME_HEIGHT)), - uTSi = Size((int) captUndTst.get(CV_CAP_PROP_FRAME_WIDTH), - (int) captUndTst.get(CV_CAP_PROP_FRAME_HEIGHT)); + (int) captRefrnc.get(CV_CAP_PROP_FRAME_HEIGHT)), + uTSi = Size((int) captUndTst.get(CV_CAP_PROP_FRAME_WIDTH), + (int) captUndTst.get(CV_CAP_PROP_FRAME_HEIGHT)); if (refS != uTSi) { @@ -73,43 +75,43 @@ int main(int argc, char *argv[], char *window_name) const char* WIN_RF = "Reference"; // Windows - namedWindow(WIN_RF, CV_WINDOW_AUTOSIZE ); - namedWindow(WIN_UT, CV_WINDOW_AUTOSIZE ); - cvMoveWindow(WIN_RF, 400 , 0); //750, 2 (bernat =0) - cvMoveWindow(WIN_UT, refS.width, 0); //1500, 2 + namedWindow(WIN_RF, CV_WINDOW_AUTOSIZE); + namedWindow(WIN_UT, CV_WINDOW_AUTOSIZE); + cvMoveWindow(WIN_RF, 400 , 0); //750, 2 (bernat =0) + cvMoveWindow(WIN_UT, refS.width, 0); //1500, 2 cout << "Reference frame resolution: Width=" << refS.width << " Height=" << refS.height - << " of nr#: " << captRefrnc.get(CV_CAP_PROP_FRAME_COUNT) << endl; + << " of nr#: " << captRefrnc.get(CV_CAP_PROP_FRAME_COUNT) << endl; - cout << "PSNR trigger value " << - setiosflags(ios::fixed) << setprecision(3) << psnrTriggerValue << endl; + cout << "PSNR trigger value " << setiosflags(ios::fixed) << setprecision(3) + << psnrTriggerValue << endl; Mat frameReference, frameUnderTest; double psnrV; Scalar mssimV; - while( true) //Show the image captured in the window and repeat + for(;;) //Show the image captured in the window and repeat { captRefrnc >> frameReference; captUndTst >> frameUnderTest; - if( frameReference.empty() || frameUnderTest.empty()) + if (frameReference.empty() || frameUnderTest.empty()) { cout << " < < < Game over! > > > "; break; } ++frameNum; - cout <<"Frame:" << frameNum <<"# "; + cout << "Frame: " << frameNum << "# "; ///////////////////////////////// PSNR //////////////////////////////////////////////////// - psnrV = getPSNR(frameReference,frameUnderTest); //get PSNR + psnrV = getPSNR(frameReference,frameUnderTest); cout << setiosflags(ios::fixed) << setprecision(3) << psnrV << "dB"; //////////////////////////////////// MSSIM ///////////////////////////////////////////////// if (psnrV < psnrTriggerValue && psnrV) { - mssimV = getMSSIM(frameReference,frameUnderTest); + mssimV = getMSSIM(frameReference, frameUnderTest); cout << " MSSIM: " << " R " << setiosflags(ios::fixed) << setprecision(2) << mssimV.val[2] * 100 << "%" @@ -120,10 +122,10 @@ int main(int argc, char *argv[], char *window_name) cout << endl; ////////////////////////////////// Show Image ///////////////////////////////////////////// - imshow( WIN_RF, frameReference); - imshow( WIN_UT, frameUnderTest); + imshow(WIN_RF, frameReference); + imshow(WIN_UT, frameUnderTest); - c = cvWaitKey(delay); + c = (char)cvWaitKey(delay); if (c == 27) break; } @@ -137,7 +139,7 @@ double getPSNR(const Mat& I1, const Mat& I2) s1.convertTo(s1, CV_32F); // cannot make a square on 8 bits s1 = s1.mul(s1); // |I1 - I2|^2 - Scalar s = sum(s1); // sum elements per channel + Scalar s = sum(s1); // sum elements per channel double sse = s.val[0] + s.val[1] + s.val[2]; // sum channels @@ -145,8 +147,8 @@ double getPSNR(const Mat& I1, const Mat& I2) return 0; else { - double mse =sse /(double)(I1.channels() * I1.total()); - double psnr = 10.0*log10((255*255)/mse); + double mse = sse / (double)(I1.channels() * I1.total()); + double psnr = 10.0 * log10((255 * 255) / mse); return psnr; } } @@ -155,10 +157,10 @@ Scalar getMSSIM( const Mat& i1, const Mat& i2) { const double C1 = 6.5025, C2 = 58.5225; /***************************** INITS **********************************/ - int d = CV_32F; + int d = CV_32F; Mat I1, I2; - i1.convertTo(I1, d); // cannot calculate on one byte large values + i1.convertTo(I1, d); // cannot calculate on one byte large values i2.convertTo(I2, d); Mat I2_2 = I2.mul(I2); // I2^2 @@ -167,7 +169,7 @@ Scalar getMSSIM( const Mat& i1, const Mat& i2) /*************************** END INITS **********************************/ - Mat mu1, mu2; // PRELIMINARY COMPUTING + Mat mu1, mu2; // PRELIMINARY COMPUTING GaussianBlur(I1, mu1, Size(11, 11), 1.5); GaussianBlur(I2, mu2, Size(11, 11), 1.5); @@ -191,15 +193,15 @@ Scalar getMSSIM( const Mat& i1, const Mat& i2) t1 = 2 * mu1_mu2 + C1; t2 = 2 * sigma12 + C2; - t3 = t1.mul(t2); // t3 = ((2*mu1_mu2 + C1).*(2*sigma12 + C2)) + t3 = t1.mul(t2); // t3 = ((2*mu1_mu2 + C1).*(2*sigma12 + C2)) t1 = mu1_2 + mu2_2 + C1; t2 = sigma1_2 + sigma2_2 + C2; - t1 = t1.mul(t2); // t1 =((mu1_2 + mu2_2 + C1).*(sigma1_2 + sigma2_2 + C2)) + t1 = t1.mul(t2); // t1 =((mu1_2 + mu2_2 + C1).*(sigma1_2 + sigma2_2 + C2)) Mat ssim_map; - divide(t3, t1, ssim_map); // ssim_map = t3./t1; + divide(t3, t1, ssim_map); // ssim_map = t3./t1; - Scalar mssim = mean( ssim_map ); // mssim = average of ssim map + Scalar mssim = mean(ssim_map); // mssim = average of ssim map return mssim; -} \ No newline at end of file +} diff --git a/samples/cpp/tutorial_code/HighGUI/video-write/video-write.cpp b/samples/cpp/tutorial_code/HighGUI/video-write/video-write.cpp index d55571829..8ee99a10a 100644 --- a/samples/cpp/tutorial_code/HighGUI/video-write/video-write.cpp +++ b/samples/cpp/tutorial_code/HighGUI/video-write/video-write.cpp @@ -7,51 +7,53 @@ using namespace std; using namespace cv; -void help() +static void help() { cout - << "\n--------------------------------------------------------------------------" << endl - << "This program shows how to write video files. You can extract the R or G or B color channel " - << " of the input video.write " << endl - << "Usage:" << endl - << "./video-write inputvideoName [ R | G | B] [Y | N]" << endl - << "--------------------------------------------------------------------------" << endl + << "------------------------------------------------------------------------------" << endl + << "This program shows how to write video files." << endl + << "You can extract the R or G or B color channel of the input video." << endl + << "Usage:" << endl + << "./video-write inputvideoName [ R | G | B] [Y | N]" << endl + << "------------------------------------------------------------------------------" << endl << endl; } -int main(int argc, char *argv[], char *window_name) + +int main(int argc, char *argv[]) { help(); + if (argc != 4) { cout << "Not enough parameters" << endl; return -1; } - const string source = argv[1]; // the source file name + const string source = argv[1]; // the source file name const bool askOutputType = argv[3][0] =='Y'; // If false it will use the inputs codec type - VideoCapture inputVideo(source); // Open input - if ( !inputVideo.isOpened()) + VideoCapture inputVideo(source); // Open input + if (!inputVideo.isOpened()) { - cout << "Could not open the input video." << source << endl; + cout << "Could not open the input video: " << source << endl; return -1; } - string::size_type pAt = source.find_last_of('.'); // Find extension point + string::size_type pAt = source.find_last_of('.'); // Find extension point const string NAME = source.substr(0, pAt) + argv[2][0] + ".avi"; // Form the new name with container int ex = static_cast(inputVideo.get(CV_CAP_PROP_FOURCC)); // Get Codec Type- Int form // Transform from int to char via Bitwise operators - char EXT[] = {ex & 0XFF , (ex & 0XFF00) >> 8,(ex & 0XFF0000) >> 16,(ex & 0XFF000000) >> 24, 0}; + char EXT[] = {(char)(ex & 0XFF) , (char)((ex & 0XFF00) >> 8),(char)((ex & 0XFF0000) >> 16),(char)((ex & 0XFF000000) >> 24), 0}; - Size S = Size((int) inputVideo.get(CV_CAP_PROP_FRAME_WIDTH), //Acquire input size + Size S = Size((int) inputVideo.get(CV_CAP_PROP_FRAME_WIDTH), // Acquire input size (int) inputVideo.get(CV_CAP_PROP_FRAME_HEIGHT)); VideoWriter outputVideo; // Open the output if (askOutputType) - outputVideo.open(NAME , ex=-1, inputVideo.get(CV_CAP_PROP_FPS),S, true); + outputVideo.open(NAME, ex=-1, inputVideo.get(CV_CAP_PROP_FPS), S, true); else - outputVideo.open(NAME , ex, inputVideo.get(CV_CAP_PROP_FPS),S, true); + outputVideo.open(NAME, ex, inputVideo.get(CV_CAP_PROP_FPS), S, true); if (!outputVideo.isOpened()) { @@ -59,33 +61,29 @@ int main(int argc, char *argv[], char *window_name) return -1; } - union { int v; char c[5];} uEx ; - uEx.v = ex; // From Int to char via union - uEx.c[4]='\0'; - cout << "Input frame resolution: Width=" << S.width << " Height=" << S.height - << " of nr#: " << inputVideo.get(CV_CAP_PROP_FRAME_COUNT) << endl; + << " of nr#: " << inputVideo.get(CV_CAP_PROP_FRAME_COUNT) << endl; cout << "Input codec type: " << EXT << endl; - int channel = 2; // Select the channel to save + int channel = 2; // Select the channel to save switch(argv[2][0]) { - case 'R' : {channel = 2; break;} - case 'G' : {channel = 1; break;} - case 'B' : {channel = 0; break;} + case 'R' : channel = 2; break; + case 'G' : channel = 1; break; + case 'B' : channel = 0; break; } - Mat src,res; + Mat src, res; vector spl; - while( true) //Show the image captured in the window and repeat + for(;;) //Show the image captured in the window and repeat { inputVideo >> src; // read - if( src.empty()) break; // check if at end + if (src.empty()) break; // check if at end - split(src, spl); // process - extract only the correct channel - for( int i =0; i < 3; ++i) - if (i != channel) - spl[i] = Mat::zeros(S, spl[0].type()); + split(src, spl); // process - extract only the correct channel + for (int i =0; i < 3; ++i) + if (i != channel) + spl[i] = Mat::zeros(S, spl[0].type()); merge(spl, res); //outputVideo.write(res); //save or @@ -94,4 +92,4 @@ int main(int argc, char *argv[], char *window_name) cout << "Finished writing" << endl; return 0; -} \ No newline at end of file +} diff --git a/samples/cpp/tutorial_code/Histograms_Matching/EqualizeHist_Demo.cpp b/samples/cpp/tutorial_code/Histograms_Matching/EqualizeHist_Demo.cpp index ff51cdf6b..49e4be0e5 100644 --- a/samples/cpp/tutorial_code/Histograms_Matching/EqualizeHist_Demo.cpp +++ b/samples/cpp/tutorial_code/Histograms_Matching/EqualizeHist_Demo.cpp @@ -15,12 +15,12 @@ using namespace std; /** * @function main */ -int main( int argc, char** argv ) +int main( int, char** argv ) { Mat src, dst; - char* source_window = "Source image"; - char* equalized_window = "Equalized Image"; + const char* source_window = "Source image"; + const char* equalized_window = "Equalized Image"; /// Load image src = imread( argv[1], 1 ); diff --git a/samples/cpp/tutorial_code/Histograms_Matching/MatchTemplate_Demo.cpp b/samples/cpp/tutorial_code/Histograms_Matching/MatchTemplate_Demo.cpp index 2522f1c04..e3633576f 100644 --- a/samples/cpp/tutorial_code/Histograms_Matching/MatchTemplate_Demo.cpp +++ b/samples/cpp/tutorial_code/Histograms_Matching/MatchTemplate_Demo.cpp @@ -14,8 +14,8 @@ using namespace cv; /// Global Variables Mat img; Mat templ; Mat result; -char* image_window = "Source Image"; -char* result_window = "Result window"; +const char* image_window = "Source Image"; +const char* result_window = "Result window"; int match_method; int max_Trackbar = 5; @@ -26,7 +26,7 @@ void MatchingMethod( int, void* ); /** * @function main */ -int main( int argc, char** argv ) +int main( int, char** argv ) { /// Load image and template img = imread( argv[1], 1 ); @@ -37,7 +37,7 @@ int main( int argc, char** argv ) namedWindow( result_window, CV_WINDOW_AUTOSIZE ); /// Create Trackbar - char* trackbar_label = "Method: \n 0: SQDIFF \n 1: SQDIFF NORMED \n 2: TM CCORR \n 3: TM CCORR NORMED \n 4: TM COEFF \n 5: TM COEFF NORMED"; + const char* trackbar_label = "Method: \n 0: SQDIFF \n 1: SQDIFF NORMED \n 2: TM CCORR \n 3: TM CCORR NORMED \n 4: TM COEFF \n 5: TM COEFF NORMED"; createTrackbar( trackbar_label, image_window, &match_method, max_Trackbar, MatchingMethod ); MatchingMethod( 0, 0 ); diff --git a/samples/cpp/tutorial_code/Histograms_Matching/calcBackProject_Demo1.cpp b/samples/cpp/tutorial_code/Histograms_Matching/calcBackProject_Demo1.cpp index 2e6fcc0d8..f42260374 100644 --- a/samples/cpp/tutorial_code/Histograms_Matching/calcBackProject_Demo1.cpp +++ b/samples/cpp/tutorial_code/Histograms_Matching/calcBackProject_Demo1.cpp @@ -23,7 +23,7 @@ void Hist_and_Backproj(int, void* ); /** * @function main */ -int main( int argc, char** argv ) +int main( int, char** argv ) { /// Read the image src = imread( argv[1], 1 ); @@ -36,7 +36,7 @@ int main( int argc, char** argv ) mixChannels( &hsv, 1, &hue, 1, ch, 1 ); /// Create Trackbar to enter the number of bins - char* window_image = "Source image"; + const char* window_image = "Source image"; namedWindow( window_image, CV_WINDOW_AUTOSIZE ); createTrackbar("* Hue bins: ", window_image, &bins, 180, Hist_and_Backproj ); Hist_and_Backproj(0, 0); diff --git a/samples/cpp/tutorial_code/Histograms_Matching/calcBackProject_Demo2.cpp b/samples/cpp/tutorial_code/Histograms_Matching/calcBackProject_Demo2.cpp index 7d53af391..42dd01a67 100644 --- a/samples/cpp/tutorial_code/Histograms_Matching/calcBackProject_Demo2.cpp +++ b/samples/cpp/tutorial_code/Histograms_Matching/calcBackProject_Demo2.cpp @@ -17,7 +17,7 @@ Mat src; Mat hsv; Mat mask; int lo = 20; int up = 20; -char* window_image = "Source image"; +const char* window_image = "Source image"; /// Function Headers void Hist_and_Backproj( ); @@ -26,7 +26,7 @@ void pickPoint (int event, int x, int y, int, void* ); /** * @function main */ -int main( int argc, char** argv ) +int main( int, char** argv ) { /// Read the image src = imread( argv[1], 1 ); diff --git a/samples/cpp/tutorial_code/Histograms_Matching/calcHist_Demo.cpp b/samples/cpp/tutorial_code/Histograms_Matching/calcHist_Demo.cpp index e010c6ac0..d3af5e7a9 100644 --- a/samples/cpp/tutorial_code/Histograms_Matching/calcHist_Demo.cpp +++ b/samples/cpp/tutorial_code/Histograms_Matching/calcHist_Demo.cpp @@ -15,7 +15,7 @@ using namespace cv; /** * @function main */ -int main( int argc, char** argv ) +int main( int, char** argv ) { Mat src, dst; diff --git a/samples/cpp/tutorial_code/ImgProc/AddingImages.cpp b/samples/cpp/tutorial_code/ImgProc/AddingImages.cpp index 40056ad4f..4e974275c 100644 --- a/samples/cpp/tutorial_code/ImgProc/AddingImages.cpp +++ b/samples/cpp/tutorial_code/ImgProc/AddingImages.cpp @@ -4,8 +4,7 @@ * @author OpenCV team */ -#include -#include +#include "opencv2/highgui/highgui.hpp" #include using namespace cv; @@ -14,7 +13,7 @@ using namespace cv; * @function main * @brief Main function */ -int main( int argc, char** argv ) +int main( void ) { double alpha = 0.5; double beta; double input; @@ -35,8 +34,8 @@ int main( int argc, char** argv ) src1 = imread("../images/LinuxLogo.jpg"); src2 = imread("../images/WindowsLogo.jpg"); - if( !src1.data ) { printf("Error loading src1 \n"); return -1; } - if( !src2.data ) { printf("Error loading src2 \n"); return -1; } + if( !src1.data ) { std::cout<< "Error loading src1"< -#include +#include "opencv2/highgui/highgui.hpp" #include using namespace cv; @@ -17,7 +16,7 @@ int beta; /**< Simple brightness control */ * @function main * @brief Main function */ -int main( int argc, char** argv ) +int main( int, char** argv ) { /// Read image given by user Mat image = imread( argv[1] ); diff --git a/samples/cpp/tutorial_code/ImgProc/Morphology_1.cpp b/samples/cpp/tutorial_code/ImgProc/Morphology_1.cpp index 61f1cf06f..47030fa4f 100644 --- a/samples/cpp/tutorial_code/ImgProc/Morphology_1.cpp +++ b/samples/cpp/tutorial_code/ImgProc/Morphology_1.cpp @@ -6,7 +6,6 @@ #include "opencv2/imgproc/imgproc.hpp" #include "opencv2/highgui/highgui.hpp" -#include "highgui.h" #include #include @@ -29,7 +28,7 @@ void Dilation( int, void* ); /** * @function main */ -int main( int argc, char** argv ) +int main( int, char** argv ) { /// Load an image src = imread( argv[1] ); @@ -73,7 +72,7 @@ int main( int argc, char** argv ) */ void Erosion( int, void* ) { - int erosion_type; + int erosion_type = 0; if( erosion_elem == 0 ){ erosion_type = MORPH_RECT; } else if( erosion_elem == 1 ){ erosion_type = MORPH_CROSS; } else if( erosion_elem == 2) { erosion_type = MORPH_ELLIPSE; } @@ -91,7 +90,7 @@ void Erosion( int, void* ) */ void Dilation( int, void* ) { - int dilation_type; + int dilation_type = 0; if( dilation_elem == 0 ){ dilation_type = MORPH_RECT; } else if( dilation_elem == 1 ){ dilation_type = MORPH_CROSS; } else if( dilation_elem == 2) { dilation_type = MORPH_ELLIPSE; } diff --git a/samples/cpp/tutorial_code/ImgProc/Morphology_2.cpp b/samples/cpp/tutorial_code/ImgProc/Morphology_2.cpp index ab1cc9457..c501bfd32 100644 --- a/samples/cpp/tutorial_code/ImgProc/Morphology_2.cpp +++ b/samples/cpp/tutorial_code/ImgProc/Morphology_2.cpp @@ -21,7 +21,7 @@ int const max_operator = 4; int const max_elem = 2; int const max_kernel_size = 21; -char* window_name = "Morphology Transformations Demo"; +const char* window_name = "Morphology Transformations Demo"; /** Function Headers */ @@ -30,7 +30,7 @@ void Morphology_Operations( int, void* ); /** * @function main */ -int main( int argc, char** argv ) +int main( int, char** argv ) { /// Load an image src = imread( argv[1] ); diff --git a/samples/cpp/tutorial_code/ImgProc/Pyramids.cpp b/samples/cpp/tutorial_code/ImgProc/Pyramids.cpp index 825fb4b47..d0cae3c4f 100644 --- a/samples/cpp/tutorial_code/ImgProc/Pyramids.cpp +++ b/samples/cpp/tutorial_code/ImgProc/Pyramids.cpp @@ -15,13 +15,13 @@ using namespace cv; /// Global variables Mat src, dst, tmp; -char* window_name = "Pyramids Demo"; +const char* window_name = "Pyramids Demo"; /** * @function main */ -int main( int argc, char** argv ) +int main( void ) { /// General instructions printf( "\n Zoom In-Out demo \n " ); @@ -44,7 +44,7 @@ int main( int argc, char** argv ) imshow( window_name, dst ); /// Loop - while( true ) + for(;;) { int c; c = waitKey(10); diff --git a/samples/cpp/tutorial_code/ImgProc/Smoothing.cpp b/samples/cpp/tutorial_code/ImgProc/Smoothing.cpp index d541a4334..5f51d07d2 100644 --- a/samples/cpp/tutorial_code/ImgProc/Smoothing.cpp +++ b/samples/cpp/tutorial_code/ImgProc/Smoothing.cpp @@ -22,14 +22,14 @@ Mat src; Mat dst; char window_name[] = "Smoothing Demo"; /// Function headers -int display_caption( char* caption ); +int display_caption( const char* caption ); int display_dst( int delay ); /** * function main */ -int main( int argc, char** argv ) +int main( void ) { namedWindow( window_name, CV_WINDOW_AUTOSIZE ); @@ -84,7 +84,7 @@ int main( int argc, char** argv ) /** * @function display_caption */ -int display_caption( char* caption ) +int display_caption( const char* caption ) { dst = Mat::zeros( src.size(), src.type() ); putText( dst, caption, diff --git a/samples/cpp/tutorial_code/ImgProc/Threshold.cpp b/samples/cpp/tutorial_code/ImgProc/Threshold.cpp index c20aa2359..7505ec297 100644 --- a/samples/cpp/tutorial_code/ImgProc/Threshold.cpp +++ b/samples/cpp/tutorial_code/ImgProc/Threshold.cpp @@ -20,10 +20,10 @@ int const max_type = 4; int const max_BINARY_value = 255; Mat src, src_gray, dst; -char* window_name = "Threshold Demo"; +const char* window_name = "Threshold Demo"; -char* trackbar_type = "Type: \n 0: Binary \n 1: Binary Inverted \n 2: Truncate \n 3: To Zero \n 4: To Zero Inverted"; -char* trackbar_value = "Value"; +const char* trackbar_type = "Type: \n 0: Binary \n 1: Binary Inverted \n 2: Truncate \n 3: To Zero \n 4: To Zero Inverted"; +const char* trackbar_value = "Value"; /// Function headers void Threshold_Demo( int, void* ); @@ -31,7 +31,7 @@ void Threshold_Demo( int, void* ); /** * @function main */ -int main( int argc, char** argv ) +int main( int, char** argv ) { /// Load an image src = imread( argv[1], 1 ); @@ -55,7 +55,7 @@ int main( int argc, char** argv ) Threshold_Demo( 0, 0 ); /// Wait until user finishes program - while(true) + for(;;) { int c; c = waitKey( 20 ); diff --git a/samples/cpp/tutorial_code/ImgTrans/CannyDetector_Demo.cpp b/samples/cpp/tutorial_code/ImgTrans/CannyDetector_Demo.cpp index 9dc6ea083..c798f2fb4 100644 --- a/samples/cpp/tutorial_code/ImgTrans/CannyDetector_Demo.cpp +++ b/samples/cpp/tutorial_code/ImgTrans/CannyDetector_Demo.cpp @@ -21,13 +21,13 @@ int lowThreshold; int const max_lowThreshold = 100; int ratio = 3; int kernel_size = 3; -char* window_name = "Edge Map"; +const char* window_name = "Edge Map"; /** * @function CannyThreshold * @brief Trackbar callback - Canny thresholds input with a ratio 1:3 */ -void CannyThreshold(int, void*) +static void CannyThreshold(int, void*) { /// Reduce noise with a kernel 3x3 blur( src_gray, detected_edges, Size(3,3) ); @@ -46,7 +46,7 @@ void CannyThreshold(int, void*) /** * @function main */ -int main( int argc, char** argv ) +int main( int, char** argv ) { /// Load an image src = imread( argv[1] ); diff --git a/samples/cpp/tutorial_code/ImgTrans/Geometric_Transforms_Demo.cpp b/samples/cpp/tutorial_code/ImgTrans/Geometric_Transforms_Demo.cpp index 28422b882..2d1835720 100644 --- a/samples/cpp/tutorial_code/ImgTrans/Geometric_Transforms_Demo.cpp +++ b/samples/cpp/tutorial_code/ImgTrans/Geometric_Transforms_Demo.cpp @@ -13,14 +13,14 @@ using namespace cv; using namespace std; /// Global variables -char* source_window = "Source image"; -char* warp_window = "Warp"; -char* warp_rotate_window = "Warp + Rotate"; +const char* source_window = "Source image"; +const char* warp_window = "Warp"; +const char* warp_rotate_window = "Warp + Rotate"; /** * @function main */ -int main( int argc, char** argv ) +int main( int, char** argv ) { Point2f srcTri[3]; Point2f dstTri[3]; @@ -37,12 +37,12 @@ int main( int argc, char** argv ) /// Set your 3 points to calculate the Affine Transform srcTri[0] = Point2f( 0,0 ); - srcTri[1] = Point2f( src.cols - 1, 0 ); - srcTri[2] = Point2f( 0, src.rows - 1 ); + srcTri[1] = Point2f( src.cols - 1.f, 0 ); + srcTri[2] = Point2f( 0, src.rows - 1.f ); - dstTri[0] = Point2f( src.cols*0.0, src.rows*0.33 ); - dstTri[1] = Point2f( src.cols*0.85, src.rows*0.25 ); - dstTri[2] = Point2f( src.cols*0.15, src.rows*0.7 ); + dstTri[0] = Point2f( src.cols*0.0f, src.rows*0.33f ); + dstTri[1] = Point2f( src.cols*0.85f, src.rows*0.25f ); + dstTri[2] = Point2f( src.cols*0.15f, src.rows*0.7f ); /// Get the Affine Transform warp_mat = getAffineTransform( srcTri, dstTri ); diff --git a/samples/cpp/tutorial_code/ImgTrans/HoughCircle_Demo.cpp b/samples/cpp/tutorial_code/ImgTrans/HoughCircle_Demo.cpp index ec17fdaae..71d37fb7a 100644 --- a/samples/cpp/tutorial_code/ImgTrans/HoughCircle_Demo.cpp +++ b/samples/cpp/tutorial_code/ImgTrans/HoughCircle_Demo.cpp @@ -14,7 +14,7 @@ using namespace cv; /** * @function main */ -int main(int argc, char** argv) +int main(int, char** argv) { Mat src, src_gray; diff --git a/samples/cpp/tutorial_code/ImgTrans/HoughLines_Demo.cpp b/samples/cpp/tutorial_code/ImgTrans/HoughLines_Demo.cpp index 56a4a94b5..561948a58 100644 --- a/samples/cpp/tutorial_code/ImgTrans/HoughLines_Demo.cpp +++ b/samples/cpp/tutorial_code/ImgTrans/HoughLines_Demo.cpp @@ -21,8 +21,8 @@ Mat standard_hough, probabilistic_hough; int min_threshold = 50; int max_trackbar = 150; -char* standard_name = "Standard Hough Lines Demo"; -char* probabilistic_name = "Probabilistic Hough Lines Demo"; +const char* standard_name = "Standard Hough Lines Demo"; +const char* probabilistic_name = "Probabilistic Hough Lines Demo"; int s_trackbar = max_trackbar; int p_trackbar = max_trackbar; @@ -35,7 +35,7 @@ void Probabilistic_Hough( int, void* ); /** * @function main */ -int main( int argc, char** argv ) +int main( int, char** argv ) { /// Read the image src = imread( argv[1], 1 ); @@ -91,7 +91,7 @@ void Standard_Hough( int, void* ) HoughLines( edges, s_lines, 1, CV_PI/180, min_threshold + s_trackbar, 0, 0 ); /// Show the result - for( int i = 0; i < s_lines.size(); i++ ) + for( size_t i = 0; i < s_lines.size(); i++ ) { float r = s_lines[i][0], t = s_lines[i][1]; double cos_t = cos(t), sin_t = sin(t); diff --git a/samples/cpp/tutorial_code/ImgTrans/Laplace_Demo.cpp b/samples/cpp/tutorial_code/ImgTrans/Laplace_Demo.cpp index 5f996fff3..279dc6dcb 100644 --- a/samples/cpp/tutorial_code/ImgTrans/Laplace_Demo.cpp +++ b/samples/cpp/tutorial_code/ImgTrans/Laplace_Demo.cpp @@ -14,7 +14,7 @@ using namespace cv; /** * @function main */ -int main( int argc, char** argv ) +int main( int, char** argv ) { Mat src, src_gray, dst; @@ -22,9 +22,7 @@ int main( int argc, char** argv ) int scale = 1; int delta = 0; int ddepth = CV_16S; - char* window_name = "Laplace Demo"; - - int c; + const char* window_name = "Laplace Demo"; /// Load an image src = imread( argv[1] ); diff --git a/samples/cpp/tutorial_code/ImgTrans/Remap_Demo.cpp b/samples/cpp/tutorial_code/ImgTrans/Remap_Demo.cpp index de58e984b..40e5118a6 100644 --- a/samples/cpp/tutorial_code/ImgTrans/Remap_Demo.cpp +++ b/samples/cpp/tutorial_code/ImgTrans/Remap_Demo.cpp @@ -14,7 +14,7 @@ using namespace cv; /// Global variables Mat src, dst; Mat map_x, map_y; -char* remap_window = "Remap demo"; +const char* remap_window = "Remap demo"; int ind = 0; /// Function Headers @@ -23,7 +23,7 @@ void update_map( void ); /** * @function main */ -int main( int argc, char** argv ) +int main( int, char** argv ) { /// Load the image src = imread( argv[1], 1 ); @@ -37,7 +37,7 @@ int main( int argc, char** argv ) namedWindow( remap_window, CV_WINDOW_AUTOSIZE ); /// Loop - while( true ) + for(;;) { /// Each 1 sec. Press ESC to exit the program int c = waitKey( 1000 ); @@ -71,8 +71,8 @@ void update_map( void ) case 0: if( i > src.cols*0.25 && i < src.cols*0.75 && j > src.rows*0.25 && j < src.rows*0.75 ) { - map_x.at(j,i) = 2*( i - src.cols*0.25 ) + 0.5 ; - map_y.at(j,i) = 2*( j - src.rows*0.25 ) + 0.5 ; + map_x.at(j,i) = 2*( i - src.cols*0.25f ) + 0.5f ; + map_y.at(j,i) = 2*( j - src.rows*0.25f ) + 0.5f ; } else { map_x.at(j,i) = 0 ; @@ -80,16 +80,16 @@ void update_map( void ) } break; case 1: - map_x.at(j,i) = i ; - map_y.at(j,i) = src.rows - j ; + map_x.at(j,i) = (float)i ; + map_y.at(j,i) = (float)(src.rows - j) ; break; case 2: - map_x.at(j,i) = src.cols - i ; - map_y.at(j,i) = j ; + map_x.at(j,i) = (float)(src.cols - i) ; + map_y.at(j,i) = (float)j ; break; case 3: - map_x.at(j,i) = src.cols - i ; - map_y.at(j,i) = src.rows - j ; + map_x.at(j,i) = (float)(src.cols - i) ; + map_y.at(j,i) = (float)(src.rows - j) ; break; } // end of switch } diff --git a/samples/cpp/tutorial_code/ImgTrans/Sobel_Demo.cpp b/samples/cpp/tutorial_code/ImgTrans/Sobel_Demo.cpp index 0af569fa7..0ac9eb1a3 100644 --- a/samples/cpp/tutorial_code/ImgTrans/Sobel_Demo.cpp +++ b/samples/cpp/tutorial_code/ImgTrans/Sobel_Demo.cpp @@ -14,18 +14,16 @@ using namespace cv; /** * @function main */ -int main( int argc, char** argv ) +int main( int, char** argv ) { Mat src, src_gray; Mat grad; - char* window_name = "Sobel Demo - Simple Edge Detector"; + const char* window_name = "Sobel Demo - Simple Edge Detector"; int scale = 1; int delta = 0; int ddepth = CV_16S; - int c; - /// Load an image src = imread( argv[1] ); diff --git a/samples/cpp/tutorial_code/ImgTrans/copyMakeBorder_demo.cpp b/samples/cpp/tutorial_code/ImgTrans/copyMakeBorder_demo.cpp index b90a17577..4b2783e31 100644 --- a/samples/cpp/tutorial_code/ImgTrans/copyMakeBorder_demo.cpp +++ b/samples/cpp/tutorial_code/ImgTrans/copyMakeBorder_demo.cpp @@ -16,13 +16,13 @@ Mat src, dst; int top, bottom, left, right; int borderType; Scalar value; -char* window_name = "copyMakeBorder Demo"; +const char* window_name = "copyMakeBorder Demo"; RNG rng(12345); /** * @function main */ -int main( int argc, char** argv ) +int main( int, char** argv ) { int c; @@ -31,8 +31,9 @@ int main( int argc, char** argv ) src = imread( argv[1] ); if( !src.data ) - { return -1; + { printf(" No data entered, please enter the path to an image file \n"); + return -1; } /// Brief how-to for this program @@ -52,7 +53,7 @@ int main( int argc, char** argv ) imshow( window_name, dst ); - while( true ) + for(;;) { c = waitKey(500); diff --git a/samples/cpp/tutorial_code/ImgTrans/filter2D_demo.cpp b/samples/cpp/tutorial_code/ImgTrans/filter2D_demo.cpp index 86158d913..7a8dc768c 100644 --- a/samples/cpp/tutorial_code/ImgTrans/filter2D_demo.cpp +++ b/samples/cpp/tutorial_code/ImgTrans/filter2D_demo.cpp @@ -14,7 +14,7 @@ using namespace cv; /** * @function main */ -int main ( int argc, char** argv ) +int main ( int, char** argv ) { /// Declare variables Mat src, dst; @@ -24,7 +24,7 @@ int main ( int argc, char** argv ) double delta; int ddepth; int kernel_size; - char* window_name = "filter2D Demo"; + const char* window_name = "filter2D Demo"; int c; @@ -44,7 +44,7 @@ int main ( int argc, char** argv ) /// Loop - Will filter the image with different kernel sizes each 0.5 seconds int ind = 0; - while( true ) + for(;;) { c = waitKey(500); /// Press 'ESC' to exit the program diff --git a/samples/cpp/tutorial_code/ShapeDescriptors/findContours_demo.cpp b/samples/cpp/tutorial_code/ShapeDescriptors/findContours_demo.cpp index 0eeb3b621..e301476ee 100644 --- a/samples/cpp/tutorial_code/ShapeDescriptors/findContours_demo.cpp +++ b/samples/cpp/tutorial_code/ShapeDescriptors/findContours_demo.cpp @@ -24,7 +24,7 @@ void thresh_callback(int, void* ); /** * @function main */ -int main( int argc, char** argv ) +int main( int, char** argv ) { /// Load source image and convert it to gray src = imread( argv[1], 1 ); @@ -34,7 +34,7 @@ int main( int argc, char** argv ) blur( src_gray, src_gray, Size(3,3) ); /// Create Window - char* source_window = "Source"; + const char* source_window = "Source"; namedWindow( source_window, CV_WINDOW_AUTOSIZE ); imshow( source_window, src ); @@ -61,10 +61,10 @@ void thresh_callback(int, void* ) /// Draw contours Mat drawing = Mat::zeros( canny_output.size(), CV_8UC3 ); - for( int i = 0; i< contours.size(); i++ ) + for( size_t i = 0; i< contours.size(); i++ ) { Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) ); - drawContours( drawing, contours, i, color, 2, 8, hierarchy, 0, Point() ); + drawContours( drawing, contours, (int)i, color, 2, 8, hierarchy, 0, Point() ); } /// Show in a window diff --git a/samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp b/samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp index d1de8ac31..b973cfd97 100644 --- a/samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp +++ b/samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo1.cpp @@ -24,7 +24,7 @@ void thresh_callback(int, void* ); /** * @function main */ -int main( int argc, char** argv ) +int main( int, char** argv ) { /// Load source image and convert it to gray src = imread( argv[1], 1 ); @@ -34,7 +34,7 @@ int main( int argc, char** argv ) blur( src_gray, src_gray, Size(3,3) ); /// Create Window - char* source_window = "Source"; + const char* source_window = "Source"; namedWindow( source_window, CV_WINDOW_AUTOSIZE ); imshow( source_window, src ); @@ -65,7 +65,7 @@ void thresh_callback(int, void* ) vectorcenter( contours.size() ); vectorradius( contours.size() ); - for( int i = 0; i < contours.size(); i++ ) + for( size_t i = 0; i < contours.size(); i++ ) { approxPolyDP( Mat(contours[i]), contours_poly[i], 3, true ); boundRect[i] = boundingRect( Mat(contours_poly[i]) ); minEnclosingCircle( contours_poly[i], center[i], radius[i] ); @@ -74,10 +74,10 @@ void thresh_callback(int, void* ) /// Draw polygonal contour + bonding rects + circles Mat drawing = Mat::zeros( threshold_output.size(), CV_8UC3 ); - for( int i = 0; i< contours.size(); i++ ) + for( size_t i = 0; i< contours.size(); i++ ) { Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) ); - drawContours( drawing, contours_poly, i, color, 1, 8, vector(), 0, Point() ); + drawContours( drawing, contours_poly, (int)i, color, 1, 8, vector(), 0, Point() ); rectangle( drawing, boundRect[i].tl(), boundRect[i].br(), color, 2, 8, 0 ); circle( drawing, center[i], (int)radius[i], color, 2, 8, 0 ); } diff --git a/samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo2.cpp b/samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo2.cpp index 657b46441..70d8663c9 100644 --- a/samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo2.cpp +++ b/samples/cpp/tutorial_code/ShapeDescriptors/generalContours_demo2.cpp @@ -24,7 +24,7 @@ void thresh_callback(int, void* ); /** * @function main */ -int main( int argc, char** argv ) +int main( int, char** argv ) { /// Load source image and convert it to gray src = imread( argv[1], 1 ); @@ -34,7 +34,7 @@ int main( int argc, char** argv ) blur( src_gray, src_gray, Size(3,3) ); /// Create Window - char* source_window = "Source"; + const char* source_window = "Source"; namedWindow( source_window, CV_WINDOW_AUTOSIZE ); imshow( source_window, src ); @@ -63,7 +63,7 @@ void thresh_callback(int, void* ) vector minRect( contours.size() ); vector minEllipse( contours.size() ); - for( int i = 0; i < contours.size(); i++ ) + for( size_t i = 0; i < contours.size(); i++ ) { minRect[i] = minAreaRect( Mat(contours[i]) ); if( contours[i].size() > 5 ) { minEllipse[i] = fitEllipse( Mat(contours[i]) ); } @@ -71,11 +71,11 @@ void thresh_callback(int, void* ) /// Draw contours + rotated rects + ellipses Mat drawing = Mat::zeros( threshold_output.size(), CV_8UC3 ); - for( int i = 0; i< contours.size(); i++ ) + for( size_t i = 0; i< contours.size(); i++ ) { Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) ); // contour - drawContours( drawing, contours, i, color, 1, 8, vector(), 0, Point() ); + drawContours( drawing, contours, (int)i, color, 1, 8, vector(), 0, Point() ); // ellipse ellipse( drawing, minEllipse[i], color, 2, 8 ); // rotated rectangle diff --git a/samples/cpp/tutorial_code/ShapeDescriptors/hull_demo.cpp b/samples/cpp/tutorial_code/ShapeDescriptors/hull_demo.cpp index c6e138302..8fe5d5b07 100644 --- a/samples/cpp/tutorial_code/ShapeDescriptors/hull_demo.cpp +++ b/samples/cpp/tutorial_code/ShapeDescriptors/hull_demo.cpp @@ -24,7 +24,7 @@ void thresh_callback(int, void* ); /** * @function main */ -int main( int argc, char** argv ) +int main( int, char** argv ) { /// Load source image and convert it to gray src = imread( argv[1], 1 ); @@ -34,7 +34,7 @@ int main( int argc, char** argv ) blur( src_gray, src_gray, Size(3,3) ); /// Create Window - char* source_window = "Source"; + const char* source_window = "Source"; namedWindow( source_window, CV_WINDOW_AUTOSIZE ); imshow( source_window, src ); @@ -63,16 +63,16 @@ void thresh_callback(int, void* ) /// Find the convex hull object for each contour vector >hull( contours.size() ); - for( int i = 0; i < contours.size(); i++ ) + for( size_t i = 0; i < contours.size(); i++ ) { convexHull( Mat(contours[i]), hull[i], false ); } /// Draw contours + hull results Mat drawing = Mat::zeros( threshold_output.size(), CV_8UC3 ); - for( int i = 0; i< contours.size(); i++ ) + for( size_t i = 0; i< contours.size(); i++ ) { Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) ); - drawContours( drawing, contours, i, color, 1, 8, vector(), 0, Point() ); - drawContours( drawing, hull, i, color, 1, 8, vector(), 0, Point() ); + drawContours( drawing, contours, (int)i, color, 1, 8, vector(), 0, Point() ); + drawContours( drawing, hull, (int)i, color, 1, 8, vector(), 0, Point() ); } /// Show in a window diff --git a/samples/cpp/tutorial_code/ShapeDescriptors/moments_demo.cpp b/samples/cpp/tutorial_code/ShapeDescriptors/moments_demo.cpp index 363b7d3a4..efd3c63d9 100644 --- a/samples/cpp/tutorial_code/ShapeDescriptors/moments_demo.cpp +++ b/samples/cpp/tutorial_code/ShapeDescriptors/moments_demo.cpp @@ -24,7 +24,7 @@ void thresh_callback(int, void* ); /** * @function main */ -int main( int argc, char** argv ) +int main( int, char** argv ) { /// Load source image and convert it to gray src = imread( argv[1], 1 ); @@ -34,7 +34,7 @@ int main( int argc, char** argv ) blur( src_gray, src_gray, Size(3,3) ); /// Create Window - char* source_window = "Source"; + const char* source_window = "Source"; namedWindow( source_window, CV_WINDOW_AUTOSIZE ); imshow( source_window, src ); @@ -61,20 +61,20 @@ void thresh_callback(int, void* ) /// Get the moments vector mu(contours.size() ); - for( int i = 0; i < contours.size(); i++ ) + for( size_t i = 0; i < contours.size(); i++ ) { mu[i] = moments( contours[i], false ); } /// Get the mass centers: vector mc( contours.size() ); - for( int i = 0; i < contours.size(); i++ ) - { mc[i] = Point2f( mu[i].m10/mu[i].m00 , mu[i].m01/mu[i].m00 ); } + for( size_t i = 0; i < contours.size(); i++ ) + { mc[i] = Point2f( static_cast(mu[i].m10/mu[i].m00) , static_cast(mu[i].m01/mu[i].m00) ); } /// Draw contours Mat drawing = Mat::zeros( canny_output.size(), CV_8UC3 ); - for( int i = 0; i< contours.size(); i++ ) + for( size_t i = 0; i< contours.size(); i++ ) { Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) ); - drawContours( drawing, contours, i, color, 2, 8, hierarchy, 0, Point() ); + drawContours( drawing, contours, (int)i, color, 2, 8, hierarchy, 0, Point() ); circle( drawing, mc[i], 4, color, -1, 8, 0 ); } @@ -84,11 +84,11 @@ void thresh_callback(int, void* ) /// Calculate the area with the moments 00 and compare with the result of the OpenCV function printf("\t Info: Area and Contour Length \n"); - for( int i = 0; i< contours.size(); i++ ) + for( size_t i = 0; i< contours.size(); i++ ) { - printf(" * Contour[%d] - Area (M_00) = %.2f - Area OpenCV: %.2f - Length: %.2f \n", i, mu[i].m00, contourArea(contours[i]), arcLength( contours[i], true ) ); + printf(" * Contour[%d] - Area (M_00) = %.2f - Area OpenCV: %.2f - Length: %.2f \n", (int)i, mu[i].m00, contourArea(contours[i]), arcLength( contours[i], true ) ); Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) ); - drawContours( drawing, contours, i, color, 2, 8, hierarchy, 0, Point() ); + drawContours( drawing, contours, (int)i, color, 2, 8, hierarchy, 0, Point() ); circle( drawing, mc[i], 4, color, -1, 8, 0 ); } } diff --git a/samples/cpp/tutorial_code/ShapeDescriptors/pointPolygonTest_demo.cpp b/samples/cpp/tutorial_code/ShapeDescriptors/pointPolygonTest_demo.cpp index e989f2987..c15bc22c6 100644 --- a/samples/cpp/tutorial_code/ShapeDescriptors/pointPolygonTest_demo.cpp +++ b/samples/cpp/tutorial_code/ShapeDescriptors/pointPolygonTest_demo.cpp @@ -16,7 +16,7 @@ using namespace std; /** * @function main */ -int main( int argc, char** argv ) +int main( void ) { /// Create an image const int r = 100; @@ -25,12 +25,12 @@ int main( int argc, char** argv ) /// Create a sequence of points to make a contour: vector vert(6); - vert[0] = Point( 1.5*r, 1.34*r ); + vert[0] = Point( 3*r/2, static_cast(1.34*r) ); vert[1] = Point( 1*r, 2*r ); - vert[2] = Point( 1.5*r, 2.866*r ); - vert[3] = Point( 2.5*r, 2.866*r ); + vert[2] = Point( 3*r/2, static_cast(2.866*r) ); + vert[3] = Point( 5*r/2, static_cast(2.866*r) ); vert[4] = Point( 3*r, 2*r ); - vert[5] = Point( 2.5*r, 1.34*r ); + vert[5] = Point( 5*r/2, static_cast(1.34*r) ); /// Draw it in src for( int j = 0; j < 6; j++ ) @@ -47,7 +47,7 @@ int main( int argc, char** argv ) for( int j = 0; j < src.rows; j++ ) { for( int i = 0; i < src.cols; i++ ) - { raw_dist.at(j,i) = pointPolygonTest( contours[0], Point2f(i,j), true ); } + { raw_dist.at(j,i) = (float)pointPolygonTest( contours[0], Point2f((float)i,(float)j), true ); } } double minVal; double maxVal; @@ -61,16 +61,16 @@ int main( int argc, char** argv ) { for( int i = 0; i < src.cols; i++ ) { if( raw_dist.at(j,i) < 0 ) - { drawing.at(j,i)[0] = 255 - (int) abs(raw_dist.at(j,i))*255/minVal; } + { drawing.at(j,i)[0] = (uchar)(255 - abs(raw_dist.at(j,i))*255/minVal); } else if( raw_dist.at(j,i) > 0 ) - { drawing.at(j,i)[2] = 255 - (int) raw_dist.at(j,i)*255/maxVal; } + { drawing.at(j,i)[2] = (uchar)(255 - raw_dist.at(j,i)*255/maxVal); } else { drawing.at(j,i)[0] = 255; drawing.at(j,i)[1] = 255; drawing.at(j,i)[2] = 255; } } } /// Create Window and show your results - char* source_window = "Source"; + const char* source_window = "Source"; namedWindow( source_window, CV_WINDOW_AUTOSIZE ); imshow( source_window, src ); namedWindow( "Distance", CV_WINDOW_AUTOSIZE ); diff --git a/samples/cpp/tutorial_code/TrackingMotion/cornerDetector_Demo.cpp b/samples/cpp/tutorial_code/TrackingMotion/cornerDetector_Demo.cpp index d3a62c6e1..b4789e334 100644 --- a/samples/cpp/tutorial_code/TrackingMotion/cornerDetector_Demo.cpp +++ b/samples/cpp/tutorial_code/TrackingMotion/cornerDetector_Demo.cpp @@ -26,8 +26,8 @@ double myShiTomasi_minVal; double myShiTomasi_maxVal; RNG rng(12345); -char* myHarris_window = "My Harris corner detector"; -char* myShiTomasi_window = "My Shi Tomasi corner detector"; +const char* myHarris_window = "My Harris corner detector"; +const char* myShiTomasi_window = "My Shi Tomasi corner detector"; /// Function headers void myShiTomasi_function( int, void* ); @@ -36,7 +36,7 @@ void myHarris_function( int, void* ); /** * @function main */ -int main( int argc, char** argv ) +int main( int, char** argv ) { /// Load source image and convert it to gray src = imread( argv[1], 1 ); @@ -57,7 +57,7 @@ int main( int argc, char** argv ) { float lambda_1 = myHarris_dst.at(j, i)[0]; float lambda_2 = myHarris_dst.at(j, i)[1]; - Mc.at(j,i) = lambda_1*lambda_2 - 0.04*pow( ( lambda_1 + lambda_2 ), 2 ); + Mc.at(j,i) = lambda_1*lambda_2 - 0.04f*pow( ( lambda_1 + lambda_2 ), 2 ); } } diff --git a/samples/cpp/tutorial_code/TrackingMotion/cornerHarris_Demo.cpp b/samples/cpp/tutorial_code/TrackingMotion/cornerHarris_Demo.cpp index 3a4b48aba..667ad7e32 100644 --- a/samples/cpp/tutorial_code/TrackingMotion/cornerHarris_Demo.cpp +++ b/samples/cpp/tutorial_code/TrackingMotion/cornerHarris_Demo.cpp @@ -18,8 +18,8 @@ Mat src, src_gray; int thresh = 200; int max_thresh = 255; -char* source_window = "Source image"; -char* corners_window = "Corners detected"; +const char* source_window = "Source image"; +const char* corners_window = "Corners detected"; /// Function header void cornerHarris_demo( int, void* ); @@ -27,7 +27,7 @@ void cornerHarris_demo( int, void* ); /** * @function main */ -int main( int argc, char** argv ) +int main( int, char** argv ) { /// Load source image and convert it to gray src = imread( argv[1], 1 ); diff --git a/samples/cpp/tutorial_code/TrackingMotion/cornerSubPix_Demo.cpp b/samples/cpp/tutorial_code/TrackingMotion/cornerSubPix_Demo.cpp index fd6fcd9d9..3b538119e 100644 --- a/samples/cpp/tutorial_code/TrackingMotion/cornerSubPix_Demo.cpp +++ b/samples/cpp/tutorial_code/TrackingMotion/cornerSubPix_Demo.cpp @@ -20,7 +20,7 @@ int maxCorners = 10; int maxTrackbar = 25; RNG rng(12345); -char* source_window = "Image"; +const char* source_window = "Image"; /// Function header void goodFeaturesToTrack_Demo( int, void* ); @@ -28,7 +28,7 @@ void goodFeaturesToTrack_Demo( int, void* ); /** * @function main */ -int main( int argc, char** argv ) +int main( int, char** argv ) { /// Load source image and convert it to gray src = imread( argv[1], 1 ); @@ -83,7 +83,7 @@ void goodFeaturesToTrack_Demo( int, void* ) /// Draw corners detected cout<<"** Number of corners detected: "< #include #include +#include #include #include @@ -10,7 +11,7 @@ using namespace cv; using namespace std; -void help() +static void help() { cout << "This is a camera calibration sample." << endl << "Usage: calibration configurationFile" << endl @@ -99,7 +100,7 @@ public: if (readStringList(input, imageList)) { inputType = IMAGE_LIST; - nrFrames = (nrFrames < imageList.size()) ? nrFrames : imageList.size(); + nrFrames = (nrFrames < (int)imageList.size()) ? nrFrames : (int)imageList.size(); } else inputType = VIDEO_FILE; @@ -196,11 +197,7 @@ private: }; -void write(FileStorage& fs, const std::string&, const Settings& x) -{ - x.write(fs); -} -void read(const FileNode& node, Settings& x, const Settings& default_value = Settings()) +static void read(const FileNode& node, Settings& x, const Settings& default_value = Settings()) { if(node.empty()) x = default_value; @@ -282,6 +279,9 @@ int main(int argc, char* argv[]) case Settings::ASYMMETRIC_CIRCLES_GRID: found = findCirclesGrid( view, s.boardSize, pointBuf, CALIB_CB_ASYMMETRIC_GRID ); break; + default: + found = false; + break; } if ( found) // If done with success, @@ -336,7 +336,7 @@ int main(int argc, char* argv[]) //------------------------------ Show image and check for input commands ------------------- imshow("Image View", view); - char key = waitKey(s.inputCapture.isOpened() ? 50 : s.delay); + char key = (char)waitKey(s.inputCapture.isOpened() ? 50 : s.delay); if( key == ESC_KEY ) break; @@ -366,7 +366,7 @@ int main(int argc, char* argv[]) continue; remap(view, rview, map1, map2, INTER_LINEAR); imshow("Image View", rview); - char c = waitKey(); + char c = (char)waitKey(); if( c == ESC_KEY || c == 'q' || c == 'Q' ) break; } @@ -376,11 +376,11 @@ int main(int argc, char* argv[]) return 0; } -double computeReprojectionErrors( const vector >& objectPoints, - const vector >& imagePoints, - const vector& rvecs, const vector& tvecs, - const Mat& cameraMatrix , const Mat& distCoeffs, - vector& perViewErrors) +static double computeReprojectionErrors( const vector >& objectPoints, + const vector >& imagePoints, + const vector& rvecs, const vector& tvecs, + const Mat& cameraMatrix , const Mat& distCoeffs, + vector& perViewErrors) { vector imagePoints2; int i, totalPoints = 0; @@ -402,8 +402,8 @@ double computeReprojectionErrors( const vector >& objectPoints, return std::sqrt(totalErr/totalPoints); } -void calcBoardCornerPositions(Size boardSize, float squareSize, vector& corners, - Settings::Pattern patternType /*= Settings::CHESSBOARD*/) +static void calcBoardCornerPositions(Size boardSize, float squareSize, vector& corners, + Settings::Pattern patternType /*= Settings::CHESSBOARD*/) { corners.clear(); @@ -421,12 +421,14 @@ void calcBoardCornerPositions(Size boardSize, float squareSize, vector& for( int j = 0; j < boardSize.width; j++ ) corners.push_back(Point3f(float((2*j + i % 2)*squareSize), float(i*squareSize), 0)); break; + default: + break; } } -bool runCalibration( Settings& s, Size& imageSize, Mat& cameraMatrix, Mat& distCoeffs, - vector > imagePoints, vector& rvecs, vector& tvecs, - vector& reprojErrs, double& totalAvgErr) +static bool runCalibration( Settings& s, Size& imageSize, Mat& cameraMatrix, Mat& distCoeffs, + vector > imagePoints, vector& rvecs, vector& tvecs, + vector& reprojErrs, double& totalAvgErr) { cameraMatrix = Mat::eye(3, 3, CV_64F); @@ -455,16 +457,16 @@ bool runCalibration( Settings& s, Size& imageSize, Mat& cameraMatrix, Mat& distC } // Print camera parameters to the output file -void saveCameraParams( Settings& s, Size& imageSize, Mat& cameraMatrix, Mat& distCoeffs, - const vector& rvecs, const vector& tvecs, - const vector& reprojErrs, const vector >& imagePoints, - double totalAvgErr ) +static void saveCameraParams( Settings& s, Size& imageSize, Mat& cameraMatrix, Mat& distCoeffs, + const vector& rvecs, const vector& tvecs, + const vector& reprojErrs, const vector >& imagePoints, + double totalAvgErr ) { FileStorage fs( s.outputFileName, FileStorage::WRITE ); - time_t t; - time( &t ); - struct tm *t2 = localtime( &t ); + time_t tm; + time( &tm ); + struct tm *t2 = localtime( &tm ); char buf[1024]; strftime( buf, sizeof(buf)-1, "%c", t2 ); @@ -522,7 +524,7 @@ void saveCameraParams( Settings& s, Size& imageSize, Mat& cameraMatrix, Mat& dis if( !imagePoints.empty() ) { - Mat imagePtMat((int)imagePoints.size(), imagePoints[0].size(), CV_32FC2); + Mat imagePtMat((int)imagePoints.size(), (int)imagePoints[0].size(), CV_32FC2); for( int i = 0; i < (int)imagePoints.size(); i++ ) { Mat r = imagePtMat.row(i).reshape(2, imagePtMat.cols); diff --git a/samples/cpp/tutorial_code/calib3d/stereoBM/SBM_Sample.cpp b/samples/cpp/tutorial_code/calib3d/stereoBM/SBM_Sample.cpp index c3ae67637..13d5aa870 100644 --- a/samples/cpp/tutorial_code/calib3d/stereoBM/SBM_Sample.cpp +++ b/samples/cpp/tutorial_code/calib3d/stereoBM/SBM_Sample.cpp @@ -12,7 +12,7 @@ using namespace cv; -char *windowDisparity = "Disparity"; +const char *windowDisparity = "Disparity"; void readme(); diff --git a/samples/cpp/tutorial_code/contrib/retina_tutorial.cpp b/samples/cpp/tutorial_code/contrib/retina_tutorial.cpp index 3fc9a093a..8ebcb7cba 100644 --- a/samples/cpp/tutorial_code/contrib/retina_tutorial.cpp +++ b/samples/cpp/tutorial_code/contrib/retina_tutorial.cpp @@ -118,7 +118,7 @@ int main(int argc, char* argv[]) { cv::Mat retinaOutput_magno; // processing loop with no stop condition - while(true) + for(;;) { // if using video stream, then, grabbing a new frame, else, input remains the same if (videoCapture.isOpened()) diff --git a/samples/cpp/tutorial_code/core/Matrix/Drawing_1.cpp b/samples/cpp/tutorial_code/core/Matrix/Drawing_1.cpp index 2f5da6ebf..3e2437fef 100644 --- a/samples/cpp/tutorial_code/core/Matrix/Drawing_1.cpp +++ b/samples/cpp/tutorial_code/core/Matrix/Drawing_1.cpp @@ -20,7 +20,7 @@ void MyLine( Mat img, Point start, Point end ); * @function main * @brief Main function */ -int main( int argc, char **argv ){ +int main( void ){ /// Windows names char atom_window[] = "Drawing 1: Atom"; @@ -40,7 +40,7 @@ int main( int argc, char **argv ){ MyEllipse( atom_image, -45 ); /// 1.b. Creating circles - MyFilledCircle( atom_image, Point( w/2.0, w/2.0) ); + MyFilledCircle( atom_image, Point( w/2, w/2) ); /// 2. Draw a rook /// ------------------ @@ -50,7 +50,7 @@ int main( int argc, char **argv ){ /// 2.b. Creating rectangles rectangle( rook_image, - Point( 0, 7*w/8.0 ), + Point( 0, 7*w/8 ), Point( w, w), Scalar( 0, 255, 255 ), -1, @@ -84,8 +84,8 @@ void MyEllipse( Mat img, double angle ) int lineType = 8; ellipse( img, - Point( w/2.0, w/2.0 ), - Size( w/4.0, w/16.0 ), + Point( w/2, w/2 ), + Size( w/4, w/16 ), angle, 0, 360, @@ -105,7 +105,7 @@ void MyFilledCircle( Mat img, Point center ) circle( img, center, - w/32.0, + w/32, Scalar( 0, 0, 255 ), thickness, lineType ); @@ -121,26 +121,26 @@ void MyPolygon( Mat img ) /** Create some points */ Point rook_points[1][20]; - rook_points[0][0] = Point( w/4.0, 7*w/8.0 ); - rook_points[0][1] = Point( 3*w/4.0, 7*w/8.0 ); - rook_points[0][2] = Point( 3*w/4.0, 13*w/16.0 ); - rook_points[0][3] = Point( 11*w/16.0, 13*w/16.0 ); - rook_points[0][4] = Point( 19*w/32.0, 3*w/8.0 ); - rook_points[0][5] = Point( 3*w/4.0, 3*w/8.0 ); - rook_points[0][6] = Point( 3*w/4.0, w/8.0 ); - rook_points[0][7] = Point( 26*w/40.0, w/8.0 ); - rook_points[0][8] = Point( 26*w/40.0, w/4.0 ); - rook_points[0][9] = Point( 22*w/40.0, w/4.0 ); - rook_points[0][10] = Point( 22*w/40.0, w/8.0 ); - rook_points[0][11] = Point( 18*w/40.0, w/8.0 ); - rook_points[0][12] = Point( 18*w/40.0, w/4.0 ); - rook_points[0][13] = Point( 14*w/40.0, w/4.0 ); - rook_points[0][14] = Point( 14*w/40.0, w/8.0 ); - rook_points[0][15] = Point( w/4.0, w/8.0 ); - rook_points[0][16] = Point( w/4.0, 3*w/8.0 ); - rook_points[0][17] = Point( 13*w/32.0, 3*w/8.0 ); - rook_points[0][18] = Point( 5*w/16.0, 13*w/16.0 ); - rook_points[0][19] = Point( w/4.0, 13*w/16.0) ; + rook_points[0][0] = Point( w/4, 7*w/8 ); + rook_points[0][1] = Point( 3*w/4, 7*w/8 ); + rook_points[0][2] = Point( 3*w/4, 13*w/16 ); + rook_points[0][3] = Point( 11*w/16, 13*w/16 ); + rook_points[0][4] = Point( 19*w/32, 3*w/8 ); + rook_points[0][5] = Point( 3*w/4, 3*w/8 ); + rook_points[0][6] = Point( 3*w/4, w/8 ); + rook_points[0][7] = Point( 26*w/40, w/8 ); + rook_points[0][8] = Point( 26*w/40, w/4 ); + rook_points[0][9] = Point( 22*w/40, w/4 ); + rook_points[0][10] = Point( 22*w/40, w/8 ); + rook_points[0][11] = Point( 18*w/40, w/8 ); + rook_points[0][12] = Point( 18*w/40, w/4 ); + rook_points[0][13] = Point( 14*w/40, w/4 ); + rook_points[0][14] = Point( 14*w/40, w/8 ); + rook_points[0][15] = Point( w/4, w/8 ); + rook_points[0][16] = Point( w/4, 3*w/8 ); + rook_points[0][17] = Point( 13*w/32, 3*w/8 ); + rook_points[0][18] = Point( 5*w/16, 13*w/16 ); + rook_points[0][19] = Point( w/4, 13*w/16 ); const Point* ppt[1] = { rook_points[0] }; int npt[] = { 20 }; diff --git a/samples/cpp/tutorial_code/core/Matrix/Drawing_2.cpp b/samples/cpp/tutorial_code/core/Matrix/Drawing_2.cpp index 56058e2ec..c84eccb69 100644 --- a/samples/cpp/tutorial_code/core/Matrix/Drawing_2.cpp +++ b/samples/cpp/tutorial_code/core/Matrix/Drawing_2.cpp @@ -36,7 +36,7 @@ int Displaying_Big_End( Mat image, char* window_name, RNG rng ); /** * @function main */ -int main( int argc, char** argv ) +int main( void ) { int c; @@ -106,7 +106,6 @@ static Scalar randomColor( RNG& rng ) */ int Drawing_Random_Lines( Mat image, char* window_name, RNG rng ) { - int lineType = 8; Point pt1, pt2; for( int i = 0; i < NUMBER; i++ ) @@ -303,7 +302,7 @@ int Displaying_Random_Text( Mat image, char* window_name, RNG rng ) /** * @function Displaying_Big_End */ -int Displaying_Big_End( Mat image, char* window_name, RNG rng ) +int Displaying_Big_End( Mat image, char* window_name, RNG ) { Size textsize = getTextSize("OpenCV forever!", CV_FONT_HERSHEY_COMPLEX, 3, 5, 0); Point org((window_width - textsize.width)/2, (window_height - textsize.height)/2); diff --git a/samples/cpp/tutorial_code/core/discrete_fourier_transform/discrete_fourier_transform.cpp b/samples/cpp/tutorial_code/core/discrete_fourier_transform/discrete_fourier_transform.cpp index f15f1bd94..ba54188ae 100644 --- a/samples/cpp/tutorial_code/core/discrete_fourier_transform/discrete_fourier_transform.cpp +++ b/samples/cpp/tutorial_code/core/discrete_fourier_transform/discrete_fourier_transform.cpp @@ -7,7 +7,7 @@ using namespace cv; using namespace std; -void help(char* progName) +static void help(char* progName) { cout << endl << "This program demonstrated the use of the discrete Fourier transform (DFT). " << endl diff --git a/samples/cpp/tutorial_code/core/file_input_output/file_input_output.cpp b/samples/cpp/tutorial_code/core/file_input_output/file_input_output.cpp index 614ff50ca..9c527a8aa 100644 --- a/samples/cpp/tutorial_code/core/file_input_output/file_input_output.cpp +++ b/samples/cpp/tutorial_code/core/file_input_output/file_input_output.cpp @@ -5,7 +5,7 @@ using namespace cv; using namespace std; -void help(char** av) +static void help(char** av) { cout << endl << av[0] << " shows the usage of the OpenCV serialization functionality." << endl @@ -42,11 +42,11 @@ public: // Data Members }; //These write and read functions must be defined for the serialization in FileStorage to work -void write(FileStorage& fs, const std::string&, const MyData& x) +static void write(FileStorage& fs, const std::string&, const MyData& x) { x.write(fs); } -void read(const FileNode& node, MyData& x, const MyData& default_value = MyData()){ +static void read(const FileNode& node, MyData& x, const MyData& default_value = MyData()){ if(node.empty()) x = default_value; else @@ -54,7 +54,7 @@ void read(const FileNode& node, MyData& x, const MyData& default_value = MyData( } // This function will print our custom class to the console -ostream& operator<<(ostream& out, const MyData& m) +static ostream& operator<<(ostream& out, const MyData& m) { out << "{ id = " << m.id << ", "; out << "X = " << m.X << ", "; diff --git a/samples/cpp/tutorial_code/core/how_to_scan_images/how_to_scan_images.cpp b/samples/cpp/tutorial_code/core/how_to_scan_images/how_to_scan_images.cpp index c878f55e5..defc23fd7 100644 --- a/samples/cpp/tutorial_code/core/how_to_scan_images/how_to_scan_images.cpp +++ b/samples/cpp/tutorial_code/core/how_to_scan_images/how_to_scan_images.cpp @@ -6,7 +6,7 @@ using namespace std; using namespace cv; -void help() +static void help() { cout << "\n--------------------------------------------------------------------------" << endl @@ -57,7 +57,7 @@ int main( int argc, char* argv[]) uchar table[256]; for (int i = 0; i < 256; ++i) - table[i] = divideWith* (i/divideWith); + table[i] = (uchar)(divideWith * (i/divideWith)); const int times = 100; double t; diff --git a/samples/cpp/tutorial_code/core/interoperability_with_OpenCV_1/interoperability_with_OpenCV_1.cpp b/samples/cpp/tutorial_code/core/interoperability_with_OpenCV_1/interoperability_with_OpenCV_1.cpp index 85394667b..aeeaf2110 100644 --- a/samples/cpp/tutorial_code/core/interoperability_with_OpenCV_1/interoperability_with_OpenCV_1.cpp +++ b/samples/cpp/tutorial_code/core/interoperability_with_OpenCV_1/interoperability_with_OpenCV_1.cpp @@ -8,7 +8,7 @@ using namespace cv; // The new C++ interface API is inside this namespace. Import it. using namespace std; -void help( char* progName) +static void help( char* progName) { cout << endl << progName << " shows how to use cv::Mat and IplImages together (converting back and forth)." << endl diff --git a/samples/cpp/tutorial_code/core/mat_mask_operations/mat_mask_operations.cpp b/samples/cpp/tutorial_code/core/mat_mask_operations/mat_mask_operations.cpp index d941a0d0a..94e0a29a6 100644 --- a/samples/cpp/tutorial_code/core/mat_mask_operations/mat_mask_operations.cpp +++ b/samples/cpp/tutorial_code/core/mat_mask_operations/mat_mask_operations.cpp @@ -6,7 +6,7 @@ using namespace std; using namespace cv; -void help(char* progName) +static void help(char* progName) { cout << endl << "This program shows how to filter images with mask: the write it yourself and the" diff --git a/samples/cpp/tutorial_code/core/mat_the_basic_image_container/mat_the_basic_image_container.cpp b/samples/cpp/tutorial_code/core/mat_the_basic_image_container/mat_the_basic_image_container.cpp index adcdb2078..4f26f050d 100644 --- a/samples/cpp/tutorial_code/core/mat_the_basic_image_container/mat_the_basic_image_container.cpp +++ b/samples/cpp/tutorial_code/core/mat_the_basic_image_container/mat_the_basic_image_container.cpp @@ -6,7 +6,7 @@ using namespace std; using namespace cv; -void help() +static void help() { cout << "\n--------------------------------------------------------------------------" << endl @@ -77,8 +77,8 @@ int main(int,char**) cout << "Vector of floats via Mat = " << Mat(v) << endl << endl; vector vPoints(20); - for (size_t E = 0; E < vPoints.size(); ++E) - vPoints[E] = Point2f((float)(E * 5), (float)(E % 7)); + for (size_t i = 0; i < vPoints.size(); ++i) + vPoints[i] = Point2f((float)(i * 5), (float)(i % 7)); cout << "A vector of 2D Points = " << vPoints << endl << endl; return 0; diff --git a/samples/cpp/tutorial_code/features2D/SURF_FlannMatcher.cpp b/samples/cpp/tutorial_code/features2D/SURF_FlannMatcher.cpp index d2e40ed45..f4cde9b2e 100644 --- a/samples/cpp/tutorial_code/features2D/SURF_FlannMatcher.cpp +++ b/samples/cpp/tutorial_code/features2D/SURF_FlannMatcher.cpp @@ -83,7 +83,7 @@ int main( int argc, char** argv ) //-- Show detected matches imshow( "Good Matches", img_matches ); - for( int i = 0; i < good_matches.size(); i++ ) + for( int i = 0; i < (int)good_matches.size(); i++ ) { printf( "-- Good Match [%d] Keypoint 1: %d -- Keypoint 2: %d \n", i, good_matches[i].queryIdx, good_matches[i].trainIdx ); } waitKey(0); diff --git a/samples/cpp/tutorial_code/features2D/SURF_Homography.cpp b/samples/cpp/tutorial_code/features2D/SURF_Homography.cpp index d6f997c9f..506e3b44f 100644 --- a/samples/cpp/tutorial_code/features2D/SURF_Homography.cpp +++ b/samples/cpp/tutorial_code/features2D/SURF_Homography.cpp @@ -10,7 +10,7 @@ #include "opencv2/features2d/features2d.hpp" #include "opencv2/highgui/highgui.hpp" #include "opencv2/calib3d/calib3d.hpp" -#include "opencv2/nonfree/features2d.cpp" +#include "opencv2/nonfree/features2d.hpp" using namespace cv; @@ -84,7 +84,7 @@ int main( int argc, char** argv ) std::vector obj; std::vector scene; - for( int i = 0; i < good_matches.size(); i++ ) + for( size_t i = 0; i < good_matches.size(); i++ ) { //-- Get the keypoints from the good matches obj.push_back( keypoints_object[ good_matches[i].queryIdx ].pt ); @@ -103,10 +103,11 @@ int main( int argc, char** argv ) //-- Draw lines between the corners (the mapped object in the scene - image_2 ) - line( img_matches, scene_corners[0] + Point2f( img_object.cols, 0), scene_corners[1] + Point2f( img_object.cols, 0), Scalar(0, 255, 0), 4 ); - line( img_matches, scene_corners[1] + Point2f( img_object.cols, 0), scene_corners[2] + Point2f( img_object.cols, 0), Scalar( 0, 255, 0), 4 ); - line( img_matches, scene_corners[2] + Point2f( img_object.cols, 0), scene_corners[3] + Point2f( img_object.cols, 0), Scalar( 0, 255, 0), 4 ); - line( img_matches, scene_corners[3] + Point2f( img_object.cols, 0), scene_corners[0] + Point2f( img_object.cols, 0), Scalar( 0, 255, 0), 4 ); + Point2f offset( (float)img_object.cols, 0); + line( img_matches, scene_corners[0] + offset, scene_corners[1] + offset, Scalar(0, 255, 0), 4 ); + line( img_matches, scene_corners[1] + offset, scene_corners[2] + offset, Scalar( 0, 255, 0), 4 ); + line( img_matches, scene_corners[2] + offset, scene_corners[3] + offset, Scalar( 0, 255, 0), 4 ); + line( img_matches, scene_corners[3] + offset, scene_corners[0] + offset, Scalar( 0, 255, 0), 4 ); //-- Show detected matches imshow( "Good Matches & Object detection", img_matches ); diff --git a/samples/cpp/tutorial_code/features2D/SURF_descriptor.cpp b/samples/cpp/tutorial_code/features2D/SURF_descriptor.cpp index 051d95ec5..527e5dd95 100644 --- a/samples/cpp/tutorial_code/features2D/SURF_descriptor.cpp +++ b/samples/cpp/tutorial_code/features2D/SURF_descriptor.cpp @@ -9,7 +9,7 @@ #include "opencv2/core/core.hpp" #include "opencv2/features2d/features2d.hpp" #include "opencv2/highgui/highgui.hpp" -#include "opencv2/nonfree/features2d.cpp" +#include "opencv2/nonfree/features2d.hpp" using namespace cv; @@ -49,7 +49,7 @@ int main( int argc, char** argv ) extractor.compute( img_2, keypoints_2, descriptors_2 ); //-- Step 3: Matching descriptor vectors with a brute force matcher - BruteForceMatcher< L2 > matcher; + BFMatcher matcher(NORM_L2); std::vector< DMatch > matches; matcher.match( descriptors_1, descriptors_2, matches ); diff --git a/samples/cpp/tutorial_code/features2D/SURF_detector.cpp b/samples/cpp/tutorial_code/features2D/SURF_detector.cpp index 63ca76eb2..2625f1df3 100644 --- a/samples/cpp/tutorial_code/features2D/SURF_detector.cpp +++ b/samples/cpp/tutorial_code/features2D/SURF_detector.cpp @@ -9,7 +9,7 @@ #include "opencv2/core/core.hpp" #include "opencv2/features2d/features2d.hpp" #include "opencv2/highgui/highgui.hpp" -#include "opencv2/nonfree/features2d.cpp" +#include "opencv2/nonfree/features2d.hpp" using namespace cv; diff --git a/samples/cpp/tutorial_code/gpu/gpu-basics-similarity/gpu-basics-similarity.cpp b/samples/cpp/tutorial_code/gpu/gpu-basics-similarity/gpu-basics-similarity.cpp index 810865f64..0bcb6fafe 100644 --- a/samples/cpp/tutorial_code/gpu/gpu-basics-similarity/gpu-basics-similarity.cpp +++ b/samples/cpp/tutorial_code/gpu/gpu-basics-similarity/gpu-basics-similarity.cpp @@ -42,7 +42,7 @@ struct BufferMSSIM // Optimized GPU versions }; Scalar getMSSIM_GPU_optimized( const Mat& i1, const Mat& i2, BufferMSSIM& b); -void help() +static void help() { cout << "\n--------------------------------------------------------------------------" << endl @@ -54,7 +54,7 @@ void help() << endl; } -int main(int argc, char *argv[]) +int main(int, char *argv[]) { help(); Mat I1 = imread(argv[1]); // Read the two images @@ -72,7 +72,7 @@ int main(int argc, char *argv[]) int TIMES; stringstream sstr(argv[3]); sstr >> TIMES; - double time, result; + double time, result = 0; //------------------------------- PSNR CPU ---------------------------------------------------- time = (double)getTickCount(); @@ -84,7 +84,7 @@ int main(int argc, char *argv[]) time /= TIMES; cout << "Time of PSNR CPU (averaged for " << TIMES << " runs): " << time << " milliseconds." - << " With result of: " << result << endl; + << " With result of: " << result << endl; //------------------------------- PSNR GPU ---------------------------------------------------- time = (double)getTickCount(); @@ -291,17 +291,17 @@ Scalar getMSSIM_GPU( const Mat& i1, const Mat& i2) { const float C1 = 6.5025f, C2 = 58.5225f; /***************************** INITS **********************************/ - gpu::GpuMat gI1, gI2, gs1, t1,t2; + gpu::GpuMat gI1, gI2, gs1, tmp1,tmp2; gI1.upload(i1); gI2.upload(i2); - gI1.convertTo(t1, CV_MAKE_TYPE(CV_32F, gI1.channels())); - gI2.convertTo(t2, CV_MAKE_TYPE(CV_32F, gI2.channels())); + gI1.convertTo(tmp1, CV_MAKE_TYPE(CV_32F, gI1.channels())); + gI2.convertTo(tmp2, CV_MAKE_TYPE(CV_32F, gI2.channels())); vector vI1, vI2; - gpu::split(t1, vI1); - gpu::split(t2, vI2); + gpu::split(tmp1, vI1); + gpu::split(tmp2, vI2); Scalar mssim; for( int i = 0; i < gI1.channels(); ++i ) @@ -356,8 +356,6 @@ Scalar getMSSIM_GPU( const Mat& i1, const Mat& i2) Scalar getMSSIM_GPU_optimized( const Mat& i1, const Mat& i2, BufferMSSIM& b) { - int cn = i1.channels(); - const float C1 = 6.5025f, C2 = 58.5225f; /***************************** INITS **********************************/ diff --git a/samples/cpp/tutorial_code/introduction/windows_visual_studio_Opencv/Test.cpp b/samples/cpp/tutorial_code/introduction/windows_visual_studio_Opencv/Test.cpp index 946ad4485..7f43f0e77 100644 --- a/samples/cpp/tutorial_code/introduction/windows_visual_studio_Opencv/Test.cpp +++ b/samples/cpp/tutorial_code/introduction/windows_visual_studio_Opencv/Test.cpp @@ -14,7 +14,7 @@ using namespace cv; double getPSNR ( const Mat& I1, const Mat& I2); Scalar getMSSIM( const Mat& I1, const Mat& I2); -void help() +static void help() { cout << "\n--------------------------------------------------------------------------" << endl @@ -26,7 +26,7 @@ void help() << "--------------------------------------------------------------------------" << endl << endl; } -int main(int argc, char *argv[], char *window_name) +int main(int argc, char *argv[]) { help(); if (argc != 5) @@ -89,7 +89,7 @@ int main(int argc, char *argv[], char *window_name) double psnrV; Scalar mssimV; - while( true) //Show the image captured in the window and repeat + for(;;) //Show the image captured in the window and repeat { captRefrnc >> frameReference; captUndTst >> frameUnderTest; @@ -124,7 +124,7 @@ int main(int argc, char *argv[], char *window_name) imshow( WIN_RF, frameReference); imshow( WIN_UT, frameUnderTest); - c = cvWaitKey(delay); + c = (char)cvWaitKey(delay); if (c == 27) break; } diff --git a/samples/cpp/tutorial_code/ml/non_linear_svms/non_linear_svms.cpp b/samples/cpp/tutorial_code/ml/non_linear_svms/non_linear_svms.cpp index d94e8f82d..a24029a23 100644 --- a/samples/cpp/tutorial_code/ml/non_linear_svms/non_linear_svms.cpp +++ b/samples/cpp/tutorial_code/ml/non_linear_svms/non_linear_svms.cpp @@ -9,7 +9,7 @@ using namespace cv; using namespace std; -void help() +static void help() { cout<< "\n--------------------------------------------------------------------------" << endl << "This program shows Support Vector Machines for Non-Linearly Separable Data. " << endl diff --git a/samples/cpp/tutorial_code/objectDetection/objectDetection.cpp b/samples/cpp/tutorial_code/objectDetection/objectDetection.cpp index 14538ab6a..e20a7d4ca 100644 --- a/samples/cpp/tutorial_code/objectDetection/objectDetection.cpp +++ b/samples/cpp/tutorial_code/objectDetection/objectDetection.cpp @@ -28,7 +28,7 @@ RNG rng(12345); /** * @function main */ -int main( int argc, const char** argv ) +int main( void ) { CvCapture* capture; Mat frame; @@ -41,7 +41,7 @@ int main( int argc, const char** argv ) capture = cvCaptureFromCAM( -1 ); if( capture ) { - while( true ) + for(;;) { frame = cvQueryFrame( capture ); @@ -72,10 +72,10 @@ void detectAndDisplay( Mat frame ) //-- Detect faces face_cascade.detectMultiScale( frame_gray, faces, 1.1, 2, 0|CV_HAAR_SCALE_IMAGE, Size(30, 30) ); - for( int i = 0; i < faces.size(); i++ ) + for( size_t i = 0; i < faces.size(); i++ ) { - Point center( faces[i].x + faces[i].width*0.5, faces[i].y + faces[i].height*0.5 ); - ellipse( frame, center, Size( faces[i].width*0.5, faces[i].height*0.5), 0, 0, 360, Scalar( 255, 0, 255 ), 2, 8, 0 ); + Point center( faces[i].x + faces[i].width/2, faces[i].y + faces[i].height/2 ); + ellipse( frame, center, Size( faces[i].width/2, faces[i].height/2), 0, 0, 360, Scalar( 255, 0, 255 ), 2, 8, 0 ); Mat faceROI = frame_gray( faces[i] ); std::vector eyes; @@ -83,11 +83,11 @@ void detectAndDisplay( Mat frame ) //-- In each face, detect eyes eyes_cascade.detectMultiScale( faceROI, eyes, 1.1, 2, 0 |CV_HAAR_SCALE_IMAGE, Size(30, 30) ); - for( int j = 0; j < eyes.size(); j++ ) + for( size_t j = 0; j < eyes.size(); j++ ) { - Point center( faces[i].x + eyes[j].x + eyes[j].width*0.5, faces[i].y + eyes[j].y + eyes[j].height*0.5 ); + Point eye_center( faces[i].x + eyes[j].x + eyes[j].width/2, faces[i].y + eyes[j].y + eyes[j].height/2 ); int radius = cvRound( (eyes[j].width + eyes[j].height)*0.25 ); - circle( frame, center, radius, Scalar( 255, 0, 0 ), 3, 8, 0 ); + circle( frame, eye_center, radius, Scalar( 255, 0, 0 ), 3, 8, 0 ); } } //-- Show what you got diff --git a/samples/cpp/tutorial_code/objectDetection/objectDetection2.cpp b/samples/cpp/tutorial_code/objectDetection/objectDetection2.cpp index 4180dc7af..75167f612 100644 --- a/samples/cpp/tutorial_code/objectDetection/objectDetection2.cpp +++ b/samples/cpp/tutorial_code/objectDetection/objectDetection2.cpp @@ -28,7 +28,7 @@ RNG rng(12345); /** * @function main */ -int main( int argc, const char** argv ) +int main( void ) { CvCapture* capture; Mat frame; @@ -41,7 +41,7 @@ int main( int argc, const char** argv ) capture = cvCaptureFromCAM( -1 ); if( capture ) { - while( true ) + for(;;) { frame = cvQueryFrame( capture ); @@ -73,7 +73,7 @@ void detectAndDisplay( Mat frame ) //-- Detect faces face_cascade.detectMultiScale( frame_gray, faces, 1.1, 2, 0, Size(80, 80) ); - for( int i = 0; i < faces.size(); i++ ) + for( size_t i = 0; i < faces.size(); i++ ) { Mat faceROI = frame_gray( faces[i] ); std::vector eyes; @@ -83,14 +83,14 @@ void detectAndDisplay( Mat frame ) if( eyes.size() == 2) { //-- Draw the face - Point center( faces[i].x + faces[i].width*0.5, faces[i].y + faces[i].height*0.5 ); - ellipse( frame, center, Size( faces[i].width*0.5, faces[i].height*0.5), 0, 0, 360, Scalar( 255, 0, 0 ), 2, 8, 0 ); + Point center( faces[i].x + faces[i].width/2, faces[i].y + faces[i].height/2 ); + ellipse( frame, center, Size( faces[i].width/2, faces[i].height/2), 0, 0, 360, Scalar( 255, 0, 0 ), 2, 8, 0 ); - for( int j = 0; j < eyes.size(); j++ ) + for( size_t j = 0; j < eyes.size(); j++ ) { //-- Draw the eyes - Point center( faces[i].x + eyes[j].x + eyes[j].width*0.5, faces[i].y + eyes[j].y + eyes[j].height*0.5 ); + Point eye_center( faces[i].x + eyes[j].x + eyes[j].width/2, faces[i].y + eyes[j].y + eyes[j].height/2 ); int radius = cvRound( (eyes[j].width + eyes[j].height)*0.25 ); - circle( frame, center, radius, Scalar( 255, 0, 255 ), 3, 8, 0 ); + circle( frame, eye_center, radius, Scalar( 255, 0, 255 ), 3, 8, 0 ); } } From dad56e202fb400d19fa31b172359cd17048a28e7 Mon Sep 17 00:00:00 2001 From: Andrey Kamaev Date: Thu, 8 Nov 2012 11:41:27 +0400 Subject: [PATCH 67/91] Rename sample & tutorial executables --- samples/c/CMakeLists.txt | 4 ++-- samples/cpp/CMakeLists.txt | 19 ++++++++++++++----- samples/gpu/CMakeLists.txt | 2 +- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/samples/c/CMakeLists.txt b/samples/c/CMakeLists.txt index 411e18578..dfab5e00a 100644 --- a/samples/c/CMakeLists.txt +++ b/samples/c/CMakeLists.txt @@ -27,7 +27,7 @@ if(BUILD_EXAMPLES AND OCV_DEPENDENCIES_FOUND) target_link_libraries(${the_target} ${OPENCV_LINKER_LIBS} ${OPENCV_C_SAMPLES_REQUIRED_DEPS}) set_target_properties(${the_target} PROPERTIES - OUTPUT_NAME "${name}" + OUTPUT_NAME "c-example-${name}" PROJECT_LABEL "(EXAMPLE) ${name}") if(ENABLE_SOLUTION_FOLDERS) @@ -47,7 +47,7 @@ if(BUILD_EXAMPLES AND OCV_DEPENDENCIES_FOUND) foreach(sample_filename ${cpp_samples}) get_filename_component(sample ${sample_filename} NAME_WE) - OPENCV_DEFINE_C_EXAMPLE(${sample} ${sample_filename}) + OPENCV_DEFINE_C_EXAMPLE(${sample} ${sample_filename}) endforeach() endif() diff --git a/samples/cpp/CMakeLists.txt b/samples/cpp/CMakeLists.txt index 1ed0d2c6f..2004857f1 100644 --- a/samples/cpp/CMakeLists.txt +++ b/samples/cpp/CMakeLists.txt @@ -28,7 +28,16 @@ if(BUILD_EXAMPLES AND OCV_DEPENDENCIES_FOUND) # Define executable targets # --------------------------------------------- MACRO(OPENCV_DEFINE_CPP_EXAMPLE name srcs) - set(the_target "example_${name}") + + if("${srcs}" MATCHES "tutorial_code") + set(sample_kind tutorial) + set(sample_KIND TUTORIAL) + else() + set(sample_kind example) + set(sample_KIND EXAMPLE) + endif() + + set(the_target "${sample_kind}_${name}") add_executable(${the_target} ${srcs}) target_link_libraries(${the_target} ${OPENCV_LINKER_LIBS} ${OPENCV_CPP_SAMPLES_REQUIRED_DEPS}) @@ -37,11 +46,11 @@ if(BUILD_EXAMPLES AND OCV_DEPENDENCIES_FOUND) endif() set_target_properties(${the_target} PROPERTIES - OUTPUT_NAME "${name}" - PROJECT_LABEL "(EXAMPLE) ${name}") + OUTPUT_NAME "cpp-${sample_kind}-${name}" + PROJECT_LABEL "(${sample_KIND}) ${name}") if(ENABLE_SOLUTION_FOLDERS) - set_target_properties(${the_target} PROPERTIES FOLDER "samples//cpp") + set_target_properties(${the_target} PROPERTIES FOLDER "${sample_kind}s//cpp") endif() if(WIN32) @@ -49,7 +58,7 @@ if(BUILD_EXAMPLES AND OCV_DEPENDENCIES_FOUND) set_target_properties(${the_target} PROPERTIES LINK_FLAGS "/NODEFAULTLIB:atlthunk.lib /NODEFAULTLIB:atlsd.lib /DEBUG") endif() install(TARGETS ${the_target} - RUNTIME DESTINATION "samples/cpp" COMPONENT main) + RUNTIME DESTINATION "${sample_kind}s/cpp" COMPONENT main) endif() ENDMACRO() diff --git a/samples/gpu/CMakeLists.txt b/samples/gpu/CMakeLists.txt index 2bf069eaf..6abb7e5af 100644 --- a/samples/gpu/CMakeLists.txt +++ b/samples/gpu/CMakeLists.txt @@ -35,7 +35,7 @@ if(BUILD_EXAMPLES AND OCV_DEPENDENCIES_FOUND) target_link_libraries(${the_target} ${OPENCV_LINKER_LIBS} ${OPENCV_GPU_SAMPLES_REQUIRED_DEPS}) set_target_properties(${the_target} PROPERTIES - OUTPUT_NAME "${name}_${project}" + OUTPUT_NAME "${project}-example-${name}" PROJECT_LABEL "(EXAMPLE_${project_upper}) ${name}") if(ENABLE_SOLUTION_FOLDERS) From a126532cb7e2a02f162ae4c179ea46f8b0a20893 Mon Sep 17 00:00:00 2001 From: Andrey Kamaev Date: Fri, 9 Nov 2012 11:29:52 +0400 Subject: [PATCH 68/91] Fix OS X build warnings --- modules/calib3d/perf/perf_precomp.hpp | 2 +- modules/calib3d/test/test_precomp.hpp | 2 +- modules/contrib/test/test_precomp.hpp | 2 +- modules/core/perf/perf_precomp.hpp | 2 +- modules/core/test/test_precomp.hpp | 2 +- modules/features2d/perf/perf_precomp.hpp | 2 +- modules/features2d/test/test_precomp.hpp | 2 +- modules/gpu/perf/perf_precomp.hpp | 2 +- modules/gpu/test/test_precomp.hpp | 2 +- modules/highgui/perf/perf_precomp.hpp | 2 +- modules/highgui/test/test_precomp.hpp | 2 +- modules/imgproc/perf/perf_precomp.hpp | 2 +- modules/imgproc/test/test_precomp.hpp | 2 +- modules/legacy/test/test_precomp.hpp | 2 +- modules/ml/test/test_precomp.hpp | 2 +- modules/nonfree/perf/perf_precomp.hpp | 2 +- modules/nonfree/test/test_precomp.hpp | 2 +- modules/objdetect/perf/perf_precomp.hpp | 2 +- modules/objdetect/test/test_precomp.hpp | 2 +- modules/photo/perf/perf_precomp.hpp | 2 +- modules/photo/test/test_precomp.hpp | 2 +- modules/stitching/perf/perf_precomp.hpp | 2 +- modules/stitching/test/test_precomp.hpp | 2 +- modules/video/perf/perf_precomp.hpp | 2 +- modules/video/test/test_precomp.hpp | 2 +- 25 files changed, 25 insertions(+), 25 deletions(-) diff --git a/modules/calib3d/perf/perf_precomp.hpp b/modules/calib3d/perf/perf_precomp.hpp index 891d50e05..6cee5b90e 100644 --- a/modules/calib3d/perf/perf_precomp.hpp +++ b/modules/calib3d/perf/perf_precomp.hpp @@ -1,6 +1,6 @@ #ifdef __GNUC__ # pragma GCC diagnostic ignored "-Wmissing-declarations" -# ifdef __clang__ +# if defined __clang__ || defined __APPLE__ # pragma GCC diagnostic ignored "-Wmissing-prototypes" # pragma GCC diagnostic ignored "-Wextra" # endif diff --git a/modules/calib3d/test/test_precomp.hpp b/modules/calib3d/test/test_precomp.hpp index 2d1f35702..e0fcd486d 100644 --- a/modules/calib3d/test/test_precomp.hpp +++ b/modules/calib3d/test/test_precomp.hpp @@ -1,6 +1,6 @@ #ifdef __GNUC__ # pragma GCC diagnostic ignored "-Wmissing-declarations" -# ifdef __clang__ +# if defined __clang__ || defined __APPLE__ # pragma GCC diagnostic ignored "-Wmissing-prototypes" # pragma GCC diagnostic ignored "-Wextra" # endif diff --git a/modules/contrib/test/test_precomp.hpp b/modules/contrib/test/test_precomp.hpp index 2a7a3d44b..d477eddbb 100644 --- a/modules/contrib/test/test_precomp.hpp +++ b/modules/contrib/test/test_precomp.hpp @@ -1,6 +1,6 @@ #ifdef __GNUC__ # pragma GCC diagnostic ignored "-Wmissing-declarations" -# ifdef __clang__ +# if defined __clang__ || defined __APPLE__ # pragma GCC diagnostic ignored "-Wmissing-prototypes" # pragma GCC diagnostic ignored "-Wextra" # endif diff --git a/modules/core/perf/perf_precomp.hpp b/modules/core/perf/perf_precomp.hpp index 9417bc364..4d5d9886e 100644 --- a/modules/core/perf/perf_precomp.hpp +++ b/modules/core/perf/perf_precomp.hpp @@ -1,6 +1,6 @@ #ifdef __GNUC__ # pragma GCC diagnostic ignored "-Wmissing-declarations" -# ifdef __clang__ +# if defined __clang__ || defined __APPLE__ # pragma GCC diagnostic ignored "-Wmissing-prototypes" # pragma GCC diagnostic ignored "-Wextra" # endif diff --git a/modules/core/test/test_precomp.hpp b/modules/core/test/test_precomp.hpp index 6f1b188cc..5cbe1c8f9 100644 --- a/modules/core/test/test_precomp.hpp +++ b/modules/core/test/test_precomp.hpp @@ -1,6 +1,6 @@ #ifdef __GNUC__ # pragma GCC diagnostic ignored "-Wmissing-declarations" -# ifdef __clang__ +# if defined __clang__ || defined __APPLE__ # pragma GCC diagnostic ignored "-Wmissing-prototypes" # pragma GCC diagnostic ignored "-Wextra" # endif diff --git a/modules/features2d/perf/perf_precomp.hpp b/modules/features2d/perf/perf_precomp.hpp index 1f3ad1fe9..c3f98c217 100644 --- a/modules/features2d/perf/perf_precomp.hpp +++ b/modules/features2d/perf/perf_precomp.hpp @@ -1,6 +1,6 @@ #ifdef __GNUC__ # pragma GCC diagnostic ignored "-Wmissing-declarations" -# ifdef __clang__ +# if defined __clang__ || defined __APPLE__ # pragma GCC diagnostic ignored "-Wmissing-prototypes" # pragma GCC diagnostic ignored "-Wextra" # endif diff --git a/modules/features2d/test/test_precomp.hpp b/modules/features2d/test/test_precomp.hpp index 28985f944..bc2d8be6e 100644 --- a/modules/features2d/test/test_precomp.hpp +++ b/modules/features2d/test/test_precomp.hpp @@ -1,6 +1,6 @@ #ifdef __GNUC__ # pragma GCC diagnostic ignored "-Wmissing-declarations" -# ifdef __clang__ +# if defined __clang__ || defined __APPLE__ # pragma GCC diagnostic ignored "-Wmissing-prototypes" # pragma GCC diagnostic ignored "-Wextra" # endif diff --git a/modules/gpu/perf/perf_precomp.hpp b/modules/gpu/perf/perf_precomp.hpp index 04ccfdef3..4dca93c44 100644 --- a/modules/gpu/perf/perf_precomp.hpp +++ b/modules/gpu/perf/perf_precomp.hpp @@ -1,6 +1,6 @@ #ifdef __GNUC__ # pragma GCC diagnostic ignored "-Wmissing-declarations" -# ifdef __clang__ +# if defined __clang__ || defined __APPLE__ # pragma GCC diagnostic ignored "-Wmissing-prototypes" # pragma GCC diagnostic ignored "-Wextra" # endif diff --git a/modules/gpu/test/test_precomp.hpp b/modules/gpu/test/test_precomp.hpp index 3e6abef82..b75f8edd8 100644 --- a/modules/gpu/test/test_precomp.hpp +++ b/modules/gpu/test/test_precomp.hpp @@ -41,7 +41,7 @@ #ifdef __GNUC__ # pragma GCC diagnostic ignored "-Wmissing-declarations" -# ifdef __clang__ +# if defined __clang__ || defined __APPLE__ # pragma GCC diagnostic ignored "-Wmissing-prototypes" # pragma GCC diagnostic ignored "-Wextra" # endif diff --git a/modules/highgui/perf/perf_precomp.hpp b/modules/highgui/perf/perf_precomp.hpp index fc9c3b8b2..2b57ad7ee 100644 --- a/modules/highgui/perf/perf_precomp.hpp +++ b/modules/highgui/perf/perf_precomp.hpp @@ -1,6 +1,6 @@ #ifdef __GNUC__ # pragma GCC diagnostic ignored "-Wmissing-declarations" -# ifdef __clang__ +# if defined __clang__ || defined __APPLE__ # pragma GCC diagnostic ignored "-Wmissing-prototypes" # pragma GCC diagnostic ignored "-Wextra" # endif diff --git a/modules/highgui/test/test_precomp.hpp b/modules/highgui/test/test_precomp.hpp index 6941a0c6e..3286c0f59 100644 --- a/modules/highgui/test/test_precomp.hpp +++ b/modules/highgui/test/test_precomp.hpp @@ -1,6 +1,6 @@ #ifdef __GNUC__ # pragma GCC diagnostic ignored "-Wmissing-declarations" -# ifdef __clang__ +# if defined __clang__ || defined __APPLE__ # pragma GCC diagnostic ignored "-Wmissing-prototypes" # pragma GCC diagnostic ignored "-Wextra" # endif diff --git a/modules/imgproc/perf/perf_precomp.hpp b/modules/imgproc/perf/perf_precomp.hpp index 9120beec8..304802491 100644 --- a/modules/imgproc/perf/perf_precomp.hpp +++ b/modules/imgproc/perf/perf_precomp.hpp @@ -1,6 +1,6 @@ #ifdef __GNUC__ # pragma GCC diagnostic ignored "-Wmissing-declarations" -# ifdef __clang__ +# if defined __clang__ || defined __APPLE__ # pragma GCC diagnostic ignored "-Wmissing-prototypes" # pragma GCC diagnostic ignored "-Wextra" # endif diff --git a/modules/imgproc/test/test_precomp.hpp b/modules/imgproc/test/test_precomp.hpp index 493a09d36..4c973c1ae 100644 --- a/modules/imgproc/test/test_precomp.hpp +++ b/modules/imgproc/test/test_precomp.hpp @@ -1,6 +1,6 @@ #ifdef __GNUC__ # pragma GCC diagnostic ignored "-Wmissing-declarations" -# ifdef __clang__ +# if defined __clang__ || defined __APPLE__ # pragma GCC diagnostic ignored "-Wmissing-prototypes" # pragma GCC diagnostic ignored "-Wextra" # endif diff --git a/modules/legacy/test/test_precomp.hpp b/modules/legacy/test/test_precomp.hpp index f40c7d406..b4ac3f574 100644 --- a/modules/legacy/test/test_precomp.hpp +++ b/modules/legacy/test/test_precomp.hpp @@ -1,6 +1,6 @@ #ifdef __GNUC__ # pragma GCC diagnostic ignored "-Wmissing-declarations" -# ifdef __clang__ +# if defined __clang__ || defined __APPLE__ # pragma GCC diagnostic ignored "-Wmissing-prototypes" # pragma GCC diagnostic ignored "-Wextra" # endif diff --git a/modules/ml/test/test_precomp.hpp b/modules/ml/test/test_precomp.hpp index 46334d527..3ccf10a4a 100644 --- a/modules/ml/test/test_precomp.hpp +++ b/modules/ml/test/test_precomp.hpp @@ -1,6 +1,6 @@ #ifdef __GNUC__ # pragma GCC diagnostic ignored "-Wmissing-declarations" -# ifdef __clang__ +# if defined __clang__ || defined __APPLE__ # pragma GCC diagnostic ignored "-Wmissing-prototypes" # pragma GCC diagnostic ignored "-Wextra" # endif diff --git a/modules/nonfree/perf/perf_precomp.hpp b/modules/nonfree/perf/perf_precomp.hpp index 3afb5b4c3..79a368d71 100644 --- a/modules/nonfree/perf/perf_precomp.hpp +++ b/modules/nonfree/perf/perf_precomp.hpp @@ -1,6 +1,6 @@ #ifdef __GNUC__ # pragma GCC diagnostic ignored "-Wmissing-declarations" -# ifdef __clang__ +# if defined __clang__ || defined __APPLE__ # pragma GCC diagnostic ignored "-Wmissing-prototypes" # pragma GCC diagnostic ignored "-Wextra" # endif diff --git a/modules/nonfree/test/test_precomp.hpp b/modules/nonfree/test/test_precomp.hpp index cbf5253ab..062ab7bb1 100644 --- a/modules/nonfree/test/test_precomp.hpp +++ b/modules/nonfree/test/test_precomp.hpp @@ -1,6 +1,6 @@ #ifdef __GNUC__ # pragma GCC diagnostic ignored "-Wmissing-declarations" -# ifdef __clang__ +# if defined __clang__ || defined __APPLE__ # pragma GCC diagnostic ignored "-Wmissing-prototypes" # pragma GCC diagnostic ignored "-Wextra" # endif diff --git a/modules/objdetect/perf/perf_precomp.hpp b/modules/objdetect/perf/perf_precomp.hpp index c5ae36cf9..d1a7e444c 100644 --- a/modules/objdetect/perf/perf_precomp.hpp +++ b/modules/objdetect/perf/perf_precomp.hpp @@ -1,6 +1,6 @@ #ifdef __GNUC__ # pragma GCC diagnostic ignored "-Wmissing-declarations" -# ifdef __clang__ +# if defined __clang__ || defined __APPLE__ # pragma GCC diagnostic ignored "-Wmissing-prototypes" # pragma GCC diagnostic ignored "-Wextra" # endif diff --git a/modules/objdetect/test/test_precomp.hpp b/modules/objdetect/test/test_precomp.hpp index cb7ac0f15..9100ab04c 100644 --- a/modules/objdetect/test/test_precomp.hpp +++ b/modules/objdetect/test/test_precomp.hpp @@ -1,6 +1,6 @@ #ifdef __GNUC__ # pragma GCC diagnostic ignored "-Wmissing-declarations" -# ifdef __clang__ +# if defined __clang__ || defined __APPLE__ # pragma GCC diagnostic ignored "-Wmissing-prototypes" # pragma GCC diagnostic ignored "-Wextra" # endif diff --git a/modules/photo/perf/perf_precomp.hpp b/modules/photo/perf/perf_precomp.hpp index 3c40b2921..117233333 100644 --- a/modules/photo/perf/perf_precomp.hpp +++ b/modules/photo/perf/perf_precomp.hpp @@ -1,6 +1,6 @@ #ifdef __GNUC__ # pragma GCC diagnostic ignored "-Wmissing-declarations" -# ifdef __clang__ +# if defined __clang__ || defined __APPLE__ # pragma GCC diagnostic ignored "-Wmissing-prototypes" # pragma GCC diagnostic ignored "-Wextra" # endif diff --git a/modules/photo/test/test_precomp.hpp b/modules/photo/test/test_precomp.hpp index 877f21532..d1f3dcab2 100644 --- a/modules/photo/test/test_precomp.hpp +++ b/modules/photo/test/test_precomp.hpp @@ -1,6 +1,6 @@ #ifdef __GNUC__ # pragma GCC diagnostic ignored "-Wmissing-declarations" -# ifdef __clang__ +# if defined __clang__ || defined __APPLE__ # pragma GCC diagnostic ignored "-Wmissing-prototypes" # pragma GCC diagnostic ignored "-Wextra" # endif diff --git a/modules/stitching/perf/perf_precomp.hpp b/modules/stitching/perf/perf_precomp.hpp index f6cdae81e..559891fe3 100644 --- a/modules/stitching/perf/perf_precomp.hpp +++ b/modules/stitching/perf/perf_precomp.hpp @@ -1,6 +1,6 @@ #ifdef __GNUC__ # pragma GCC diagnostic ignored "-Wmissing-declarations" -# ifdef __clang__ +# if defined __clang__ || defined __APPLE__ # pragma GCC diagnostic ignored "-Wmissing-prototypes" # pragma GCC diagnostic ignored "-Wextra" # endif diff --git a/modules/stitching/test/test_precomp.hpp b/modules/stitching/test/test_precomp.hpp index e703850bf..5509d1c86 100644 --- a/modules/stitching/test/test_precomp.hpp +++ b/modules/stitching/test/test_precomp.hpp @@ -1,6 +1,6 @@ #ifdef __GNUC__ # pragma GCC diagnostic ignored "-Wmissing-declarations" -# ifdef __clang__ +# if defined __clang__ || defined __APPLE__ # pragma GCC diagnostic ignored "-Wmissing-prototypes" # pragma GCC diagnostic ignored "-Wextra" # endif diff --git a/modules/video/perf/perf_precomp.hpp b/modules/video/perf/perf_precomp.hpp index bbee05eb7..e1c2b566b 100644 --- a/modules/video/perf/perf_precomp.hpp +++ b/modules/video/perf/perf_precomp.hpp @@ -1,6 +1,6 @@ #ifdef __GNUC__ # pragma GCC diagnostic ignored "-Wmissing-declarations" -# ifdef __clang__ +# if defined __clang__ || defined __APPLE__ # pragma GCC diagnostic ignored "-Wmissing-prototypes" # pragma GCC diagnostic ignored "-Wextra" # endif diff --git a/modules/video/test/test_precomp.hpp b/modules/video/test/test_precomp.hpp index 6b528bb5a..a4b869a52 100644 --- a/modules/video/test/test_precomp.hpp +++ b/modules/video/test/test_precomp.hpp @@ -1,6 +1,6 @@ #ifdef __GNUC__ # pragma GCC diagnostic ignored "-Wmissing-declarations" -# ifdef __clang__ +# if defined __clang__ || defined __APPLE__ # pragma GCC diagnostic ignored "-Wmissing-prototypes" # pragma GCC diagnostic ignored "-Wextra" # endif From baef62b4d2c8942ce6fe8a3a62113bc4ce14b8eb Mon Sep 17 00:00:00 2001 From: Alexander Smorkalov Date: Fri, 9 Nov 2012 11:46:14 +0400 Subject: [PATCH 69/91] Java test fix. Eclipse test execution fix. --- .../src/org/opencv/test/OpenCVTestCase.java | 2 + .../src/org/opencv/test/OpenCVTestRunner.java | 24 +++--- .../features2d/FASTFeatureDetectorTest.java | 9 +- .../org/opencv/test/highgui/HighguiTest.java | 6 +- .../opencv/test/highgui/VideoCaptureTest.java | 83 ++++++++++++++----- 5 files changed, 87 insertions(+), 37 deletions(-) diff --git a/modules/java/android_test/src/org/opencv/test/OpenCVTestCase.java b/modules/java/android_test/src/org/opencv/test/OpenCVTestCase.java index 102adf195..f8f3c6f89 100644 --- a/modules/java/android_test/src/org/opencv/test/OpenCVTestCase.java +++ b/modules/java/android_test/src/org/opencv/test/OpenCVTestCase.java @@ -28,6 +28,8 @@ public class OpenCVTestCase extends TestCase { //change to 'true' to unblock fail on fail("Not yet implemented") public static final boolean passNYI = true; + protected static boolean isEnabled = true; + protected static final int matSize = 10; protected static final double EPS = 0.001; protected static final double weakEPS = 0.5; diff --git a/modules/java/android_test/src/org/opencv/test/OpenCVTestRunner.java b/modules/java/android_test/src/org/opencv/test/OpenCVTestRunner.java index 3c416c510..f77801211 100644 --- a/modules/java/android_test/src/org/opencv/test/OpenCVTestRunner.java +++ b/modules/java/android_test/src/org/opencv/test/OpenCVTestRunner.java @@ -2,9 +2,9 @@ package org.opencv.test; import java.io.File; import java.io.IOException; -import java.util.Iterator; +//import java.util.Iterator; -import junit.framework.TestCase; +//import junit.framework.TestCase; import junit.framework.Assert; import org.opencv.android.Utils; @@ -72,15 +72,17 @@ public class OpenCVTestRunner extends InstrumentationTestRunner { //List testCases = androidTestRunner.getTestCases(); //Collections.shuffle(testCases); //shuffle the tests order - if(OpenCVTestCase.passNYI) { - // turn off problematic camera tests - Iterator it = androidTestRunner.getTestCases().iterator(); - while (it.hasNext()) { - String name = it.next().toString(); - if (name.contains("VideoCaptureTest")) - it.remove(); - } - } + // Note: VideoCapture tests turned off by flag field in VideoCaptureTest class + +// if(OpenCVTestCase.passNYI) { +// // turn off problematic camera tests +// Iterator it = androidTestRunner.getTestCases().iterator(); +// while (it.hasNext()) { +// String name = it.next().toString(); +// if (name.contains("VideoCaptureTest")) +// it.remove(); +// } +// } super.onStart(); diff --git a/modules/java/android_test/src/org/opencv/test/features2d/FASTFeatureDetectorTest.java b/modules/java/android_test/src/org/opencv/test/features2d/FASTFeatureDetectorTest.java index 35ffd6477..4e068e1ac 100644 --- a/modules/java/android_test/src/org/opencv/test/features2d/FASTFeatureDetectorTest.java +++ b/modules/java/android_test/src/org/opencv/test/features2d/FASTFeatureDetectorTest.java @@ -13,6 +13,8 @@ import org.opencv.features2d.KeyPoint; import org.opencv.test.OpenCVTestCase; import org.opencv.test.OpenCVTestRunner; +import android.util.Log; + public class FASTFeatureDetectorTest extends OpenCVTestCase { FeatureDetector detector; @@ -127,9 +129,9 @@ public class FASTFeatureDetectorTest extends OpenCVTestCase { detector.write(filename); - String truth = "\n\nFeature2D.FAST\n1\n10\n\n"; + String truth = "\n\nFeature2D.FAST\n1\n10\n2\n\n"; String data = readFile(filename); - + Log.d("qqq", "\"" + data + "\""); assertEquals(truth, data); } @@ -138,9 +140,10 @@ public class FASTFeatureDetectorTest extends OpenCVTestCase { detector.write(filename); - String truth = "%YAML:1.0\nname: \"Feature2D.FAST\"\nnonmaxSuppression: 1\nthreshold: 10\n"; + String truth = "%YAML:1.0\nname: \"Feature2D.FAST\"\nnonmaxSuppression: 1\nthreshold: 10\ntype: 2\n"; String data = readFile(filename); + Log.d("qqq", "\"" + data + "\""); assertEquals(truth, data); } } diff --git a/modules/java/android_test/src/org/opencv/test/highgui/HighguiTest.java b/modules/java/android_test/src/org/opencv/test/highgui/HighguiTest.java index 9f7872771..b8e7c3b8b 100644 --- a/modules/java/android_test/src/org/opencv/test/highgui/HighguiTest.java +++ b/modules/java/android_test/src/org/opencv/test/highgui/HighguiTest.java @@ -22,10 +22,10 @@ public class HighguiTest extends OpenCVTestCase { public void testImencodeStringMatListOfByteListOfInteger() { MatOfInt params40 = new MatOfInt(Highgui.IMWRITE_JPEG_QUALITY, 40); MatOfInt params90 = new MatOfInt(Highgui.IMWRITE_JPEG_QUALITY, 90); - /* or + /* or MatOfInt params = new MatOfInt(); - params.fromArray(Highgui.IMWRITE_JPEG_QUALITY, 40); - */ + params.fromArray(Highgui.IMWRITE_JPEG_QUALITY, 40); + */ MatOfByte buff40 = new MatOfByte(); MatOfByte buff90 = new MatOfByte(); diff --git a/modules/java/android_test/src/org/opencv/test/highgui/VideoCaptureTest.java b/modules/java/android_test/src/org/opencv/test/highgui/VideoCaptureTest.java index c6901c5e4..ce210714c 100644 --- a/modules/java/android_test/src/org/opencv/test/highgui/VideoCaptureTest.java +++ b/modules/java/android_test/src/org/opencv/test/highgui/VideoCaptureTest.java @@ -19,13 +19,17 @@ public class VideoCaptureTest extends OpenCVTestCase { super.setUp(); capture = null; + isEnabled = false; isSucceed = false; isOpened = false; } public void testGet() { - try - { + if (!isEnabled) { + fail("Not yet implemented"); + } + + try { capture = new VideoCapture(Highgui.CV_CAP_ANDROID); double frameWidth = capture.get(Highgui.CV_CAP_PROP_FRAME_WIDTH); assertTrue(0 != frameWidth); @@ -35,8 +39,11 @@ public class VideoCaptureTest extends OpenCVTestCase { } public void testGetSupportedPreviewSizes() { - try - { + if (!isEnabled) { + fail("Not yet implemented"); + } + + try { capture = new VideoCapture(Highgui.CV_CAP_ANDROID); List sizes = capture.getSupportedPreviewSizes(); assertNotNull(sizes); @@ -47,12 +54,20 @@ public class VideoCaptureTest extends OpenCVTestCase { } public void testGrab() { + if (!isEnabled) { + fail("Not yet implemented"); + } + capture = new VideoCapture(); isSucceed = capture.grab(); assertFalse(isSucceed); } public void testGrabFromRealCamera() { + if (!isEnabled) { + fail("Not yet implemented"); + } + try { capture = new VideoCapture(Highgui.CV_CAP_ANDROID); isSucceed = capture.grab(); @@ -63,13 +78,20 @@ public class VideoCaptureTest extends OpenCVTestCase { } public void testIsOpened() { + if (!isEnabled) { + fail("Not yet implemented"); + } + capture = new VideoCapture(); assertFalse(capture.isOpened()); } public void testIsOpenedRealCamera() { - try - { + if (!isEnabled) { + fail("Not yet implemented"); + } + + try { capture = new VideoCapture(Highgui.CV_CAP_ANDROID); isOpened = capture.isOpened(); assertTrue(isOpened); @@ -79,8 +101,11 @@ public class VideoCaptureTest extends OpenCVTestCase { } public void testOpen() { - try - { + if (!isEnabled) { + fail("Not yet implemented"); + } + + try { capture = new VideoCapture(); capture.open(Highgui.CV_CAP_ANDROID); isOpened = capture.isOpened(); @@ -91,8 +116,11 @@ public class VideoCaptureTest extends OpenCVTestCase { } public void testRead() { - try - { + if (!isEnabled) { + fail("Not yet implemented"); + } + + try { capture = new VideoCapture(Highgui.CV_CAP_ANDROID); isSucceed = capture.read(dst); assertTrue(isSucceed); @@ -104,8 +132,11 @@ public class VideoCaptureTest extends OpenCVTestCase { } public void testRelease() { - try - { + if (!isEnabled) { + fail("Not yet implemented"); + } + + try { capture = new VideoCapture(Highgui.CV_CAP_ANDROID); capture.release(); assertFalse(capture.isOpened()); @@ -116,8 +147,11 @@ public class VideoCaptureTest extends OpenCVTestCase { } public void testRetrieveMat() { - try - { + if (!isEnabled) { + fail("Not yet implemented"); + } + + try { capture = new VideoCapture(Highgui.CV_CAP_ANDROID); capture.grab(); isSucceed = capture.retrieve(dst); @@ -130,8 +164,11 @@ public class VideoCaptureTest extends OpenCVTestCase { } public void testRetrieveMatInt() { - try - { + if (!isEnabled) { + fail("Not yet implemented"); + } + + try { capture = new VideoCapture(Highgui.CV_CAP_ANDROID); capture.grab(); isSucceed = capture.retrieve(dst, Highgui.CV_CAP_ANDROID_GREY_FRAME); @@ -144,8 +181,11 @@ public class VideoCaptureTest extends OpenCVTestCase { } public void testSet() { - try - { + if (!isEnabled) { + fail("Not yet implemented"); + } + + try { capture = new VideoCapture(Highgui.CV_CAP_ANDROID); capture.set(Highgui.CV_CAP_PROP_FRAME_WIDTH, 640); capture.set(Highgui.CV_CAP_PROP_FRAME_HEIGHT, 480); @@ -165,8 +205,11 @@ public class VideoCaptureTest extends OpenCVTestCase { } public void testVideoCaptureInt() { - try - { + if (!isEnabled) { + fail("Not yet implemented"); + } + + try { capture = new VideoCapture(Highgui.CV_CAP_ANDROID); assertNotNull(capture); assertTrue(capture.isOpened()); From dda2eb0f76535a56a719fc4b6cfac5b9bba62951 Mon Sep 17 00:00:00 2001 From: Alexander Smorkalov Date: Fri, 9 Nov 2012 12:16:48 +0400 Subject: [PATCH 70/91] Libinfo build fix; Libinfo revision formating fix; HW dependent VersionCode for Manager implemented. --- CMakeLists.txt | 2 +- android/libinfo/info.c | 2 +- android/service/engine/AndroidManifest.xml | 2 +- android/service/engine/CMakeLists.txt | 18 ++++++++++++++++++ 4 files changed, 21 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0502fb899..8707e0155 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -467,7 +467,7 @@ if(BUILD_ANDROID_PACKAGE) add_subdirectory(android/package) endif() -if (ANDROID AND NOT BUILD_ANDROID_SERVICE AND NOT BUILD_ANDROID_PACKAGE AND NOT BUILD_CAMERA_WRAPER) +if (ANDROID) add_subdirectory(android/libinfo) endif() diff --git a/android/libinfo/info.c b/android/libinfo/info.c index f1e5bf01e..f0c2dd6a2 100644 --- a/android/libinfo/info.c +++ b/android/libinfo/info.c @@ -7,7 +7,7 @@ const char* GetLibraryList(void); JNIEXPORT jstring JNICALL Java_org_opencv_android_StaticHelper_getLibraryList(JNIEnv *, jclass); #define PACKAGE_NAME "org.opencv.lib_v" CVAUX_STR(CV_MAJOR_VERSION) CVAUX_STR(CV_MINOR_VERSION) "_" ANDROID_PACKAGE_PLATFORM -#define PACKAGE_REVISION CVAUX_STR(CV_SUBMINOR_VERSION) CVAUX_STR(ANDROID_PACKAGE_RELEASE) +#define PACKAGE_REVISION CVAUX_STR(CV_SUBMINOR_VERSION) "." CVAUX_STR(ANDROID_PACKAGE_RELEASE) const char* GetPackageName(void) { diff --git a/android/service/engine/AndroidManifest.xml b/android/service/engine/AndroidManifest.xml index b1d6f691c..55cddcd8c 100644 --- a/android/service/engine/AndroidManifest.xml +++ b/android/service/engine/AndroidManifest.xml @@ -1,7 +1,7 @@ diff --git a/android/service/engine/CMakeLists.txt b/android/service/engine/CMakeLists.txt index 529aef9bd..b0d8425ca 100644 --- a/android/service/engine/CMakeLists.txt +++ b/android/service/engine/CMakeLists.txt @@ -4,6 +4,24 @@ set(JNI_LIB_NAME ${engine} ${engine}_jni) unset(__android_project_chain CACHE) add_android_project(opencv_engine "${CMAKE_CURRENT_SOURCE_DIR}" SDK_TARGET 8 ${ANDROID_SDK_TARGET} IGNORE_JAVA ON) +set(ANDROID_PLATFORM_VERSION_CODE "0") + +if(ARMEABI_V7A) + set(ANDROID_PLATFORM_VERSION_CODE "2") + elseif(ARMEABI_V6) + set(ANDROID_PLATFORM_VERSION_CODE "1") + elseif(ARMEABI) + set(ANDROID_PLATFORM_VERSION_CODE "1") + elseif(X86) + set(ANDROID_PLATFORM_VERSION_CODE "3") + elseif(MIPS) + set(ANDROID_PLATFORM_VERSION_CODE "4") + else() + message(WARNING "Can not automatically determine the value for ANDROID_PLATFORM_VERSION_CODE") + endif() + +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/${ANDROID_MANIFEST_FILE}" "${OpenCV_BINARY_DIR}/android/service/engine/.build/${ANDROID_MANIFEST_FILE}" @ONLY) + link_directories("${ANDROID_SOURCE_TREE}/out/target/product/generic/system/lib" "${ANDROID_SOURCE_TREE}/out/target/product/${ANDROID_PRODUCT}/system/lib" "${ANDROID_SOURCE_TREE}/bin/${ANDROID_ARCH_NAME}") # -D__SUPPORT_ARMEABI_FEATURES key is also available From e06c5b6fd5c9c186176263b2def0f71c18af2cfa Mon Sep 17 00:00:00 2001 From: Alexander Smorkalov Date: Mon, 12 Nov 2012 17:47:20 +0400 Subject: [PATCH 71/91] Code review comments applied. --- .../src/org/opencv/test/OpenCVTestCase.java | 2 +- .../src/org/opencv/test/OpenCVTestRunner.java | 14 ---------- .../opencv/test/highgui/VideoCaptureTest.java | 28 +++++++++---------- 3 files changed, 15 insertions(+), 29 deletions(-) diff --git a/modules/java/android_test/src/org/opencv/test/OpenCVTestCase.java b/modules/java/android_test/src/org/opencv/test/OpenCVTestCase.java index f8f3c6f89..6acf0b34d 100644 --- a/modules/java/android_test/src/org/opencv/test/OpenCVTestCase.java +++ b/modules/java/android_test/src/org/opencv/test/OpenCVTestCase.java @@ -28,7 +28,7 @@ public class OpenCVTestCase extends TestCase { //change to 'true' to unblock fail on fail("Not yet implemented") public static final boolean passNYI = true; - protected static boolean isEnabled = true; + protected static boolean isTestCaseEnabled = true; protected static final int matSize = 10; protected static final double EPS = 0.001; diff --git a/modules/java/android_test/src/org/opencv/test/OpenCVTestRunner.java b/modules/java/android_test/src/org/opencv/test/OpenCVTestRunner.java index f77801211..3bd0be249 100644 --- a/modules/java/android_test/src/org/opencv/test/OpenCVTestRunner.java +++ b/modules/java/android_test/src/org/opencv/test/OpenCVTestRunner.java @@ -2,9 +2,6 @@ package org.opencv.test; import java.io.File; import java.io.IOException; -//import java.util.Iterator; - -//import junit.framework.TestCase; import junit.framework.Assert; import org.opencv.android.Utils; @@ -74,17 +71,6 @@ public class OpenCVTestRunner extends InstrumentationTestRunner { // Note: VideoCapture tests turned off by flag field in VideoCaptureTest class -// if(OpenCVTestCase.passNYI) { -// // turn off problematic camera tests -// Iterator it = androidTestRunner.getTestCases().iterator(); -// while (it.hasNext()) { -// String name = it.next().toString(); -// if (name.contains("VideoCaptureTest")) -// it.remove(); -// } -// } - - super.onStart(); } diff --git a/modules/java/android_test/src/org/opencv/test/highgui/VideoCaptureTest.java b/modules/java/android_test/src/org/opencv/test/highgui/VideoCaptureTest.java index ce210714c..903768f7b 100644 --- a/modules/java/android_test/src/org/opencv/test/highgui/VideoCaptureTest.java +++ b/modules/java/android_test/src/org/opencv/test/highgui/VideoCaptureTest.java @@ -19,13 +19,13 @@ public class VideoCaptureTest extends OpenCVTestCase { super.setUp(); capture = null; - isEnabled = false; + isTestCaseEnabled = false; isSucceed = false; isOpened = false; } public void testGet() { - if (!isEnabled) { + if (!isTestCaseEnabled) { fail("Not yet implemented"); } @@ -39,7 +39,7 @@ public class VideoCaptureTest extends OpenCVTestCase { } public void testGetSupportedPreviewSizes() { - if (!isEnabled) { + if (!isTestCaseEnabled) { fail("Not yet implemented"); } @@ -54,7 +54,7 @@ public class VideoCaptureTest extends OpenCVTestCase { } public void testGrab() { - if (!isEnabled) { + if (!isTestCaseEnabled) { fail("Not yet implemented"); } @@ -64,7 +64,7 @@ public class VideoCaptureTest extends OpenCVTestCase { } public void testGrabFromRealCamera() { - if (!isEnabled) { + if (!isTestCaseEnabled) { fail("Not yet implemented"); } @@ -78,7 +78,7 @@ public class VideoCaptureTest extends OpenCVTestCase { } public void testIsOpened() { - if (!isEnabled) { + if (!isTestCaseEnabled) { fail("Not yet implemented"); } @@ -87,7 +87,7 @@ public class VideoCaptureTest extends OpenCVTestCase { } public void testIsOpenedRealCamera() { - if (!isEnabled) { + if (!isTestCaseEnabled) { fail("Not yet implemented"); } @@ -101,7 +101,7 @@ public class VideoCaptureTest extends OpenCVTestCase { } public void testOpen() { - if (!isEnabled) { + if (!isTestCaseEnabled) { fail("Not yet implemented"); } @@ -116,7 +116,7 @@ public class VideoCaptureTest extends OpenCVTestCase { } public void testRead() { - if (!isEnabled) { + if (!isTestCaseEnabled) { fail("Not yet implemented"); } @@ -132,7 +132,7 @@ public class VideoCaptureTest extends OpenCVTestCase { } public void testRelease() { - if (!isEnabled) { + if (!isTestCaseEnabled) { fail("Not yet implemented"); } @@ -147,7 +147,7 @@ public class VideoCaptureTest extends OpenCVTestCase { } public void testRetrieveMat() { - if (!isEnabled) { + if (!isTestCaseEnabled) { fail("Not yet implemented"); } @@ -164,7 +164,7 @@ public class VideoCaptureTest extends OpenCVTestCase { } public void testRetrieveMatInt() { - if (!isEnabled) { + if (!isTestCaseEnabled) { fail("Not yet implemented"); } @@ -181,7 +181,7 @@ public class VideoCaptureTest extends OpenCVTestCase { } public void testSet() { - if (!isEnabled) { + if (!isTestCaseEnabled) { fail("Not yet implemented"); } @@ -205,7 +205,7 @@ public class VideoCaptureTest extends OpenCVTestCase { } public void testVideoCaptureInt() { - if (!isEnabled) { + if (!isTestCaseEnabled) { fail("Not yet implemented"); } From 6fb959710dc5c22c852dcc9627f852a1088f1da3 Mon Sep 17 00:00:00 2001 From: Alexander Smorkalov Date: Mon, 12 Nov 2012 18:01:56 +0400 Subject: [PATCH 72/91] Code review comments applied. --- .../dev_with_OCV_on_Android.rst | 132 +++++++++--------- 1 file changed, 67 insertions(+), 65 deletions(-) diff --git a/doc/tutorials/introduction/android_binary_package/dev_with_OCV_on_Android.rst b/doc/tutorials/introduction/android_binary_package/dev_with_OCV_on_Android.rst index 52f739361..0943b043c 100644 --- a/doc/tutorials/introduction/android_binary_package/dev_with_OCV_on_Android.rst +++ b/doc/tutorials/introduction/android_binary_package/dev_with_OCV_on_Android.rst @@ -260,34 +260,35 @@ To build your own Android application, which uses OpenCV from native part, the f #. Either use :ref:`manual ` ``ndk-build`` invocation or :ref:`setup Eclipse CDT Builder ` to build native JNI lib before Java part [re]build and APK creation. -Hello OpenCV Sample -=================== +"Hello OpenCV" Sample +===================== -Here are basic steps to guide you trough the process of creating a simple OpenCV-centric application. +Here are basic steps to guide you trough the creation process of a simple OpenCV-centric application. It will be capable of accessing camera output, processing it and displaying the result. -#. Open Eclipse IDE, create a new clean workspace, create a new Android project (*File -> New -> Android Project*). +#. Open Eclipse IDE, create a new clean workspace, create a new Android project (:guilabel:`File -> New -> Android Project`). -#. Set name, target, package and minSDKVersion accordingly. +#. Set name, target, package and ``minSDKVersion`` accordingly. -#. Add the following permissions to the AndroidManifest.xml file: +#. Add the following permissions to the ``AndroidManifest.xml`` file: .. code-block:: xml :linenos: - + - - - + + + + -#. Reference OpenCV library within your project properties. +#. Reference the OpenCV library within your project properties. .. image:: images/dev_OCV_reference.png :alt: Reference OpenCV library. :align: center -#. Create new view layout for your application, lets name it hello_opencv.xml, and add the following to it: +#. Create new view layout for your application, lets name it ``hello_opencv.xml``, and add the following to it: .. code-block:: xml :linenos: @@ -307,70 +308,71 @@ It will be capable of accessing camera output, processing it and displaying the #. Remove default auto generated layout, if exists. -#. Create a new *Activity* (*New -> Other -> Android -> Android Activity*) and name it, for example: *HelloOpenCVActivity*. Add *CvCameraViewListener* interface to *implementes* section of *HelloOpenCVActivity* class. Add the following code to activity implementation: +#. Create a new ``Activity`` (:guilabel:`New -> Other -> Android -> Android Activity`) and name it, for example: ``HelloOpenCVActivity``. + Add ``CvCameraViewListener`` interface to ``implements`` list of ``HelloOpenCVActivity`` class. Add the following code to activity implementation: .. code-block:: java :linenos: - public class Sample1Java extends Activity implements CvCameraViewListener { - - private CameraBridgeViewBase mOpenCvCameraView; + public class Sample1Java extends Activity implements CvCameraViewListener { - private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) { + private CameraBridgeViewBase mOpenCvCameraView; + + private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) { + @Override + public void onManagerConnected(int status) { + switch (status) { + case LoaderCallbackInterface.SUCCESS: { + Log.i(TAG, "OpenCV loaded successfully"); + mOpenCvCameraView.enableView(); + } break; + default: + super.onManagerConnected(status); + } + } + }; + + /** Called when the activity is first created. */ @Override - public void onManagerConnected(int status) { - switch (status) { - case LoaderCallbackInterface.SUCCESS: { - Log.i(TAG, "OpenCV loaded successfully"); - mOpenCvCameraView.enableView(); - } break; - default: - super.onManagerConnected(status); - } + public void onCreate(Bundle savedInstanceState) { + Log.i(TAG, "called onCreate"); + super.onCreate(savedInstanceState); + requestWindowFeature(Window.FEATURE_NO_TITLE); + getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + setContentView(R.layout.hello_opencv); + mOpenCvCameraView = (CameraBridgeViewBase) findViewById(R.id.java_surface_view); + mOpenCvCameraView.setVisibility(SurfaceView.VISIBLE); + mOpenCvCameraView.setCvCameraViewListener(this); } - }; - /** Called when the activity is first created. */ - @Override - public void onCreate(Bundle savedInstanceState) { - Log.i(TAG, "called onCreate"); - super.onCreate(savedInstanceState); - requestWindowFeature(Window.FEATURE_NO_TITLE); - getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); - setContentView(R.layout.hello_opencv); - mOpenCvCameraView = (CameraBridgeViewBase) findViewById(R.id.java_surface_view); - mOpenCvCameraView.setVisibility(SurfaceView.VISIBLE); - mOpenCvCameraView.setCvCameraViewListener(this); - } + @Override + public void onPause() + { + if (mOpenCvCameraView != null) + mOpenCvCameraView.disableView(); + super.onPause(); + } - @Override - public void onPause() - { - if (mOpenCvCameraView != null) - mOpenCvCameraView.disableView(); - super.onPause(); - } + @Override + public void onResume() + { + super.onResume(); + OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_3, this, mLoaderCallback); + } - @Override - public void onResume() - { - super.onResume(); - OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_3, this, mLoaderCallback); - } + public void onDestroy() { + super.onDestroy(); + if (mOpenCvCameraView != null) + mOpenCvCameraView.disableView(); + } - public void onDestroy() { - super.onDestroy(); - if (mOpenCvCameraView != null) - mOpenCvCameraView.disableView(); - } + public void onCameraViewStarted(int width, int height) { + } - public void onCameraViewStarted(int width, int height) { - } + public void onCameraViewStopped() { + } - public void onCameraViewStopped() { + public Mat onCameraFrame(Mat inputFrame) { + return inputFrame; + } } - - public Mat onCameraFrame(Mat inputFrame) { - return inputFrame; - } - } From bd9ca48fabd2bc03be2cd3aba6c635d830fb5b0f Mon Sep 17 00:00:00 2001 From: "marina.kolpakova" Date: Tue, 13 Nov 2012 02:49:35 +0400 Subject: [PATCH 73/91] export to python/java --- modules/objdetect/doc/soft_cascade.rst | 11 ++- .../include/opencv2/objdetect/objdetect.hpp | 13 ++-- modules/objdetect/src/softcascade.cpp | 23 +++++++ modules/objdetect/test/test_softcascade.cpp | 67 +++++-------------- 4 files changed, 57 insertions(+), 57 deletions(-) diff --git a/modules/objdetect/doc/soft_cascade.rst b/modules/objdetect/doc/soft_cascade.rst index 0ba756601..ac537b3a8 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 98c4f0a79..a78bef56f 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 bfda83426..e3bcdfe67 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 d33d5892b..b5632400a 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); } From 9f5fcff3ea86e2cd4f70c786c387ca58c3d2346f Mon Sep 17 00:00:00 2001 From: Alexander Smorkalov Date: Tue, 13 Nov 2012 10:29:49 +0400 Subject: [PATCH 74/91] More common way of test case disabling implemented. --- .../src/org/opencv/test/OpenCVTestCase.java | 8 +++ .../opencv/test/highgui/VideoCaptureTest.java | 52 ------------------- 2 files changed, 8 insertions(+), 52 deletions(-) diff --git a/modules/java/android_test/src/org/opencv/test/OpenCVTestCase.java b/modules/java/android_test/src/org/opencv/test/OpenCVTestCase.java index 6acf0b34d..71e82841a 100644 --- a/modules/java/android_test/src/org/opencv/test/OpenCVTestCase.java +++ b/modules/java/android_test/src/org/opencv/test/OpenCVTestCase.java @@ -175,6 +175,14 @@ public class OpenCVTestCase extends TestCase { super.tearDown(); } + @Override + protected void runTest() throws Throwable { + // Do nothing if the precondition does not hold. + if (isTestCaseEnabled) { + super.runTest(); + } + } + protected Mat getMat(int type, double... vals) { return new Mat(matSize, matSize, type, new Scalar(vals)); diff --git a/modules/java/android_test/src/org/opencv/test/highgui/VideoCaptureTest.java b/modules/java/android_test/src/org/opencv/test/highgui/VideoCaptureTest.java index 903768f7b..ec7211a29 100644 --- a/modules/java/android_test/src/org/opencv/test/highgui/VideoCaptureTest.java +++ b/modules/java/android_test/src/org/opencv/test/highgui/VideoCaptureTest.java @@ -25,10 +25,6 @@ public class VideoCaptureTest extends OpenCVTestCase { } public void testGet() { - if (!isTestCaseEnabled) { - fail("Not yet implemented"); - } - try { capture = new VideoCapture(Highgui.CV_CAP_ANDROID); double frameWidth = capture.get(Highgui.CV_CAP_PROP_FRAME_WIDTH); @@ -39,10 +35,6 @@ public class VideoCaptureTest extends OpenCVTestCase { } public void testGetSupportedPreviewSizes() { - if (!isTestCaseEnabled) { - fail("Not yet implemented"); - } - try { capture = new VideoCapture(Highgui.CV_CAP_ANDROID); List sizes = capture.getSupportedPreviewSizes(); @@ -54,20 +46,12 @@ public class VideoCaptureTest extends OpenCVTestCase { } public void testGrab() { - if (!isTestCaseEnabled) { - fail("Not yet implemented"); - } - capture = new VideoCapture(); isSucceed = capture.grab(); assertFalse(isSucceed); } public void testGrabFromRealCamera() { - if (!isTestCaseEnabled) { - fail("Not yet implemented"); - } - try { capture = new VideoCapture(Highgui.CV_CAP_ANDROID); isSucceed = capture.grab(); @@ -78,19 +62,11 @@ public class VideoCaptureTest extends OpenCVTestCase { } public void testIsOpened() { - if (!isTestCaseEnabled) { - fail("Not yet implemented"); - } - capture = new VideoCapture(); assertFalse(capture.isOpened()); } public void testIsOpenedRealCamera() { - if (!isTestCaseEnabled) { - fail("Not yet implemented"); - } - try { capture = new VideoCapture(Highgui.CV_CAP_ANDROID); isOpened = capture.isOpened(); @@ -101,10 +77,6 @@ public class VideoCaptureTest extends OpenCVTestCase { } public void testOpen() { - if (!isTestCaseEnabled) { - fail("Not yet implemented"); - } - try { capture = new VideoCapture(); capture.open(Highgui.CV_CAP_ANDROID); @@ -116,10 +88,6 @@ public class VideoCaptureTest extends OpenCVTestCase { } public void testRead() { - if (!isTestCaseEnabled) { - fail("Not yet implemented"); - } - try { capture = new VideoCapture(Highgui.CV_CAP_ANDROID); isSucceed = capture.read(dst); @@ -132,10 +100,6 @@ public class VideoCaptureTest extends OpenCVTestCase { } public void testRelease() { - if (!isTestCaseEnabled) { - fail("Not yet implemented"); - } - try { capture = new VideoCapture(Highgui.CV_CAP_ANDROID); capture.release(); @@ -147,10 +111,6 @@ public class VideoCaptureTest extends OpenCVTestCase { } public void testRetrieveMat() { - if (!isTestCaseEnabled) { - fail("Not yet implemented"); - } - try { capture = new VideoCapture(Highgui.CV_CAP_ANDROID); capture.grab(); @@ -164,10 +124,6 @@ public class VideoCaptureTest extends OpenCVTestCase { } public void testRetrieveMatInt() { - if (!isTestCaseEnabled) { - fail("Not yet implemented"); - } - try { capture = new VideoCapture(Highgui.CV_CAP_ANDROID); capture.grab(); @@ -181,10 +137,6 @@ public class VideoCaptureTest extends OpenCVTestCase { } public void testSet() { - if (!isTestCaseEnabled) { - fail("Not yet implemented"); - } - try { capture = new VideoCapture(Highgui.CV_CAP_ANDROID); capture.set(Highgui.CV_CAP_PROP_FRAME_WIDTH, 640); @@ -205,10 +157,6 @@ public class VideoCaptureTest extends OpenCVTestCase { } public void testVideoCaptureInt() { - if (!isTestCaseEnabled) { - fail("Not yet implemented"); - } - try { capture = new VideoCapture(Highgui.CV_CAP_ANDROID); assertNotNull(capture); From 96e4eed018bf6b287927c9576e393bda83899b0f Mon Sep 17 00:00:00 2001 From: Alexander Smorkalov Date: Tue, 13 Nov 2012 11:41:08 +0400 Subject: [PATCH 75/91] Logcat message for disabled test cases added. --- .../android_test/src/org/opencv/test/OpenCVTestCase.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/modules/java/android_test/src/org/opencv/test/OpenCVTestCase.java b/modules/java/android_test/src/org/opencv/test/OpenCVTestCase.java index 71e82841a..b24d858ee 100644 --- a/modules/java/android_test/src/org/opencv/test/OpenCVTestCase.java +++ b/modules/java/android_test/src/org/opencv/test/OpenCVTestCase.java @@ -23,8 +23,9 @@ import org.opencv.features2d.DMatch; import org.opencv.features2d.KeyPoint; import org.opencv.highgui.Highgui; -public class OpenCVTestCase extends TestCase { +import android.util.Log; +public class OpenCVTestCase extends TestCase { //change to 'true' to unblock fail on fail("Not yet implemented") public static final boolean passNYI = true; @@ -34,6 +35,8 @@ public class OpenCVTestCase extends TestCase { protected static final double EPS = 0.001; protected static final double weakEPS = 0.5; + private static final String TAG = "OpenCVTestCase"; + protected Mat dst; protected Mat truth; @@ -180,6 +183,8 @@ public class OpenCVTestCase extends TestCase { // Do nothing if the precondition does not hold. if (isTestCaseEnabled) { super.runTest(); + } else { + Log.e(TAG, "Test case \"" + this.getClass().getName() + "\" disabled!"); } } From 606c23b9aad5551d90075cfdbb3b3f9f0556709c Mon Sep 17 00:00:00 2001 From: Vladislav Vinogradov Date: Tue, 13 Nov 2012 17:50:29 +0400 Subject: [PATCH 76/91] fixed gpu module tests uses old CommandLineParser class --- modules/gpu/test/main.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/gpu/test/main.cpp b/modules/gpu/test/main.cpp index cd5bbda35..63f891a19 100644 --- a/modules/gpu/test/main.cpp +++ b/modules/gpu/test/main.cpp @@ -119,10 +119,10 @@ int main(int argc, char** argv) try { const char* keys = - "{ h help ? | | Print help}" - "{ i info | | Print information about system and exit }" - "{ device | -1 | Device on which tests will be executed (-1 means all devices) }" - "{ nvtest_output_level | none | NVidia test verbosity level (none, compact, full) }" + "{ h | help ? | false | Print help}" + "{ i | info | false | Print information about system and exit }" + "{ d | device | -1 | Device on which tests will be executed (-1 means all devices) }" + "{ nvtest_output_level | nvtest_output_level | none | NVidia test verbosity level (none, compact, full) }" ; CommandLineParser cmd(argc, (const char**)argv, keys); From a9919e01d0c857a568b6fa46fb3a878f6e6e83e1 Mon Sep 17 00:00:00 2001 From: Vladislav Vinogradov Date: Tue, 13 Nov 2012 17:54:17 +0400 Subject: [PATCH 77/91] fixed bug in gpu::HoughLines --- modules/gpu/src/cuda/hough.cu | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/gpu/src/cuda/hough.cu b/modules/gpu/src/cuda/hough.cu index ac65b360a..ee4d02591 100644 --- a/modules/gpu/src/cuda/hough.cu +++ b/modules/gpu/src/cuda/hough.cu @@ -236,7 +236,7 @@ namespace cv { namespace gpu { namespace device const int r = blockIdx.x * blockDim.x + threadIdx.x; const int n = blockIdx.y * blockDim.y + threadIdx.y; - if (r >= accum.cols - 2 && n >= accum.rows - 2) + if (r >= accum.cols - 2 || n >= accum.rows - 2) return; const int curVotes = accum(n + 1, r + 1); From 1edab12068fe04c87fee7cfbc976c0bbe0bfad3f Mon Sep 17 00:00:00 2001 From: "marina.kolpakova" Date: Tue, 13 Nov 2012 23:08:19 +0400 Subject: [PATCH 78/91] fix for negative confidence --- modules/objdetect/src/softcascade.cpp | 5 +++-- modules/objdetect/test/test_softcascade.cpp | 8 ++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/modules/objdetect/src/softcascade.cpp b/modules/objdetect/src/softcascade.cpp index e3bcdfe67..8f37c1be1 100644 --- a/modules/objdetect/src/softcascade.cpp +++ b/modules/objdetect/src/softcascade.cpp @@ -232,7 +232,7 @@ struct cv::SCascade::Fields float detectionScore = 0.f; const Octave& octave = *(level.octave); - int stBegin = octave.index * octave.stages, stEnd = stBegin + 1024;//octave.stages; + int stBegin = octave.index * octave.stages, stEnd = stBegin + octave.stages; int st = stBegin; for(; st < stEnd; ++st) @@ -270,7 +270,8 @@ struct cv::SCascade::Fields if (detectionScore <= stage.threshold) return; } - level.addDetection(dx, dy, detectionScore, detections); + if (detectionScore > 0) + level.addDetection(dx, dy, detectionScore, detections); } octIt_t fitOctave(const float& logFactor) diff --git a/modules/objdetect/test/test_softcascade.cpp b/modules/objdetect/test/test_softcascade.cpp index b5632400a..f9141c2a9 100644 --- a/modules/objdetect/test/test_softcascade.cpp +++ b/modules/objdetect/test/test_softcascade.cpp @@ -66,7 +66,7 @@ TEST(SCascade, detect) std::vector objects; cascade.detect(colored, cv::noArray(), objects); - ASSERT_EQ((int)objects.size(), 3498); + ASSERT_EQ(1459, (int)objects.size()); } TEST(SCascade, detectSeparate) @@ -83,7 +83,7 @@ TEST(SCascade, detectSeparate) cv::Mat rects, confs; cascade.detect(colored, cv::noArray(), rects, confs); - ASSERT_EQ(confs.cols, 3498); + ASSERT_EQ(1459, confs.cols); } TEST(SCascade, detectRoi) @@ -102,7 +102,7 @@ TEST(SCascade, detectRoi) rois.push_back(cv::Rect(0, 0, 640, 480)); cascade.detect(colored, rois, objects); - ASSERT_EQ((int)objects.size(), 3498); + ASSERT_EQ(1459, (int)objects.size()); } TEST(SCascade, detectNoRoi) @@ -121,5 +121,5 @@ TEST(SCascade, detectNoRoi) cascade.detect(colored, rois, objects); - ASSERT_EQ((int)objects.size(), 0); + ASSERT_EQ(0, (int)objects.size()); } \ No newline at end of file From 9cfa51a4831068c741c312956071f5ce2e5eb06c Mon Sep 17 00:00:00 2001 From: Alexander Mordvintsev Date: Mon, 12 Nov 2012 14:42:51 +0400 Subject: [PATCH 79/91] added CV_OUT to StereoVar output paramiter --- modules/contrib/include/opencv2/contrib/contrib.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/contrib/include/opencv2/contrib/contrib.hpp b/modules/contrib/include/opencv2/contrib/contrib.hpp index 1b13fd7f3..0085b0dfe 100644 --- a/modules/contrib/include/opencv2/contrib/contrib.hpp +++ b/modules/contrib/include/opencv2/contrib/contrib.hpp @@ -583,7 +583,7 @@ namespace cv virtual ~StereoVar(); //! the stereo correspondence operator that computes disparity map for the specified rectified stereo pair - CV_WRAP_AS(compute) virtual void operator()(const Mat& left, const Mat& right, Mat& disp); + CV_WRAP_AS(compute) virtual void operator()(const Mat& left, const Mat& right, CV_OUT Mat& disp); CV_PROP_RW int levels; CV_PROP_RW double pyrScale; From e3c93ad9cfc2a8c5f5bdc5a464885dd24073080f Mon Sep 17 00:00:00 2001 From: "marina.kolpakova" Date: Tue, 13 Nov 2012 23:52:18 +0400 Subject: [PATCH 80/91] Revert "Merge pull request #141 from jet47/gpu-pyrlk-fix" because this bug appears only in 2.4 This reverts commit 7e301c5c0e0591a751258d044f5f2f0889231591, reversing changes made to b5e009eb87154b830759fe9276b6233f852a4e77. --- modules/gpu/src/pyrlk.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/modules/gpu/src/pyrlk.cpp b/modules/gpu/src/pyrlk.cpp index a513dded8..47ab90415 100644 --- a/modules/gpu/src/pyrlk.cpp +++ b/modules/gpu/src/pyrlk.cpp @@ -211,9 +211,6 @@ void cv::gpu::PyrLKOpticalFlow::dense(const GpuMat& prevImg, const GpuMat& nextI pyrDown(nextPyr_[level - 1], nextPyr_[level]); } - uPyr_.resize(2); - vPyr_.resize(2); - ensureSizeIsEnough(prevImg.size(), CV_32FC1, uPyr_[0]); ensureSizeIsEnough(prevImg.size(), CV_32FC1, vPyr_[0]); ensureSizeIsEnough(prevImg.size(), CV_32FC1, uPyr_[1]); From 52a136227d0eb2a23ecf2e81defcd31a67629004 Mon Sep 17 00:00:00 2001 From: LeonidBeynenson Date: Wed, 14 Nov 2012 14:27:41 +0400 Subject: [PATCH 81/91] Modified documentation for calcOpticalFlowSF. --- .../doc/motion_analysis_and_object_tracking.rst | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/modules/video/doc/motion_analysis_and_object_tracking.rst b/modules/video/doc/motion_analysis_and_object_tracking.rst index 3b1662c84..873e7fdc4 100644 --- a/modules/video/doc/motion_analysis_and_object_tracking.rst +++ b/modules/video/doc/motion_analysis_and_object_tracking.rst @@ -601,17 +601,15 @@ calcOpticalFlowSF ----------------- Calculate an optical flow using "SimpleFlow" algorithm. -.. ocv:function:: void calcOpticalFlowSF( Mat& from, Mat& to, Mat& flow, int layers, int averaging_block_size, int max_flow ) +.. ocv:function:: void calcOpticalFlowSF( InputArray from, InputArray to, OutputArray flow, int layers, int averaging_block_size, int max_flow ) -.. ocv:function:: calcOpticalFlowSF( Mat& from, Mat& to, Mat& flow, int layers, int averaging_block_size, int max_flow, double sigma_dist, double sigma_color, int postprocess_window, double sigma_dist_fix, double sigma_color_fix, double occ_thr, int upscale_averaging_radius, double upscale_sigma_dist, double upscale_sigma_color, double speed_up_thr ) +.. ocv:function:: calcOpticalFlowSF( InputArray from, InputArray to, OutputArray flow, int layers, int averaging_block_size, int max_flow, double sigma_dist, double sigma_color, int postprocess_window, double sigma_dist_fix, double sigma_color_fix, double occ_thr, int upscale_averaging_radius, double upscale_sigma_dist, double upscale_sigma_color, double speed_up_thr ) :param prev: First 8-bit 3-channel image. - :param next: Second 8-bit 3-channel image + :param next: Second 8-bit 3-channel image of the same size as ``prev`` - :param flowX: X-coordinate of estimated flow - - :param flowY: Y-coordinate of estimated flow + :param flow: computed flow image that has the same size as ``prev`` and type ``CV_32FC2`` :param layers: Number of layers @@ -631,7 +629,7 @@ Calculate an optical flow using "SimpleFlow" algorithm. :param occ_thr: threshold for detecting occlusions - :param upscale_averaging_radiud: window size for bilateral upscale operation + :param upscale_averaging_radius: window size for bilateral upscale operation :param upscale_sigma_dist: spatial sigma for bilateral upscale operation From 1e0bff3268af9c03addf60f8dee33064e7122194 Mon Sep 17 00:00:00 2001 From: Alexander Smorkalov Date: Thu, 15 Nov 2012 11:24:41 +0400 Subject: [PATCH 82/91] Issue #2541 make install does not work for Android build fixed. --- android/libinfo/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/android/libinfo/CMakeLists.txt b/android/libinfo/CMakeLists.txt index f8e8e15af..028413ec6 100644 --- a/android/libinfo/CMakeLists.txt +++ b/android/libinfo/CMakeLists.txt @@ -35,5 +35,5 @@ set_target_properties(${the_module} PROPERTIES INSTALL_NAME_DIR lib ) -get_filename_component(lib_name "opencv_info" NAME) -install(FILES "${LIBRARY_OUTPUT_PATH}/${lib_name}" DESTINATION ${OPENCV_LIB_INSTALL_PATH} COMPONENT main) \ No newline at end of file +get_filename_component(lib_name "libopencv_info.so" NAME) +install(FILES "${LIBRARY_OUTPUT_PATH}/${lib_name}" DESTINATION ${OPENCV_LIB_INSTALL_PATH} COMPONENT main) From 759863d95cc9ac0f45e5692e7a0a07258f9412d0 Mon Sep 17 00:00:00 2001 From: Alexander Smorkalov Date: Fri, 16 Nov 2012 17:01:25 +0400 Subject: [PATCH 83/91] Issue #2537 OpenCV Manager doesn't work on Android 4.2 fixed. --- android/scripts/cmake_android_service.sh | 2 +- android/service/engine/AndroidManifest.xml | 4 ++-- android/service/engine/jni/Android.mk | 5 ++--- android/service/engine/jni/Application.mk | 1 + android/service/engine/jni/Tests/Tests.mk | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/android/scripts/cmake_android_service.sh b/android/scripts/cmake_android_service.sh index 3503bb73d..e0d1222cd 100755 --- a/android/scripts/cmake_android_service.sh +++ b/android/scripts/cmake_android_service.sh @@ -4,5 +4,5 @@ cd `dirname $0`/.. mkdir -p build_service cd build_service -cmake -DCMAKE_TOOLCHAIN_FILE=../android.toolchain.cmake -DANDROID_STL=stlport_static -DANDROID_STL_FORCE_FEATURES=OFF -DBUILD_ANDROID_SERVICE=ON -DANDROID_SOURCE_TREE=~/Projects/AndroidSource/ServiceStub/ $@ ../.. +cmake -DCMAKE_TOOLCHAIN_FILE=../android.toolchain.cmake -DANDROID_TOOLCHAIN_NAME="arm-linux-androideabi-4.4.3" -DANDROID_STL=stlport_static -DANDROID_STL_FORCE_FEATURES=OFF -DBUILD_ANDROID_SERVICE=ON -DANDROID_SOURCE_TREE=~/Projects/AndroidSource/ServiceStub/ $@ ../.. diff --git a/android/service/engine/AndroidManifest.xml b/android/service/engine/AndroidManifest.xml index b1d6f691c..1e0652494 100644 --- a/android/service/engine/AndroidManifest.xml +++ b/android/service/engine/AndroidManifest.xml @@ -1,8 +1,8 @@ + android:versionCode="21" + android:versionName="2.1" > diff --git a/android/service/engine/jni/Android.mk b/android/service/engine/jni/Android.mk index a33466c5c..9ab92a208 100644 --- a/android/service/engine/jni/Android.mk +++ b/android/service/engine/jni/Android.mk @@ -35,7 +35,7 @@ LOCAL_MODULE := libOpenCVEngine LOCAL_LDLIBS += -lz -lbinder -llog -lutils -LOCAL_LDFLAGS += -Wl,-allow-shlib-undefine +LOCAL_LDFLAGS += -Wl,-allow-shlib-undefined include $(BUILD_SHARED_LIBRARY) @@ -74,7 +74,6 @@ LOCAL_CFLAGS += -D__SUPPORT_MIPS LOCAL_MODULE := libOpenCVEngine_jni LOCAL_LDLIBS += -lz -lbinder -llog -lutils -landroid_runtime - LOCAL_SHARED_LIBRARIES = libOpenCVEngine include $(BUILD_SHARED_LIBRARY) @@ -83,4 +82,4 @@ include $(BUILD_SHARED_LIBRARY) # Native test application #--------------------------------------------------------------------- -include $(LOCAL_PATH)/Tests/Tests.mk \ No newline at end of file +#include $(LOCAL_PATH)/Tests/Tests.mk \ No newline at end of file diff --git a/android/service/engine/jni/Application.mk b/android/service/engine/jni/Application.mk index 4230cd26e..5647110fa 100644 --- a/android/service/engine/jni/Application.mk +++ b/android/service/engine/jni/Application.mk @@ -2,4 +2,5 @@ APP_ABI := armeabi x86 mips APP_PLATFORM := android-8 APP_STL := stlport_static APP_CPPFLAGS := -fno-rtti -fno-exceptions +NDK_TOOLCHAIN_VERSION=4.4.3 #APP_OPTIM := debug \ No newline at end of file diff --git a/android/service/engine/jni/Tests/Tests.mk b/android/service/engine/jni/Tests/Tests.mk index a436bc209..4cfe1c16a 100644 --- a/android/service/engine/jni/Tests/Tests.mk +++ b/android/service/engine/jni/Tests/Tests.mk @@ -36,7 +36,7 @@ LOCAL_CFLAGS += -D__SUPPORT_TEGRA3 LOCAL_CFLAGS += -D__SUPPORT_MIPS #LOCAL_CFLAGS += -D__SUPPORT_ARMEABI_FEATURES -LOCAL_LDFLAGS = -Wl,-allow-shlib-undefined +#LOCAL_LDFLAGS = -Wl,-allow-shlib-undefined LOCAL_MODULE := OpenCVEngineTestApp From 9ca1162be822f4a62d9ff984bb546d0cb389ffd7 Mon Sep 17 00:00:00 2001 From: Andrey Kamaev Date: Mon, 19 Nov 2012 11:43:28 +0400 Subject: [PATCH 84/91] Update URL for TBB download. Update to TBB 4.1 update 1 --- 3rdparty/tbb/CMakeLists.txt | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/3rdparty/tbb/CMakeLists.txt b/3rdparty/tbb/CMakeLists.txt index bf91f4d8b..1d4748d38 100644 --- a/3rdparty/tbb/CMakeLists.txt +++ b/3rdparty/tbb/CMakeLists.txt @@ -5,40 +5,46 @@ endif() project(tbb) -# 4.1 - works fine -set(tbb_ver "tbb41_20120718oss") -set(tbb_url "http://threadingbuildingblocks.org/uploads/77/188/4.1/tbb41_20120718oss_src.tgz") -set(tbb_md5 "31b9ec300f3d09da2504d5d882788dd4") +# 4.1 update 1 - works fine +set(tbb_ver "tbb41_20121003oss") +set(tbb_url "http://threadingbuildingblocks.org/sites/default/files/software_releases/source/tbb41_20121003oss_src.tgz") +set(tbb_md5 "2a684fefb855d2d0318d1ef09afa75ff") set(tbb_version_file "version_string.ver") +# 4.1 - works fine +#set(tbb_ver "tbb41_20120718oss") +#set(tbb_url "http://threadingbuildingblocks.org/sites/default/files/software_releases/source/tbb41_20120718oss_src.tgz") +#set(tbb_md5 "31b9ec300f3d09da2504d5d882788dd4") +#set(tbb_version_file "version_string.ver") + # 4.0 update 5 - works fine #set(tbb_ver "tbb40_20120613oss") -#set(tbb_url "http://threadingbuildingblocks.org/uploads/77/187/4.0%20update%205/tbb40_20120613oss_src.tgz") +#set(tbb_url "http://threadingbuildingblocks.org/sites/default/files/software_releases/source/tbb40_20120613oss_src.tgz") #set(tbb_md5 "da01ed74944ec5950cfae3476901a172") #set(tbb_version_file "version_string.ver") # 4.0 update 4 - works fine #set(tbb_ver "tbb40_20120408oss") -#set(tbb_url "http://threadingbuildingblocks.org/uploads/77/185/4.0%20update%204/tbb40_20120408oss_src.tgz") +#set(tbb_url "http://threadingbuildingblocks.org/sites/default/files/software_releases/source/tbb40_20120408oss_src.tgz") #set(tbb_md5 "734b356da7fe0ed308741f3e6018251e") #set(tbb_version_file "version_string.ver") # 4.0 update 3 - build broken #set(tbb_ver "tbb40_20120201oss") -#set(tbb_url "http://threadingbuildingblocks.org/uploads/77/182/4.0%20update%203/tbb40_20120201oss_src.tgz") +#set(tbb_url "http://threadingbuildingblocks.org/sites/default/files/software_releases/source/tbb40_20120201oss_src.tgz") #set(tbb_md5 "4669e7d4adee018de7a7b8b972987218") #set(tbb_version_file "version_string.tmp") # 4.0 update 2 - works fine #set(tbb_ver "tbb40_20111130oss") -#set(tbb_url "http://threadingbuildingblocks.org/uploads/77/180/4.0%20update%202/tbb40_20111130oss_src.tgz") +#set(tbb_url "http://threadingbuildingblocks.org/sites/default/files/software_releases/source/tbb40_20111130oss_src.tgz") #set(tbb_md5 "1e6926b21e865e79772119cd44fc3ad8") #set(tbb_version_file "version_string.tmp") #set(tbb_need_GENERIC_DWORD_LOAD_STORE TRUE) # 4.0 update 1 - works fine #set(tbb_ver "tbb40_20111003oss") -#set(tbb_url "http://threadingbuildingblocks.org/uploads/77/177/4.0%20update%201/tbb40_20111003oss_src.tgz") +#set(tbb_url "http://threadingbuildingblocks.org/sites/default/files/software_releases/source/tbb40_20111003oss_src.tgz") #set(tbb_md5 "7b5d94eb35a563b29ef402e0fd8f15c9") #set(tbb_version_file "version_string.tmp") #set(tbb_need_GENERIC_DWORD_LOAD_STORE TRUE) From 1f1d43fc88e97f10449fd2cfcbe761aa9c174eb4 Mon Sep 17 00:00:00 2001 From: Alexander Smorkalov Date: Mon, 19 Nov 2012 12:58:17 +0400 Subject: [PATCH 85/91] Issue #2548 Missing static library libtbb.a for armeabi and mips build fixed. --- cmake/OpenCVGenAndroidMK.cmake | 6 ++++++ cmake/templates/OpenCV.mk.in | 18 ++++++++++++++++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/cmake/OpenCVGenAndroidMK.cmake b/cmake/OpenCVGenAndroidMK.cmake index 04ebdb759..5b11afc17 100644 --- a/cmake/OpenCVGenAndroidMK.cmake +++ b/cmake/OpenCVGenAndroidMK.cmake @@ -71,6 +71,12 @@ if(ANDROID) endforeach() string(REPLACE "opencv_" "" OPENCV_MODULES_CONFIGMAKE "${OPENCV_MODULES_CONFIGMAKE}") + # prepare 3rd-party component list without TBB for armeabi and mips platforms. TBB is useless there. + set(OPENCV_3RDPARTY_COMPONENTS_CONFIGMAKE_NO_TBB ${OPENCV_3RDPARTY_COMPONENTS_CONFIGMAKE}) + foreach(mod ${OPENCV_3RDPARTY_COMPONENTS_CONFIGMAKE_NO_TBB}) + string(REPLACE "tbb" "" OPENCV_3RDPARTY_COMPONENTS_CONFIGMAKE_NO_TBB "${OPENCV_3RDPARTY_COMPONENTS_CONFIGMAKE_NO_TBB}") + endforeach() + if(BUILD_FAT_JAVA_LIB) set(OPENCV_LIBS_CONFIGMAKE java) else() diff --git a/cmake/templates/OpenCV.mk.in b/cmake/templates/OpenCV.mk.in index 32ab27fb6..d52f75b91 100644 --- a/cmake/templates/OpenCV.mk.in +++ b/cmake/templates/OpenCV.mk.in @@ -29,8 +29,22 @@ ifeq ($(OPENCV_LIB_TYPE),SHARED) OPENCV_3RDPARTY_COMPONENTS:= OPENCV_EXTRA_COMPONENTS:= else - OPENCV_3RDPARTY_COMPONENTS:=@OPENCV_3RDPARTY_COMPONENTS_CONFIGMAKE@ - OPENCV_EXTRA_COMPONENTS:=@OPENCV_EXTRA_COMPONENTS_CONFIGMAKE@ + ifeq ($(TARGET_ARCH_ABI),armeabi-v7a) + OPENCV_3RDPARTY_COMPONENTS:=@OPENCV_3RDPARTY_COMPONENTS_CONFIGMAKE@ + OPENCV_EXTRA_COMPONENTS:=@OPENCV_EXTRA_COMPONENTS_CONFIGMAKE@ + endif + ifeq ($(TARGET_ARCH_ABI),x86) + OPENCV_3RDPARTY_COMPONENTS:=@OPENCV_3RDPARTY_COMPONENTS_CONFIGMAKE@ + OPENCV_EXTRA_COMPONENTS:=@OPENCV_EXTRA_COMPONENTS_CONFIGMAKE@ + endif + ifeq ($(TARGET_ARCH_ABI),armeabi) + OPENCV_3RDPARTY_COMPONENTS:=@OPENCV_3RDPARTY_COMPONENTS_CONFIGMAKE_NO_TBB@ + OPENCV_EXTRA_COMPONENTS:=@OPENCV_EXTRA_COMPONENTS_CONFIGMAKE@ + endif + ifeq ($(TARGET_ARCH_ABI),mips) + OPENCV_3RDPARTY_COMPONENTS:=@OPENCV_3RDPARTY_COMPONENTS_CONFIGMAKE_NO_TBB@ + OPENCV_EXTRA_COMPONENTS:=@OPENCV_EXTRA_COMPONENTS_CONFIGMAKE@ + endif endif ifeq (${OPENCV_CAMERA_MODULES},on) From 66a1ea7604d0043343eba3feecfe9b2ccd027e13 Mon Sep 17 00:00:00 2001 From: Alexander Smorkalov Date: Tue, 20 Nov 2012 10:45:46 +0400 Subject: [PATCH 86/91] Test execution inside Eclipse fixed; OpenCV testing via OpenCV Manager implemented. --- .../src/org/opencv/test/OpenCVTestCase.java | 17 +++++- .../src/org/opencv/test/OpenCVTestRunner.java | 59 ++++++++++++++----- .../opencv/test/highgui/VideoCaptureTest.java | 31 ++++------ 3 files changed, 70 insertions(+), 37 deletions(-) diff --git a/modules/java/android_test/src/org/opencv/test/OpenCVTestCase.java b/modules/java/android_test/src/org/opencv/test/OpenCVTestCase.java index 102adf195..b24d858ee 100644 --- a/modules/java/android_test/src/org/opencv/test/OpenCVTestCase.java +++ b/modules/java/android_test/src/org/opencv/test/OpenCVTestCase.java @@ -23,15 +23,20 @@ import org.opencv.features2d.DMatch; import org.opencv.features2d.KeyPoint; import org.opencv.highgui.Highgui; -public class OpenCVTestCase extends TestCase { +import android.util.Log; +public class OpenCVTestCase extends TestCase { //change to 'true' to unblock fail on fail("Not yet implemented") public static final boolean passNYI = true; + protected static boolean isTestCaseEnabled = true; + protected static final int matSize = 10; protected static final double EPS = 0.001; protected static final double weakEPS = 0.5; + private static final String TAG = "OpenCVTestCase"; + protected Mat dst; protected Mat truth; @@ -173,6 +178,16 @@ public class OpenCVTestCase extends TestCase { super.tearDown(); } + @Override + protected void runTest() throws Throwable { + // Do nothing if the precondition does not hold. + if (isTestCaseEnabled) { + super.runTest(); + } else { + Log.e(TAG, "Test case \"" + this.getClass().getName() + "\" disabled!"); + } + } + protected Mat getMat(int type, double... vals) { return new Mat(matSize, matSize, type, new Scalar(vals)); diff --git a/modules/java/android_test/src/org/opencv/test/OpenCVTestRunner.java b/modules/java/android_test/src/org/opencv/test/OpenCVTestRunner.java index 3c416c510..2dc4aead8 100644 --- a/modules/java/android_test/src/org/opencv/test/OpenCVTestRunner.java +++ b/modules/java/android_test/src/org/opencv/test/OpenCVTestRunner.java @@ -2,11 +2,11 @@ package org.opencv.test; import java.io.File; import java.io.IOException; -import java.util.Iterator; - -import junit.framework.TestCase; import junit.framework.Assert; +import org.opencv.android.BaseLoaderCallback; +import org.opencv.android.LoaderCallbackInterface; +import org.opencv.android.OpenCVLoader; import org.opencv.android.Utils; import org.opencv.core.Mat; @@ -23,8 +23,7 @@ import android.util.Log; public class OpenCVTestRunner extends InstrumentationTestRunner { - static { System.loadLibrary("opencv_java"); } - + private static final long MANAGER_TIMEOUT = 3000; public static String LENA_PATH; public static String CHESS_PATH; public static String LBPCASCADE_FRONTALFACE_PATH; @@ -33,6 +32,26 @@ public class OpenCVTestRunner extends InstrumentationTestRunner { private AndroidTestRunner androidTestRunner; private static String TAG = "opencv_test_java"; + private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(getContext()) { + + @Override + public void onManagerConnected(int status) { + switch (status) { + case LoaderCallbackInterface.SUCCESS: + { + Log("OpenCV loaded successfully"); + synchronized (this) { + notify(); + } + } break; + default: + { + super.onManagerConnected(status); + } break; + } + } + }; + public static String getTempFileName(String extension) { File cache = context.getCacheDir(); @@ -59,6 +78,25 @@ public class OpenCVTestRunner extends InstrumentationTestRunner { @Override public void onStart() { + // try to load internal libs + if (!OpenCVLoader.initDebug()) { + // There is no internal OpenCV libs + // Using OpenCV Manager for initialization; + + Log("Internal OpenCV library not found. Using OpenCV Manager for initialization"); + OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_3, getContext(), mLoaderCallback); + + synchronized (this) { + try { + wait(MANAGER_TIMEOUT); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } else { + Log("OpenCV library found inside test package. Using it!"); + } + context = getContext(); Assert.assertTrue("Context can't be 'null'", context != null); LENA_PATH = Utils.exportResource(context, R.drawable.lena); @@ -72,17 +110,6 @@ public class OpenCVTestRunner extends InstrumentationTestRunner { //List testCases = androidTestRunner.getTestCases(); //Collections.shuffle(testCases); //shuffle the tests order - if(OpenCVTestCase.passNYI) { - // turn off problematic camera tests - Iterator it = androidTestRunner.getTestCases().iterator(); - while (it.hasNext()) { - String name = it.next().toString(); - if (name.contains("VideoCaptureTest")) - it.remove(); - } - } - - super.onStart(); } diff --git a/modules/java/android_test/src/org/opencv/test/highgui/VideoCaptureTest.java b/modules/java/android_test/src/org/opencv/test/highgui/VideoCaptureTest.java index c6901c5e4..ec7211a29 100644 --- a/modules/java/android_test/src/org/opencv/test/highgui/VideoCaptureTest.java +++ b/modules/java/android_test/src/org/opencv/test/highgui/VideoCaptureTest.java @@ -19,13 +19,13 @@ public class VideoCaptureTest extends OpenCVTestCase { super.setUp(); capture = null; + isTestCaseEnabled = false; isSucceed = false; isOpened = false; } public void testGet() { - try - { + try { capture = new VideoCapture(Highgui.CV_CAP_ANDROID); double frameWidth = capture.get(Highgui.CV_CAP_PROP_FRAME_WIDTH); assertTrue(0 != frameWidth); @@ -35,8 +35,7 @@ public class VideoCaptureTest extends OpenCVTestCase { } public void testGetSupportedPreviewSizes() { - try - { + try { capture = new VideoCapture(Highgui.CV_CAP_ANDROID); List sizes = capture.getSupportedPreviewSizes(); assertNotNull(sizes); @@ -68,8 +67,7 @@ public class VideoCaptureTest extends OpenCVTestCase { } public void testIsOpenedRealCamera() { - try - { + try { capture = new VideoCapture(Highgui.CV_CAP_ANDROID); isOpened = capture.isOpened(); assertTrue(isOpened); @@ -79,8 +77,7 @@ public class VideoCaptureTest extends OpenCVTestCase { } public void testOpen() { - try - { + try { capture = new VideoCapture(); capture.open(Highgui.CV_CAP_ANDROID); isOpened = capture.isOpened(); @@ -91,8 +88,7 @@ public class VideoCaptureTest extends OpenCVTestCase { } public void testRead() { - try - { + try { capture = new VideoCapture(Highgui.CV_CAP_ANDROID); isSucceed = capture.read(dst); assertTrue(isSucceed); @@ -104,8 +100,7 @@ public class VideoCaptureTest extends OpenCVTestCase { } public void testRelease() { - try - { + try { capture = new VideoCapture(Highgui.CV_CAP_ANDROID); capture.release(); assertFalse(capture.isOpened()); @@ -116,8 +111,7 @@ public class VideoCaptureTest extends OpenCVTestCase { } public void testRetrieveMat() { - try - { + try { capture = new VideoCapture(Highgui.CV_CAP_ANDROID); capture.grab(); isSucceed = capture.retrieve(dst); @@ -130,8 +124,7 @@ public class VideoCaptureTest extends OpenCVTestCase { } public void testRetrieveMatInt() { - try - { + try { capture = new VideoCapture(Highgui.CV_CAP_ANDROID); capture.grab(); isSucceed = capture.retrieve(dst, Highgui.CV_CAP_ANDROID_GREY_FRAME); @@ -144,8 +137,7 @@ public class VideoCaptureTest extends OpenCVTestCase { } public void testSet() { - try - { + try { capture = new VideoCapture(Highgui.CV_CAP_ANDROID); capture.set(Highgui.CV_CAP_PROP_FRAME_WIDTH, 640); capture.set(Highgui.CV_CAP_PROP_FRAME_HEIGHT, 480); @@ -165,8 +157,7 @@ public class VideoCaptureTest extends OpenCVTestCase { } public void testVideoCaptureInt() { - try - { + try { capture = new VideoCapture(Highgui.CV_CAP_ANDROID); assertNotNull(capture); assertTrue(capture.isOpened()); From ab9311947ae788852bae893e5b38da4bb67b81a2 Mon Sep 17 00:00:00 2001 From: Andrey Kamaev Date: Thu, 15 Nov 2012 12:44:57 +0400 Subject: [PATCH 87/91] Update Android CMake toolchain for NDK r8c --- android/android.toolchain.cmake | 470 +++++++++++++++++++++----------- 1 file changed, 308 insertions(+), 162 deletions(-) diff --git a/android/android.toolchain.cmake b/android/android.toolchain.cmake index 7ab966835..25cef0f98 100644 --- a/android/android.toolchain.cmake +++ b/android/android.toolchain.cmake @@ -1,7 +1,37 @@ +# Copyright (c) 2010-2011, Ethan Rublee +# Copyright (c) 2011-2012, Andrey Kamaev +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# 3. The name of the copyright holders may be used to endorse or promote +# products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + # ------------------------------------------------------------------------------ # Android CMake toolchain file, for use with the Android NDK r5-r8 # Requires cmake 2.6.3 or newer (2.8.5 or newer is recommended). -# See home page: http://code.google.com/p/android-cmake/ +# See home page: https://github.com/taka-no-me/android-cmake # # The file is mantained by the OpenCV project. The latest version can be get at # http://code.opencv.org/projects/opencv/repository/revisions/master/changes/android/android.toolchain.cmake @@ -64,6 +94,20 @@ # ANDROID_NATIVE_API_LEVEL=android-8 - level of Android API compile for. # Option is read-only when standalone toolchain is used. # +# ANDROID_TOOLCHAIN_NAME=arm-linux-androideabi-4.6 - the name of compiler +# toolchain to be used. The list of possible values depends on the NDK +# version. For NDK r8c the possible values are: +# +# * arm-linux-androideabi-4.4.3 +# * arm-linux-androideabi-4.6 +# * arm-linux-androideabi-clang3.1 +# * mipsel-linux-android-4.4.3 +# * mipsel-linux-android-4.6 +# * mipsel-linux-android-clang3.1 +# * x86-4.4.3 +# * x86-4.6 +# * x86-clang3.1 +# # ANDROID_FORCE_ARM_BUILD=OFF - set ON to generate 32-bit ARM instructions # instead of Thumb. Is not available for "x86" (inapplicable) and # "armeabi-v6 with VFP" (is forced to be ON) ABIs. @@ -147,13 +191,9 @@ # under the ${LIBRARY_OUTPUT_PATH_ROOT}/libs/${ANDROID_NDK_ABI_NAME} # (depending on the target ABI). This is convenient for Android packaging. # -# Authors: -# Ethan Rublee ethan.ruble@gmail.com -# Andrey Kamaev andrey.kamaev@itseez.com -# # Change Log: # - initial version December 2010 -# - modified April 2011 +# - April 2011 # [+] added possibility to build with NDK (without standalone toolchain) # [+] support cross-compilation on Windows (native, no cygwin support) # [+] added compiler option to force "char" type to be signed @@ -164,13 +204,13 @@ # [+] EXECUTABLE_OUTPUT_PATH is set by toolchain (required on Windows) # [~] Fixed bug with ANDROID_API_LEVEL variable # [~] turn off SWIG search if it is not found first time -# - modified May 2011 +# - May 2011 # [~] ANDROID_LEVEL is renamed to ANDROID_API_LEVEL # [+] ANDROID_API_LEVEL is detected by toolchain if not specified # [~] added guard to prevent changing of output directories on the first # cmake pass # [~] toolchain exits with error if ARM_TARGET is not recognized -# - modified June 2011 +# - June 2011 # [~] default NDK path is updated for version r5c # [+] variable CMAKE_SYSTEM_PROCESSOR is set based on ARM_TARGET # [~] toolchain install directory is added to linker paths @@ -178,13 +218,13 @@ # [+] added macro find_host_package, find_host_program to search # packages/programs on the host system # [~] fixed path to STL library -# - modified July 2011 +# - July 2011 # [~] fixed options caching # [~] search for all supported NDK versions # [~] allowed spaces in NDK path -# - modified September 2011 +# - September 2011 # [~] updated for NDK r6b -# - modified November 2011 +# - November 2011 # [*] rewritten for NDK r7 # [+] x86 toolchain support (experimental) # [+] added "armeabi-v6 with VFP" ABI for ARMv6 processors. @@ -197,37 +237,37 @@ # [~] ARM_TARGET is renamed to ANDROID_ABI # [~] ARMEABI_NDK_NAME is renamed to ANDROID_NDK_ABI_NAME # [~] ANDROID_API_LEVEL is renamed to ANDROID_NATIVE_API_LEVEL -# - modified January 2012 +# - January 2012 # [+] added stlport_static support (experimental) # [+] added special check for cygwin # [+] filtered out hidden files (starting with .) while globbing inside NDK # [+] automatically applied GLESv2 linkage fix for NDK revisions 5-6 # [+] added ANDROID_GET_ABI_RAWNAME to get NDK ABI names by CMake flags -# - modified February 2012 +# - February 2012 # [+] updated for NDK r7b # [~] fixed cmake try_compile() command # [~] Fix for missing install_name_tool on OS X -# - modified March 2012 +# - March 2012 # [~] fixed incorrect C compiler flags # [~] fixed CMAKE_SYSTEM_PROCESSOR change on ANDROID_ABI change # [+] improved toolchain loading speed # [+] added assembler language support (.S) # [+] allowed preset search paths and extra search suffixes -# - modified April 2012 +# - April 2012 # [+] updated for NDK r7c # [~] fixed most of problems with compiler/linker flags and caching # [+] added option ANDROID_FUNCTION_LEVEL_LINKING -# - modified May 2012 +# - May 2012 # [+] updated for NDK r8 # [+] added mips architecture support -# - modified August 2012 +# - August 2012 # [+] updated for NDK r8b # [~] all intermediate files generated by toolchain are moved to CMakeFiles # [~] libstdc++ and libsupc are removed from explicit link libraries # [+] added CCache support (via NDK_CCACHE environment or cmake variable) # [+] added gold linker support for NDK r8b # [~] fixed mips linker flags for NDK r8b -# - modified September 2012 +# - September 2012 # [+] added NDK release name detection (see ANDROID_NDK_RELEASE) # [+] added support for all C++ runtimes from NDK # (system, gabi++, stlport, gnustl) @@ -235,8 +275,11 @@ # [~] use gold linker as default if available (NDK r8b) # [~] globally turned off rpath # [~] compiler options are aligned with NDK r8b -# - modified October 2012 +# - October 2012 # [~] fixed C++ linking: explicitly link with math library (OpenCV #2426) +# - November 2012 +# [+] updated for NDK r8c +# [+] added support for clang compiler # ------------------------------------------------------------------------------ cmake_minimum_required( VERSION 2.6.3 ) @@ -259,7 +302,7 @@ set( CMAKE_SYSTEM_VERSION 1 ) # rpath makes low sence for Android set( CMAKE_SKIP_RPATH TRUE CACHE BOOL "If set, runtime paths are not added when using shared libraries." ) -set( ANDROID_SUPPORTED_NDK_VERSIONS ${ANDROID_EXTRA_NDK_VERSIONS} -r8b -r8 -r7c -r7b -r7 -r6b -r6 -r5c -r5b -r5 "" ) +set( ANDROID_SUPPORTED_NDK_VERSIONS ${ANDROID_EXTRA_NDK_VERSIONS} -r8c -r8b -r8 -r7c -r7b -r7 -r6b -r6 -r5c -r5b -r5 "" ) if(NOT DEFINED ANDROID_NDK_SEARCH_PATHS) if( CMAKE_HOST_WIN32 ) file( TO_CMAKE_PATH "$ENV{PROGRAMFILES}" ANDROID_NDK_SEARCH_PATHS ) @@ -367,8 +410,8 @@ endmacro() macro( __DETECT_TOOLCHAIN_MACHINE_NAME _var _root ) if( EXISTS "${_root}" ) - file( GLOB __gccExePath "${_root}/bin/*-gcc${TOOL_OS_SUFFIX}" ) - __LIST_FILTER( __gccExePath "bin/[.].*-gcc${TOOL_OS_SUFFIX}$" ) + file( GLOB __gccExePath RELATIVE "${_root}/bin/" "${_root}/bin/*-gcc${TOOL_OS_SUFFIX}" ) + __LIST_FILTER( __gccExePath "^[.].*" ) list( LENGTH __gccExePath __gccExePathsCount ) if( NOT __gccExePathsCount EQUAL 1 AND NOT _CMAKE_IN_TRY_COMPILE ) message( WARNING "Could not determine machine name for compiler from ${_root}" ) @@ -506,55 +549,73 @@ if( BUILD_WITH_STANDALONE_TOOLCHAIN ) elseif( __availableToolchainMachines MATCHES mipsel ) set( __availableToolchainArchs "mipsel" ) endif() - if( ANDROID_COMPILER_VERSION ) - # do not run gcc every time because it is relatevely expencive - set( __availableToolchainCompilerVersions "${ANDROID_COMPILER_VERSION}" ) - else() - execute_process( COMMAND "${ANDROID_STANDALONE_TOOLCHAIN}/bin/${__availableToolchainMachines}-gcc${TOOL_OS_SUFFIX}" --version - OUTPUT_VARIABLE __availableToolchainCompilerVersions OUTPUT_STRIP_TRAILING_WHITESPACE ) - string( REGEX MATCH "[0-9]+[.][0-9]+([.][0-9]+)?" __availableToolchainCompilerVersions "${__availableToolchainCompilerVersions}" ) + execute_process( COMMAND "${ANDROID_STANDALONE_TOOLCHAIN}/bin/${__availableToolchainMachines}-gcc${TOOL_OS_SUFFIX}" -dumpversion + OUTPUT_VARIABLE __availableToolchainCompilerVersions OUTPUT_STRIP_TRAILING_WHITESPACE ) + string( REGEX MATCH "[0-9]+[.][0-9]+([.][0-9]+)?" __availableToolchainCompilerVersions "${__availableToolchainCompilerVersions}" ) + if( EXISTS "${ANDROID_STANDALONE_TOOLCHAIN}/bin/clang${TOOL_OS_SUFFIX}" ) + list( APPEND __availableToolchains "standalone-clang" ) + list( APPEND __availableToolchainMachines ${__availableToolchainMachines} ) + list( APPEND __availableToolchainArchs ${__availableToolchainArchs} ) + list( APPEND __availableToolchainCompilerVersions ${__availableToolchainCompilerVersions} ) endif() endif() +macro( __GLOB_NDK_TOOLCHAINS __availableToolchainsVar ) + foreach( __toolchain ${${__availableToolchainsVar}} ) + if( "${__toolchain}" MATCHES "-clang3[.][0-9]$" AND NOT EXISTS "${ANDROID_NDK}/toolchains/${__toolchain}/prebuilt/" ) + string( REGEX REPLACE "-clang3[.][0-9]$" "-4.6" __gcc_toolchain "${__toolchain}" ) + else() + set( __gcc_toolchain "${__toolchain}" ) + endif() + __DETECT_TOOLCHAIN_MACHINE_NAME( __machine "${ANDROID_NDK}/toolchains/${__gcc_toolchain}/prebuilt/${ANDROID_NDK_HOST_SYSTEM_NAME}" ) + if( __machine ) + string( REGEX MATCH "[0-9]+[.][0-9]+([.][0-9]+)?$" __version "${__gcc_toolchain}" ) + string( REGEX MATCH "^[^-]+" __arch "${__gcc_toolchain}" ) + list( APPEND __availableToolchainMachines "${__machine}" ) + list( APPEND __availableToolchainArchs "${__arch}" ) + list( APPEND __availableToolchainCompilerVersions "${__version}" ) + else() + list( REMOVE_ITEM ${__availableToolchainsVar} "${__toolchain}" ) + endif() + unset( __gcc_toolchain ) + endforeach() +endmacro() + # get all the details about NDK if( BUILD_WITH_ANDROID_NDK ) file( GLOB ANDROID_SUPPORTED_NATIVE_API_LEVELS RELATIVE "${ANDROID_NDK}/platforms" "${ANDROID_NDK}/platforms/android-*" ) string( REPLACE "android-" "" ANDROID_SUPPORTED_NATIVE_API_LEVELS "${ANDROID_SUPPORTED_NATIVE_API_LEVELS}" ) - file( GLOB __availableToolchains RELATIVE "${ANDROID_NDK}/toolchains" "${ANDROID_NDK}/toolchains/*" ) - __LIST_FILTER( __availableToolchains "^[.]" ) + set( __availableToolchains "" ) set( __availableToolchainMachines "" ) set( __availableToolchainArchs "" ) set( __availableToolchainCompilerVersions "" ) - foreach( __toolchain ${__availableToolchains} ) - __DETECT_TOOLCHAIN_MACHINE_NAME( __machine "${ANDROID_NDK}/toolchains/${__toolchain}/prebuilt/${ANDROID_NDK_HOST_SYSTEM_NAME}" ) - if( __machine ) - string( REGEX MATCH "[0-9]+[.][0-9]+([.][0-9]+)?$" __version "${__toolchain}" ) - string( REGEX MATCH "^[^-]+" __arch "${__toolchain}" ) - list( APPEND __availableToolchainMachines "${__machine}" ) - list( APPEND __availableToolchainArchs "${__arch}" ) - list( APPEND __availableToolchainCompilerVersions "${__version}" ) - else() - list( REMOVE_ITEM __availableToolchains "${__toolchain}" ) - endif() - endforeach() + if( ANDROID_TOOLCHAIN_NAME AND EXISTS "${ANDROID_NDK}/toolchains/${ANDROID_TOOLCHAIN_NAME}/" ) + # do not go through all toolchains if we know the name + set( __availableToolchains "${ANDROID_TOOLCHAIN_NAME}" ) + __GLOB_NDK_TOOLCHAINS( __availableToolchains ) + endif() if( NOT __availableToolchains ) - message( FATAL_ERROR "Could not any working toolchain in the NDK. Probably your Android NDK is broken." ) + file( GLOB __availableToolchains RELATIVE "${ANDROID_NDK}/toolchains" "${ANDROID_NDK}/toolchains/*" ) + __LIST_FILTER( __availableToolchains "^[.]" ) + __LIST_FILTER( __availableToolchains "llvm" ) + __GLOB_NDK_TOOLCHAINS( __availableToolchains ) + endif() + if( NOT __availableToolchains ) + message( FATAL_ERROR "Could not find any working toolchain in the NDK. Probably your Android NDK is broken." ) endif() endif() # build list of available ABIs +set( ANDROID_SUPPORTED_ABIS "" ) +set( __uniqToolchainArchNames ${__availableToolchainArchs} ) +list( REMOVE_DUPLICATES __uniqToolchainArchNames ) +list( SORT __uniqToolchainArchNames ) +foreach( __arch ${__uniqToolchainArchNames} ) +list( APPEND ANDROID_SUPPORTED_ABIS ${ANDROID_SUPPORTED_ABIS_${__arch}} ) +endforeach() +unset( __uniqToolchainArchNames ) if( NOT ANDROID_SUPPORTED_ABIS ) - set( ANDROID_SUPPORTED_ABIS "" ) - set( __uniqToolchainArchNames ${__availableToolchainArchs} ) - list( REMOVE_DUPLICATES __uniqToolchainArchNames ) - list( SORT __uniqToolchainArchNames ) - foreach( __arch ${__uniqToolchainArchNames} ) - list( APPEND ANDROID_SUPPORTED_ABIS ${ANDROID_SUPPORTED_ABIS_${__arch}} ) - endforeach() - unset( __uniqToolchainArchNames ) - if( NOT ANDROID_SUPPORTED_ABIS ) - message( FATAL_ERROR "No one of known Android ABIs is supported by this cmake toolchain." ) - endif() +message( FATAL_ERROR "No one of known Android ABIs is supported by this cmake toolchain." ) endif() # choose target ABI @@ -569,33 +630,34 @@ if( __androidAbiIdx EQUAL -1 ) endif() unset( __androidAbiIdx ) -# remember target ABI -set( ANDROID_ABI "${ANDROID_ABI}" CACHE STRING "The target ABI for Android. If arm, then armeabi-v7a is recommended for hardware floating point." FORCE ) - # set target ABI options if( ANDROID_ABI STREQUAL "x86" ) set( X86 true ) set( ANDROID_NDK_ABI_NAME "x86" ) set( ANDROID_ARCH_NAME "x86" ) set( ANDROID_ARCH_FULLNAME "x86" ) + set( ANDROID_LLVM_TRIPLE "i686-none-linux-android" ) set( CMAKE_SYSTEM_PROCESSOR "i686" ) elseif( ANDROID_ABI STREQUAL "mips" ) set( MIPS true ) set( ANDROID_NDK_ABI_NAME "mips" ) set( ANDROID_ARCH_NAME "mips" ) set( ANDROID_ARCH_FULLNAME "mipsel" ) + set( ANDROID_LLVM_TRIPLE "mipsel-none-linux-android" ) set( CMAKE_SYSTEM_PROCESSOR "mips" ) elseif( ANDROID_ABI STREQUAL "armeabi" ) set( ARMEABI true ) set( ANDROID_NDK_ABI_NAME "armeabi" ) set( ANDROID_ARCH_NAME "arm" ) set( ANDROID_ARCH_FULLNAME "arm" ) + set( ANDROID_LLVM_TRIPLE "armv5te-none-linux-androideabi" ) set( CMAKE_SYSTEM_PROCESSOR "armv5te" ) elseif( ANDROID_ABI STREQUAL "armeabi-v6 with VFP" ) set( ARMEABI_V6 true ) set( ANDROID_NDK_ABI_NAME "armeabi" ) set( ANDROID_ARCH_NAME "arm" ) set( ANDROID_ARCH_FULLNAME "arm" ) + set( ANDROID_LLVM_TRIPLE "armv5te-none-linux-androideabi" ) set( CMAKE_SYSTEM_PROCESSOR "armv6" ) # need always fallback to older platform set( ARMEABI true ) @@ -604,12 +666,14 @@ elseif( ANDROID_ABI STREQUAL "armeabi-v7a") set( ANDROID_NDK_ABI_NAME "armeabi-v7a" ) set( ANDROID_ARCH_NAME "arm" ) set( ANDROID_ARCH_FULLNAME "arm" ) + set( ANDROID_LLVM_TRIPLE "armv7-none-linux-androideabi" ) set( CMAKE_SYSTEM_PROCESSOR "armv7-a" ) elseif( ANDROID_ABI STREQUAL "armeabi-v7a with VFPV3" ) set( ARMEABI_V7A true ) set( ANDROID_NDK_ABI_NAME "armeabi-v7a" ) set( ANDROID_ARCH_NAME "arm" ) set( ANDROID_ARCH_FULLNAME "arm" ) + set( ANDROID_LLVM_TRIPLE "armv7-none-linux-androideabi" ) set( CMAKE_SYSTEM_PROCESSOR "armv7-a" ) set( VFPV3 true ) elseif( ANDROID_ABI STREQUAL "armeabi-v7a with NEON" ) @@ -617,6 +681,7 @@ elseif( ANDROID_ABI STREQUAL "armeabi-v7a with NEON" ) set( ANDROID_NDK_ABI_NAME "armeabi-v7a" ) set( ANDROID_ARCH_NAME "arm" ) set( ANDROID_ARCH_FULLNAME "arm" ) + set( ANDROID_LLVM_TRIPLE "armv7-none-linux-androideabi" ) set( CMAKE_SYSTEM_PROCESSOR "armv7-a" ) set( VFPV3 true ) set( NEON true ) @@ -630,12 +695,6 @@ if( CMAKE_BINARY_DIR AND EXISTS "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMa file( APPEND "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeSystem.cmake" "SET(CMAKE_SYSTEM_PROCESSOR \"${CMAKE_SYSTEM_PROCESSOR}\")\n" ) endif() -set( ANDROID_SUPPORTED_ABIS ${ANDROID_SUPPORTED_ABIS_${ANDROID_ARCH_FULLNAME}} CACHE INTERNAL "ANDROID_ABI can be changed only to one of these ABIs. Changing to any other ABI requires to reset cmake cache." FORCE ) -if( CMAKE_VERSION VERSION_GREATER "2.8" ) - list( SORT ANDROID_SUPPORTED_ABIS_${ANDROID_ARCH_FULLNAME} ) - set_property( CACHE ANDROID_ABI PROPERTY STRINGS ${ANDROID_SUPPORTED_ABIS_${ANDROID_ARCH_FULLNAME}} ) -endif() - if( ANDROID_ARCH_NAME STREQUAL "arm" AND NOT ARMEABI_V6 ) __INIT_VARIABLE( ANDROID_FORCE_ARM_BUILD OBSOLETE_FORCE_ARM VALUES OFF ) set( ANDROID_FORCE_ARM_BUILD ${ANDROID_FORCE_ARM_BUILD} CACHE BOOL "Use 32-bit ARM instructions instead of Thumb-1" FORCE ) @@ -648,11 +707,15 @@ endif() if( ANDROID_TOOLCHAIN_NAME ) list( FIND __availableToolchains "${ANDROID_TOOLCHAIN_NAME}" __toolchainIdx ) if( __toolchainIdx EQUAL -1 ) - message( FATAL_ERROR "Previously selected toolchain \"${ANDROID_TOOLCHAIN_NAME}\" is missing. You need to remove CMakeCache.txt and rerun cmake manually to change the toolchain" ) + list( SORT __availableToolchains ) + string( REPLACE ";" "\n * " toolchains_list "${__availableToolchains}" ) + set( toolchains_list " * ${toolchains_list}") + message( FATAL_ERROR "Specified toolchain \"${ANDROID_TOOLCHAIN_NAME}\" is missing in your NDK or broken. Please verify that your NDK is working or select another compiler toolchain. +To configure the toolchain set CMake variable ANDROID_TOOLCHAIN_NAME to one of the following values:\n${toolchains_list}\n" ) endif() list( GET __availableToolchainArchs ${__toolchainIdx} __toolchainArch ) if( NOT __toolchainArch STREQUAL ANDROID_ARCH_FULLNAME ) - message( SEND_ERROR "Previously selected toolchain \"${ANDROID_TOOLCHAIN_NAME}\" is not able to compile binaries for the \"${ANDROID_ARCH_NAME}\" platform." ) + message( SEND_ERROR "Selected toolchain \"${ANDROID_TOOLCHAIN_NAME}\" is not able to compile binaries for the \"${ANDROID_ARCH_NAME}\" platform." ) endif() else() set( __toolchainIdx -1 ) @@ -681,8 +744,7 @@ endif() list( GET __availableToolchains ${__toolchainIdx} ANDROID_TOOLCHAIN_NAME ) list( GET __availableToolchainMachines ${__toolchainIdx} ANDROID_TOOLCHAIN_MACHINE_NAME ) list( GET __availableToolchainCompilerVersions ${__toolchainIdx} ANDROID_COMPILER_VERSION ) -set( ANDROID_TOOLCHAIN_NAME "${ANDROID_TOOLCHAIN_NAME}" CACHE INTERNAL "Name of toolchain used" FORCE ) -set( ANDROID_COMPILER_VERSION "${ANDROID_COMPILER_VERSION}" CACHE INTERNAL "compiler version from selected toolchain" FORCE ) + unset( __toolchainIdx ) unset( __availableToolchains ) unset( __availableToolchainMachines ) @@ -692,37 +754,35 @@ unset( __availableToolchainCompilerVersions ) # choose native API level __INIT_VARIABLE( ANDROID_NATIVE_API_LEVEL ENV_ANDROID_NATIVE_API_LEVEL ANDROID_API_LEVEL ENV_ANDROID_API_LEVEL ANDROID_STANDALONE_TOOLCHAIN_API_LEVEL ANDROID_DEFAULT_NDK_API_LEVEL_${ANDROID_ARCH_NAME} ANDROID_DEFAULT_NDK_API_LEVEL ) string( REGEX MATCH "[0-9]+" ANDROID_NATIVE_API_LEVEL "${ANDROID_NATIVE_API_LEVEL}" ) +# TODO: filter out unsupported levels # validate list( FIND ANDROID_SUPPORTED_NATIVE_API_LEVELS "${ANDROID_NATIVE_API_LEVEL}" __levelIdx ) if( __levelIdx EQUAL -1 ) message( SEND_ERROR "Specified Android native API level (${ANDROID_NATIVE_API_LEVEL}) is not supported by your NDK/toolchain." ) +else() + if( BUILD_WITH_ANDROID_NDK ) + __DETECT_NATIVE_API_LEVEL( __realApiLevel "${ANDROID_NDK}/platforms/android-${ANDROID_NATIVE_API_LEVEL}/arch-${ANDROID_ARCH_NAME}/usr/include/android/api-level.h" ) + if( NOT __realApiLevel EQUAL ANDROID_NATIVE_API_LEVEL ) + message( SEND_ERROR "Specified Android API level (${ANDROID_NATIVE_API_LEVEL}) does not match to the level found (${__realApiLevel}). Probably your copy of NDK is broken." ) + endif() + unset( __realApiLevel ) + endif() + set( ANDROID_NATIVE_API_LEVEL "${ANDROID_NATIVE_API_LEVEL}" CACHE STRING "Android API level for native code" FORCE ) + if( CMAKE_VERSION VERSION_GREATER "2.8" ) + list( SORT ANDROID_SUPPORTED_NATIVE_API_LEVELS ) + set_property( CACHE ANDROID_NATIVE_API_LEVEL PROPERTY STRINGS ${ANDROID_SUPPORTED_NATIVE_API_LEVELS} ) + endif() endif() unset( __levelIdx ) -if( BUILD_WITH_ANDROID_NDK ) - __DETECT_NATIVE_API_LEVEL( __realApiLevel "${ANDROID_NDK}/platforms/android-${ANDROID_NATIVE_API_LEVEL}/arch-${ANDROID_ARCH_NAME}/usr/include/android/api-level.h" ) - if( NOT __realApiLevel EQUAL ANDROID_NATIVE_API_LEVEL ) - message( SEND_ERROR "Specified Android API level (${ANDROID_NATIVE_API_LEVEL}) does not match to the level found (${__realApiLevel}). Probably your copy of NDK is broken." ) - endif() - unset( __realApiLevel ) -endif() -set( ANDROID_NATIVE_API_LEVEL "${ANDROID_NATIVE_API_LEVEL}" CACHE STRING "Android API level for native code" FORCE ) + + +# remember target ABI +set( ANDROID_ABI "${ANDROID_ABI}" CACHE STRING "The target ABI for Android. If arm, then armeabi-v7a is recommended for hardware floating point." FORCE ) if( CMAKE_VERSION VERSION_GREATER "2.8" ) - list( SORT ANDROID_SUPPORTED_NATIVE_API_LEVELS ) - set_property( CACHE ANDROID_NATIVE_API_LEVEL PROPERTY STRINGS ${ANDROID_SUPPORTED_NATIVE_API_LEVELS} ) + list( SORT ANDROID_SUPPORTED_ABIS_${ANDROID_ARCH_FULLNAME} ) + set_property( CACHE ANDROID_ABI PROPERTY STRINGS ${ANDROID_SUPPORTED_ABIS_${ANDROID_ARCH_FULLNAME}} ) endif() -# setup output directories -set( LIBRARY_OUTPUT_PATH_ROOT ${CMAKE_SOURCE_DIR} CACHE PATH "root for library output, set this to change where android libs are installed to" ) -set( CMAKE_INSTALL_PREFIX "${ANDROID_TOOLCHAIN_ROOT}/user" CACHE STRING "path for installing" ) - -if(NOT _CMAKE_IN_TRY_COMPILE) - if( EXISTS "${CMAKE_SOURCE_DIR}/jni/CMakeLists.txt" ) - set( EXECUTABLE_OUTPUT_PATH "${LIBRARY_OUTPUT_PATH_ROOT}/bin/${ANDROID_NDK_ABI_NAME}" CACHE PATH "Output directory for applications" ) - else() - set( EXECUTABLE_OUTPUT_PATH "${LIBRARY_OUTPUT_PATH_ROOT}/bin" CACHE PATH "Output directory for applications" ) - endif() - set( LIBRARY_OUTPUT_PATH "${LIBRARY_OUTPUT_PATH_ROOT}/libs/${ANDROID_NDK_ABI_NAME}" CACHE PATH "path for android libs" ) -endif() # runtime choice (STL, rtti, exceptions) if( NOT ANDROID_STL ) @@ -800,9 +860,84 @@ See https://android.googlesource.com/platform/development.git f907f4f9d4e56ccc80 " ) endif() + +# setup paths and STL for standalone toolchain +if( BUILD_WITH_STANDALONE_TOOLCHAIN ) + set( ANDROID_TOOLCHAIN_ROOT "${ANDROID_STANDALONE_TOOLCHAIN}" ) + set( ANDROID_CLANG_TOOLCHAIN_ROOT "${ANDROID_STANDALONE_TOOLCHAIN}" ) + set( ANDROID_SYSROOT "${ANDROID_STANDALONE_TOOLCHAIN}/sysroot" ) + + if( NOT ANDROID_STL STREQUAL "none" ) + set( ANDROID_STL_INCLUDE_DIRS "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/include/c++/${ANDROID_COMPILER_VERSION}" ) + if( ARMEABI_V7A AND EXISTS "${ANDROID_STL_INCLUDE_DIRS}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/${CMAKE_SYSTEM_PROCESSOR}/bits" ) + list( APPEND ANDROID_STL_INCLUDE_DIRS "${ANDROID_STL_INCLUDE_DIRS}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/${CMAKE_SYSTEM_PROCESSOR}" ) + elseif( ARMEABI AND NOT ANDROID_FORCE_ARM_BUILD AND EXISTS "${ANDROID_STL_INCLUDE_DIRS}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/thumb/bits" ) + list( APPEND ANDROID_STL_INCLUDE_DIRS "${ANDROID_STL_INCLUDE_DIRS}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/thumb" ) + else() + list( APPEND ANDROID_STL_INCLUDE_DIRS "${ANDROID_STL_INCLUDE_DIRS}/${ANDROID_TOOLCHAIN_MACHINE_NAME}" ) + endif() + # always search static GNU STL to get the location of libsupc++.a + if( ARMEABI_V7A AND NOT ANDROID_FORCE_ARM_BUILD AND EXISTS "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/${CMAKE_SYSTEM_PROCESSOR}/thumb/libstdc++.a" ) + set( __libstl "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/${CMAKE_SYSTEM_PROCESSOR}/thumb" ) + elseif( ARMEABI_V7A AND EXISTS "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/${CMAKE_SYSTEM_PROCESSOR}/libstdc++.a" ) + set( __libstl "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/${CMAKE_SYSTEM_PROCESSOR}" ) + elseif( ARMEABI AND NOT ANDROID_FORCE_ARM_BUILD AND EXISTS "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/thumb/libstdc++.a" ) + set( __libstl "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/thumb" ) + elseif( EXISTS "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/libstdc++.a" ) + set( __libstl "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib" ) + endif() + if( __libstl ) + set( __libsupcxx "${__libstl}/libsupc++.a" ) + set( __libstl "${__libstl}/libstdc++.a" ) + endif() + if( NOT EXISTS "${__libsupcxx}" ) + message( FATAL_ERROR "The required libstdsupc++.a is missing in your standalone toolchain. + Usually it happens because of bug in make-standalone-toolchain.sh script from NDK r7, r7b and r7c. + You need to either upgrade to newer NDK or manually copy + $ANDROID_NDK/sources/cxx-stl/gnu-libstdc++/libs/${ANDROID_NDK_ABI_NAME}/libsupc++.a + to + ${__libsupcxx} + " ) + endif() + if( ANDROID_STL STREQUAL "gnustl_shared" ) + if( ARMEABI_V7A AND EXISTS "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/${CMAKE_SYSTEM_PROCESSOR}/libgnustl_shared.so" ) + set( __libstl "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/${CMAKE_SYSTEM_PROCESSOR}/libgnustl_shared.so" ) + elseif( ARMEABI AND NOT ANDROID_FORCE_ARM_BUILD AND EXISTS "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/thumb/libgnustl_shared.so" ) + set( __libstl "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/thumb/libgnustl_shared.so" ) + elseif( EXISTS "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/libgnustl_shared.so" ) + set( __libstl "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/libgnustl_shared.so" ) + endif() + endif() + endif() +endif() + +# clang +if( "${ANDROID_TOOLCHAIN_NAME}" STREQUAL "standalone-clang" ) + set( ANDROID_COMPILER_IS_CLANG 1 ) + execute_process( COMMAND "${ANDROID_CLANG_TOOLCHAIN_ROOT}/bin/clang${TOOL_OS_SUFFIX}" --version OUTPUT_VARIABLE ANDROID_CLANG_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE ) + string( REGEX MATCH "[0-9]+[.][0-9]+" ANDROID_CLANG_VERSION "${ANDROID_CLANG_VERSION}") +elseif( "${ANDROID_TOOLCHAIN_NAME}" MATCHES "-clang3[.][0-9]?$" ) + string( REGEX MATCH "3[.][0-9]$" ANDROID_CLANG_VERSION "${ANDROID_TOOLCHAIN_NAME}") + string( REGEX REPLACE "-clang${ANDROID_CLANG_VERSION}$" "-4.6" ANDROID_GCC_TOOLCHAIN_NAME "${ANDROID_TOOLCHAIN_NAME}" ) + if( NOT EXISTS "${ANDROID_NDK}/toolchains/llvm-${ANDROID_CLANG_VERSION}/prebuilt/${ANDROID_NDK_HOST_SYSTEM_NAME}/bin/clang${TOOL_OS_SUFFIX}" ) + message( FATAL_ERROR "Could not find the " ) + endif() + set( ANDROID_COMPILER_IS_CLANG 1 ) + set( ANDROID_CLANG_TOOLCHAIN_ROOT "${ANDROID_NDK}/toolchains/llvm-${ANDROID_CLANG_VERSION}/prebuilt/${ANDROID_NDK_HOST_SYSTEM_NAME}" ) +else() + set( ANDROID_GCC_TOOLCHAIN_NAME "${ANDROID_TOOLCHAIN_NAME}" ) + unset( ANDROID_COMPILER_IS_CLANG CACHE ) +endif() + +string( REPLACE "." "" _clang_name "clang${ANDROID_CLANG_VERSION}" ) +if( NOT EXISTS "${ANDROID_CLANG_TOOLCHAIN_ROOT}/bin/${_clang_name}${TOOL_OS_SUFFIX}" ) + set( _clang_name "clang" ) +endif() + + # setup paths and STL for NDK if( BUILD_WITH_ANDROID_NDK ) - set( ANDROID_TOOLCHAIN_ROOT "${ANDROID_NDK}/toolchains/${ANDROID_TOOLCHAIN_NAME}/prebuilt/${ANDROID_NDK_HOST_SYSTEM_NAME}" ) + set( ANDROID_TOOLCHAIN_ROOT "${ANDROID_NDK}/toolchains/${ANDROID_GCC_TOOLCHAIN_NAME}/prebuilt/${ANDROID_NDK_HOST_SYSTEM_NAME}" ) set( ANDROID_SYSROOT "${ANDROID_NDK}/platforms/android-${ANDROID_NATIVE_API_LEVEL}/arch-${ANDROID_ARCH_NAME}" ) if( ANDROID_STL STREQUAL "none" ) @@ -874,54 +1009,6 @@ if( BUILD_WITH_ANDROID_NDK ) endif() endif() -# setup paths and STL for standalone toolchain -if( BUILD_WITH_STANDALONE_TOOLCHAIN ) - set( ANDROID_TOOLCHAIN_ROOT "${ANDROID_STANDALONE_TOOLCHAIN}" ) - set( ANDROID_SYSROOT "${ANDROID_STANDALONE_TOOLCHAIN}/sysroot" ) - - if( NOT ANDROID_STL STREQUAL "none" ) - set( ANDROID_STL_INCLUDE_DIRS "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/include/c++/${ANDROID_COMPILER_VERSION}" ) - if( ARMEABI_V7A AND EXISTS "${ANDROID_STL_INCLUDE_DIRS}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/${CMAKE_SYSTEM_PROCESSOR}/bits" ) - list( APPEND ANDROID_STL_INCLUDE_DIRS "${ANDROID_STL_INCLUDE_DIRS}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/${CMAKE_SYSTEM_PROCESSOR}" ) - elseif( ARMEABI AND NOT ANDROID_FORCE_ARM_BUILD AND EXISTS "${ANDROID_STL_INCLUDE_DIRS}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/thumb/bits" ) - list( APPEND ANDROID_STL_INCLUDE_DIRS "${ANDROID_STL_INCLUDE_DIRS}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/thumb" ) - else() - list( APPEND ANDROID_STL_INCLUDE_DIRS "${ANDROID_STL_INCLUDE_DIRS}/${ANDROID_TOOLCHAIN_MACHINE_NAME}" ) - endif() - # always search static GNU STL to get the location of libsupc++.a - if( ARMEABI_V7A AND NOT ANDROID_FORCE_ARM_BUILD AND EXISTS "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/${CMAKE_SYSTEM_PROCESSOR}/thumb/libstdc++.a" ) - set( __libstl "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/${CMAKE_SYSTEM_PROCESSOR}/thumb" ) - elseif( ARMEABI_V7A AND EXISTS "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/${CMAKE_SYSTEM_PROCESSOR}/libstdc++.a" ) - set( __libstl "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/${CMAKE_SYSTEM_PROCESSOR}" ) - elseif( ARMEABI AND NOT ANDROID_FORCE_ARM_BUILD AND EXISTS "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/thumb/libstdc++.a" ) - set( __libstl "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/thumb" ) - elseif( EXISTS "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/libstdc++.a" ) - set( __libstl "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib" ) - endif() - if( __libstl ) - set( __libsupcxx "${__libstl}/libsupc++.a" ) - set( __libstl "${__libstl}/libstdc++.a" ) - endif() - if( NOT EXISTS "${__libsupcxx}" ) - message( FATAL_ERROR "The required libstdsupc++.a is missing in your standalone toolchain. - Usually it happens because of bug in make-standalone-toolchain.sh script from NDK r7, r7b and r7c. - You need to either upgrade to newer NDK or manually copy - $ANDROID_NDK/sources/cxx-stl/gnu-libstdc++/libs/${ANDROID_NDK_ABI_NAME}/libsupc++.a - to - ${__libsupcxx} - " ) - endif() - if( ANDROID_STL STREQUAL "gnustl_shared" ) - if( ARMEABI_V7A AND EXISTS "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/${CMAKE_SYSTEM_PROCESSOR}/libgnustl_shared.so" ) - set( __libstl "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/${CMAKE_SYSTEM_PROCESSOR}/libgnustl_shared.so" ) - elseif( ARMEABI AND NOT ANDROID_FORCE_ARM_BUILD AND EXISTS "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/thumb/libgnustl_shared.so" ) - set( __libstl "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/thumb/libgnustl_shared.so" ) - elseif( EXISTS "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/libgnustl_shared.so" ) - set( __libstl "${ANDROID_STANDALONE_TOOLCHAIN}/${ANDROID_TOOLCHAIN_MACHINE_NAME}/lib/libgnustl_shared.so" ) - endif() - endif() - endif() -endif() # case of shared STL linkage if( ANDROID_STL MATCHES "shared" AND DEFINED __libstl ) @@ -937,6 +1024,7 @@ if( ANDROID_STL MATCHES "shared" AND DEFINED __libstl ) endif() endif() + # ccache support __INIT_VARIABLE( _ndk_ccache NDK_CCACHE ENV_NDK_CCACHE ) if( _ndk_ccache ) @@ -946,16 +1034,27 @@ else() endif() unset( _ndk_ccache ) + # setup the cross-compiler if( NOT CMAKE_C_COMPILER ) if( NDK_CCACHE ) set( CMAKE_C_COMPILER "${NDK_CCACHE}" CACHE PATH "ccache as C compiler" ) set( CMAKE_CXX_COMPILER "${NDK_CCACHE}" CACHE PATH "ccache as C++ compiler" ) - set( CMAKE_C_COMPILER_ARG1 "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-gcc${TOOL_OS_SUFFIX}" CACHE PATH "gcc") - set( CMAKE_CXX_COMPILER_ARG1 "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-g++${TOOL_OS_SUFFIX}" CACHE PATH "g++") + if( ANDROID_COMPILER_IS_CLANG ) + set( CMAKE_C_COMPILER_ARG1 "${ANDROID_CLANG_TOOLCHAIN_ROOT}/bin/${_clang_name}${TOOL_OS_SUFFIX}" CACHE PATH "C compiler") + set( CMAKE_CXX_COMPILER_ARG1 "${ANDROID_CLANG_TOOLCHAIN_ROOT}/bin/${_clang_name}++${TOOL_OS_SUFFIX}" CACHE PATH "C++ compiler") + else() + set( CMAKE_C_COMPILER_ARG1 "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-gcc${TOOL_OS_SUFFIX}" CACHE PATH "C compiler") + set( CMAKE_CXX_COMPILER_ARG1 "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-g++${TOOL_OS_SUFFIX}" CACHE PATH "C++ compiler") + endif() else() - set( CMAKE_C_COMPILER "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-gcc${TOOL_OS_SUFFIX}" CACHE PATH "gcc" ) - set( CMAKE_CXX_COMPILER "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-g++${TOOL_OS_SUFFIX}" CACHE PATH "g++" ) + if( ANDROID_COMPILER_IS_CLANG ) + set( CMAKE_C_COMPILER "${ANDROID_CLANG_TOOLCHAIN_ROOT}/bin/${_clang_name}${TOOL_OS_SUFFIX}" CACHE PATH "C compiler") + set( CMAKE_CXX_COMPILER "${ANDROID_CLANG_TOOLCHAIN_ROOT}/bin/${_clang_name}++${TOOL_OS_SUFFIX}" CACHE PATH "C++ compiler") + else() + set( CMAKE_C_COMPILER "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-gcc${TOOL_OS_SUFFIX}" CACHE PATH "C compiler" ) + set( CMAKE_CXX_COMPILER "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-g++${TOOL_OS_SUFFIX}" CACHE PATH "C++ compiler" ) + endif() endif() set( CMAKE_ASM_COMPILER "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-gcc${TOOL_OS_SUFFIX}" CACHE PATH "assembler" ) set( CMAKE_STRIP "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_MACHINE_NAME}-strip${TOOL_OS_SUFFIX}" CACHE PATH "strip" ) @@ -982,15 +1081,22 @@ endif() # Force set compilers because standard identification works badly for us include( CMakeForceCompiler ) CMAKE_FORCE_C_COMPILER( "${CMAKE_C_COMPILER}" GNU ) +if( ANDROID_COMPILER_IS_CLANG ) + set( CMAKE_C_COMPILER_ID Clang) +endif() set( CMAKE_C_PLATFORM_ID Linux ) set( CMAKE_C_SIZEOF_DATA_PTR 4 ) set( CMAKE_C_HAS_ISYSROOT 1 ) set( CMAKE_C_COMPILER_ABI ELF ) CMAKE_FORCE_CXX_COMPILER( "${CMAKE_CXX_COMPILER}" GNU ) +if( ANDROID_COMPILER_IS_CLANG ) + set( CMAKE_CXX_COMPILER_ID Clang) +endif() set( CMAKE_CXX_PLATFORM_ID Linux ) set( CMAKE_CXX_SIZEOF_DATA_PTR 4 ) set( CMAKE_CXX_HAS_ISYSROOT 1 ) set( CMAKE_CXX_COMPILER_ABI ELF ) +set( CMAKE_CXX_SOURCE_FILE_EXTENSIONS cc cp cxx cpp CPP c++ C ) # force ASM compiler (required for CMake < 2.8.5) set( CMAKE_ASM_COMPILER_ID_RUN TRUE ) set( CMAKE_ASM_COMPILER_ID GNU ) @@ -1056,10 +1162,10 @@ if( ARMEABI_V7A ) elseif( VFPV3 ) set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -mfpu=vfpv3" ) else() - set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -mfpu=vfp" ) + set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -mfpu=vfpv3-d16" ) endif() elseif( ARMEABI_V6 ) - set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -march=armv6 -mfloat-abi=softfp -mfpu=vfp" ) + set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -march=armv6 -mfloat-abi=softfp -mfpu=vfp" ) # vfp == vfpv2 elseif( ARMEABI ) set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -march=armv5te -mtune=xscale -msoft-float" ) endif() @@ -1148,17 +1254,25 @@ if( ANDROID_FUNCTION_LEVEL_LINKING ) set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -Wl,--gc-sections" ) endif() -if( ANDROID_GOLD_LINKER AND CMAKE_HOST_UNIX AND (ARMEABI OR ARMEABI_V7A OR X86) AND ANDROID_COMPILER_VERSION VERSION_EQUAL "4.6" ) - set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -fuse-ld=gold" ) -elseif( ANDROID_NDK_RELEASE STREQUAL "r8b" AND ARMEABI AND ANDROID_COMPILER_VERSION VERSION_EQUAL "4.6" AND NOT _CMAKE_IN_TRY_COMPILE ) - message( WARNING "The default bfd linker from arm GCC 4.6 toolchain can fail with 'unresolvable R_ARM_THM_CALL relocation' error message. See https://code.google.com/p/android/issues/detail?id=35342 +if( ANDROID_COMPILER_VERSION VERSION_EQUAL "4.6" ) + if( ANDROID_GOLD_LINKER AND (CMAKE_HOST_UNIX OR ANDROID_NDK_RELEASE STRGREATER "r8b") AND (ARMEABI OR ARMEABI_V7A OR X86) ) + set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -fuse-ld=gold" ) + elseif( ANDROID_NDK_RELEASE STREQUAL "r8c") + set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -fuse-ld=bfd" ) + elseif( ANDROID_NDK_RELEASE STREQUAL "r8b" AND ARMEABI AND NOT _CMAKE_IN_TRY_COMPILE ) + message( WARNING "The default bfd linker from arm GCC 4.6 toolchain can fail with 'unresolvable R_ARM_THM_CALL relocation' error message. See https://code.google.com/p/android/issues/detail?id=35342 On Linux and OS X host platform you can workaround this problem using gold linker (default). - Rerun cmake with -DANDROID_GOLD_LINKER=ON option. + Rerun cmake with -DANDROID_GOLD_LINKER=ON option in case of problems. " ) -endif() + endif() +endif() # version 4.6 if( ANDROID_NOEXECSTACK ) - set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -Wa,--noexecstack" ) + if( ANDROID_COMPILER_IS_CLANG ) + set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -Xclang -mnoexecstack" ) + else() + set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -Wa,--noexecstack" ) + endif() set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -Wl,-z,noexecstack" ) endif() @@ -1166,6 +1280,22 @@ if( ANDROID_RELRO ) set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -Wl,-z,relro -Wl,-z,now" ) endif() +if( ANDROID_COMPILER_IS_CLANG ) + set( ANDROID_CXX_FLAGS "-Qunused-arguments ${ANDROID_CXX_FLAGS}" ) + if( ARMEABI_V7A AND NOT ANDROID_FORCE_ARM_BUILD ) + set( ANDROID_CXX_FLAGS_RELEASE "-target thumbv7-none-linux-androideabi ${ANDROID_CXX_FLAGS_RELEASE}" ) + set( ANDROID_CXX_FLAGS_DEBUG "-target ${ANDROID_LLVM_TRIPLE} ${ANDROID_CXX_FLAGS_DEBUG}" ) + else() + set( ANDROID_CXX_FLAGS "-target ${ANDROID_LLVM_TRIPLE} ${ANDROID_CXX_FLAGS}" ) + endif() + if( BUILD_WITH_ANDROID_NDK ) + if(ANDROID_ARCH_NAME STREQUAL "arm" ) + set( ANDROID_CXX_FLAGS "-isystem ${ANDROID_CLANG_TOOLCHAIN_ROOT}/lib/clang/${ANDROID_CLANG_VERSION}/include ${ANDROID_CXX_FLAGS}" ) + endif() + set( ANDROID_CXX_FLAGS "-gcc-toolchain ${ANDROID_TOOLCHAIN_ROOT} ${ANDROID_CXX_FLAGS}" ) + endif() +endif() + # cache flags set( CMAKE_CXX_FLAGS "" CACHE STRING "c++ flags" ) set( CMAKE_C_FLAGS "" CACHE STRING "c flags" ) @@ -1189,9 +1319,9 @@ set( CMAKE_MODULE_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} ${CMAKE_MODULE_LINKER_FL set( CMAKE_EXE_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} ${CMAKE_EXE_LINKER_FLAGS}" ) if( MIPS AND BUILD_WITH_ANDROID_NDK AND ANDROID_NDK_RELEASE STREQUAL "r8" ) - set( CMAKE_SHARED_LINKER_FLAGS "-Wl,-T,${ANDROID_NDK}/toolchains/${ANDROID_TOOLCHAIN_NAME}/mipself.xsc ${CMAKE_SHARED_LINKER_FLAGS}" ) - set( CMAKE_MODULE_LINKER_FLAGS "-Wl,-T,${ANDROID_NDK}/toolchains/${ANDROID_TOOLCHAIN_NAME}/mipself.xsc ${CMAKE_MODULE_LINKER_FLAGS}" ) - set( CMAKE_EXE_LINKER_FLAGS "-Wl,-T,${ANDROID_NDK}/toolchains/${ANDROID_TOOLCHAIN_NAME}/mipself.x ${CMAKE_EXE_LINKER_FLAGS}" ) + set( CMAKE_SHARED_LINKER_FLAGS "-Wl,-T,${ANDROID_NDK}/toolchains/${ANDROID_GCC_TOOLCHAIN_NAME}/mipself.xsc ${CMAKE_SHARED_LINKER_FLAGS}" ) + set( CMAKE_MODULE_LINKER_FLAGS "-Wl,-T,${ANDROID_NDK}/toolchains/${ANDROID_GCC_TOOLCHAIN_NAME}/mipself.xsc ${CMAKE_MODULE_LINKER_FLAGS}" ) + set( CMAKE_EXE_LINKER_FLAGS "-Wl,-T,${ANDROID_NDK}/toolchains/${ANDROID_GCC_TOOLCHAIN_NAME}/mipself.x ${CMAKE_EXE_LINKER_FLAGS}" ) endif() # configure rtti @@ -1218,6 +1348,19 @@ endif() include_directories( SYSTEM "${ANDROID_SYSROOT}/usr/include" ${ANDROID_STL_INCLUDE_DIRS} ) link_directories( "${CMAKE_INSTALL_PREFIX}/libs/${ANDROID_NDK_ABI_NAME}" ) +# setup output directories +set( LIBRARY_OUTPUT_PATH_ROOT ${CMAKE_SOURCE_DIR} CACHE PATH "root for library output, set this to change where android libs are installed to" ) +set( CMAKE_INSTALL_PREFIX "${ANDROID_TOOLCHAIN_ROOT}/user" CACHE STRING "path for installing" ) + +if(NOT _CMAKE_IN_TRY_COMPILE) + if( EXISTS "${CMAKE_SOURCE_DIR}/jni/CMakeLists.txt" ) + set( EXECUTABLE_OUTPUT_PATH "${LIBRARY_OUTPUT_PATH_ROOT}/bin/${ANDROID_NDK_ABI_NAME}" CACHE PATH "Output directory for applications" ) + else() + set( EXECUTABLE_OUTPUT_PATH "${LIBRARY_OUTPUT_PATH_ROOT}/bin" CACHE PATH "Output directory for applications" ) + endif() + set( LIBRARY_OUTPUT_PATH "${LIBRARY_OUTPUT_PATH_ROOT}/libs/${ANDROID_NDK_ABI_NAME}" CACHE PATH "path for android libs" ) +endif() + # set these global flags for cmake client scripts to change behavior set( ANDROID True ) set( BUILD_ANDROID True ) @@ -1335,7 +1478,7 @@ endif() # Variables controlling behavior or set by cmake toolchain: # ANDROID_ABI : "armeabi-v7a" (default), "armeabi", "armeabi-v7a with NEON", "armeabi-v7a with VFPV3", "armeabi-v6 with VFP", "x86", "mips" # ANDROID_NATIVE_API_LEVEL : 3,4,5,8,9,14 (depends on NDK version) -# ANDROID_SET_OBSOLETE_VARIABLES : ON/OFF +# ANDROID_STL : gnustl_static/gnustl_shared/stlport_static/stlport_shared/gabi++_static/gabi++_shared/system_re/system/none # ANDROID_FORBID_SYGWIN : ON/OFF # ANDROID_NO_UNDEFINED : ON/OFF # ANDROID_SO_UNDEFINED : OFF/ON (default depends on NDK version) @@ -1343,16 +1486,15 @@ endif() # ANDROID_GOLD_LINKER : ON/OFF # ANDROID_NOEXECSTACK : ON/OFF # ANDROID_RELRO : ON/OFF -# Variables that takes effect only at first run: # ANDROID_FORCE_ARM_BUILD : ON/OFF -# ANDROID_STL : gnustl_static/gnustl_shared/stlport_static/stlport_shared/gabi++_static/gabi++_shared/system_re/system/none # ANDROID_STL_FORCE_FEATURES : ON/OFF -# LIBRARY_OUTPUT_PATH_ROOT : -# NDK_CCACHE : +# ANDROID_SET_OBSOLETE_VARIABLES : ON/OFF # Can be set only at the first run: # ANDROID_NDK # ANDROID_STANDALONE_TOOLCHAIN -# ANDROID_TOOLCHAIN_NAME : "arm-linux-androideabi-4.4.3" or "arm-linux-androideabi-4.6" or "mipsel-linux-android-4.4.3" or "mipsel-linux-android-4.6" or "x86-4.4.3" or "x86-4.6" +# ANDROID_TOOLCHAIN_NAME : the NDK name of compiler toolchain +# LIBRARY_OUTPUT_PATH_ROOT : +# NDK_CCACHE : # Obsolete: # ANDROID_API_LEVEL : superseded by ANDROID_NATIVE_API_LEVEL # ARM_TARGET : superseded by ANDROID_ABI @@ -1375,10 +1517,11 @@ endif() # BUILD_WITH_STANDALONE_TOOLCHAIN : TRUE if standalone toolchain is used # ANDROID_NDK_HOST_SYSTEM_NAME : "windows", "linux-x86" or "darwin-x86" depending on host platform # ANDROID_NDK_ABI_NAME : "armeabi", "armeabi-v7a", "x86" or "mips" depending on ANDROID_ABI -# ANDROID_NDK_RELEASE : one of r5, r5b, r5c, r6, r6b, r7, r7b, r7c, r8, r8b; set only for NDK +# ANDROID_NDK_RELEASE : one of r5, r5b, r5c, r6, r6b, r7, r7b, r7c, r8, r8b, r8c; set only for NDK # ANDROID_ARCH_NAME : "arm" or "x86" or "mips" depending on ANDROID_ABI # ANDROID_SYSROOT : path to the compiler sysroot # TOOL_OS_SUFFIX : "" or ".exe" depending on host platform +# ANDROID_COMPILER_IS_CLANG : TRUE if clang compiler is used # Obsolete: # ARMEABI_NDK_NAME : superseded by ANDROID_NDK_ABI_NAME # @@ -1388,10 +1531,13 @@ endif() # ANDROID_SUPPORTED_ABIS : list of currently allowed values for ANDROID_ABI # ANDROID_TOOLCHAIN_MACHINE_NAME : "arm-linux-androideabi", "arm-eabi" or "i686-android-linux" # ANDROID_TOOLCHAIN_ROOT : path to the top level of toolchain (standalone or placed inside NDK) +# ANDROID_CLANG_TOOLCHAIN_ROOT : path to clang tools # ANDROID_SUPPORTED_NATIVE_API_LEVELS : list of native API levels found inside NDK # ANDROID_STL_INCLUDE_DIRS : stl include paths # ANDROID_RTTI : if rtti is enabled by the runtime # ANDROID_EXCEPTIONS : if exceptions are enabled by the runtime +# ANDROID_GCC_TOOLCHAIN_NAME : read-only, differs from ANDROID_TOOLCHAIN_NAME only if clang is used +# ANDROID_CLANG_VERSION : version of clang compiler if clang is used # # Defaults: # ANDROID_DEFAULT_NDK_API_LEVEL From 04481d9ef487df5e8c80d38dbf1fdeb4a4f81cb0 Mon Sep 17 00:00:00 2001 From: Andrey Kamaev Date: Mon, 19 Nov 2012 15:16:13 +0400 Subject: [PATCH 88/91] Fix Android build with clang compiler --- 3rdparty/libjasper/CMakeLists.txt | 1 + 3rdparty/libjpeg/CMakeLists.txt | 1 + 3rdparty/libtiff/CMakeLists.txt | 1 + 3rdparty/tbb/CMakeLists.txt | 5 +++++ cmake/OpenCVDetectCXXCompiler.cmake | 2 +- modules/contrib/src/detection_based_tracker.cpp | 2 ++ modules/core/include/opencv2/core/core.hpp | 4 ++-- modules/core/include/opencv2/core/operations.hpp | 2 +- samples/android/tutorial-3-native/jni/jni_part.cpp | 2 ++ samples/android/tutorial-4-mixed/jni/jni_part.cpp | 2 ++ 10 files changed, 18 insertions(+), 4 deletions(-) diff --git a/3rdparty/libjasper/CMakeLists.txt b/3rdparty/libjasper/CMakeLists.txt index a6fb71ec5..42855e2a6 100644 --- a/3rdparty/libjasper/CMakeLists.txt +++ b/3rdparty/libjasper/CMakeLists.txt @@ -24,6 +24,7 @@ if(WIN32 AND NOT MINGW) endif(WIN32 AND NOT MINGW) ocv_warnings_disable(CMAKE_C_FLAGS -Wno-implicit-function-declaration -Wno-uninitialized -Wmissing-prototypes -Wmissing-declarations -Wunused -Wshadow -Wsign-compare) +ocv_warnings_disable(CMAKE_C_FLAGS -Wunused-parameter) # clang ocv_warnings_disable(CMAKE_C_FLAGS /wd4013 /wd4018 /wd4101 /wd4244 /wd4267 /wd4715) # vs2005 if(UNIX) diff --git a/3rdparty/libjpeg/CMakeLists.txt b/3rdparty/libjpeg/CMakeLists.txt index 708e63e25..b4000a40a 100644 --- a/3rdparty/libjpeg/CMakeLists.txt +++ b/3rdparty/libjpeg/CMakeLists.txt @@ -26,6 +26,7 @@ if(CMAKE_COMPILER_IS_GNUCXX) endif() ocv_warnings_disable(CMAKE_C_FLAGS -Wcast-align -Wshadow -Wunused) +ocv_warnings_disable(CMAKE_C_FLAGS -Wunused-parameter) # clang set_target_properties(${JPEG_LIBRARY} PROPERTIES OUTPUT_NAME ${JPEG_LIBRARY} diff --git a/3rdparty/libtiff/CMakeLists.txt b/3rdparty/libtiff/CMakeLists.txt index 25ff0d94e..46fef61c7 100644 --- a/3rdparty/libtiff/CMakeLists.txt +++ b/3rdparty/libtiff/CMakeLists.txt @@ -89,6 +89,7 @@ endif(WIN32) ocv_warnings_disable(CMAKE_C_FLAGS -Wno-unused-but-set-variable -Wmissing-prototypes -Wmissing-declarations -Wundef -Wunused -Wsign-compare -Wcast-align -Wshadow -Wno-maybe-uninitialized -Wno-pointer-to-int-cast -Wno-int-to-pointer-cast) +ocv_warnings_disable(CMAKE_C_FLAGS -Wunused-parameter) # clang ocv_warnings_disable(CMAKE_CXX_FLAGS -Wmissing-declarations -Wunused-parameter) ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4018 /wd4100 /wd4127 /wd4311 /wd4701 /wd4706) # vs2005 ocv_warnings_disable(CMAKE_CXX_FLAGS /wd4244) # vs2008 diff --git a/3rdparty/tbb/CMakeLists.txt b/3rdparty/tbb/CMakeLists.txt index bf91f4d8b..2f1394999 100644 --- a/3rdparty/tbb/CMakeLists.txt +++ b/3rdparty/tbb/CMakeLists.txt @@ -123,6 +123,11 @@ add_definitions(-D__TBB_DYNAMIC_LOAD_ENABLED=0 #required -DDO_ITT_NOTIFY=0 #it seems that we don't need these notifications ) +if(ANDROID_COMPILER_IS_CLANG) + add_definitions(-D__TBB_GCC_BUILTIN_ATOMICS_PRESENT=1) + ocv_warnings_disable(CMAKE_CXX_FLAGS -Wmissing-prototypes) +endif() + if(tbb_need_GENERIC_DWORD_LOAD_STORE) #needed by TBB 4.0 update 1,2; fixed in TBB 4.0 update 3 but it has 2 new problems add_definitions(-D__TBB_USE_GENERIC_DWORD_LOAD_STORE=1) diff --git a/cmake/OpenCVDetectCXXCompiler.cmake b/cmake/OpenCVDetectCXXCompiler.cmake index 65edf72ed..d8c00cfdd 100644 --- a/cmake/OpenCVDetectCXXCompiler.cmake +++ b/cmake/OpenCVDetectCXXCompiler.cmake @@ -54,7 +54,7 @@ endif() # Detect GNU version: # ---------------------------------------------------------------------------- if(CMAKE_COMPILER_IS_GNUCXX) - execute_process(COMMAND ${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1} --version + execute_process(COMMAND ${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1} -dumpversion OUTPUT_VARIABLE CMAKE_OPENCV_GCC_VERSION_FULL OUTPUT_STRIP_TRAILING_WHITESPACE) diff --git a/modules/contrib/src/detection_based_tracker.cpp b/modules/contrib/src/detection_based_tracker.cpp index 5deb3b418..a1e5dea4d 100644 --- a/modules/contrib/src/detection_based_tracker.cpp +++ b/modules/contrib/src/detection_based_tracker.cpp @@ -1,6 +1,8 @@ #if defined(__linux__) || defined(LINUX) || defined(__APPLE__) || defined(ANDROID) #include "opencv2/contrib/detection_based_tracker.hpp" +#include + #define DEBUGLOGS 1 #ifdef ANDROID diff --git a/modules/core/include/opencv2/core/core.hpp b/modules/core/include/opencv2/core/core.hpp index 561d26b3a..0454cf4e9 100644 --- a/modules/core/include/opencv2/core/core.hpp +++ b/modules/core/include/opencv2/core/core.hpp @@ -204,11 +204,11 @@ CV_EXPORTS ErrorCallback redirectError( ErrorCallback errCallback, #ifdef __GNUC__ #define CV_Error( code, msg ) cv::error( cv::Exception(code, msg, __func__, __FILE__, __LINE__) ) #define CV_Error_( code, args ) cv::error( cv::Exception(code, cv::format args, __func__, __FILE__, __LINE__) ) -#define CV_Assert( expr ) if((expr)) ; else cv::error( cv::Exception(CV_StsAssert, #expr, __func__, __FILE__, __LINE__) ) +#define CV_Assert( expr ) if(!!(expr)) ; else cv::error( cv::Exception(CV_StsAssert, #expr, __func__, __FILE__, __LINE__) ) #else #define CV_Error( code, msg ) cv::error( cv::Exception(code, msg, "", __FILE__, __LINE__) ) #define CV_Error_( code, args ) cv::error( cv::Exception(code, cv::format args, "", __FILE__, __LINE__) ) -#define CV_Assert( expr ) if((expr)) ; else cv::error( cv::Exception(CV_StsAssert, #expr, "", __FILE__, __LINE__) ) +#define CV_Assert( expr ) if(!!(expr)) ; else cv::error( cv::Exception(CV_StsAssert, #expr, "", __FILE__, __LINE__) ) #endif #ifdef _DEBUG diff --git a/modules/core/include/opencv2/core/operations.hpp b/modules/core/include/opencv2/core/operations.hpp index 847daf8c2..e3ebe6e67 100644 --- a/modules/core/include/opencv2/core/operations.hpp +++ b/modules/core/include/opencv2/core/operations.hpp @@ -56,7 +56,7 @@ #define CV_XADD(addr,delta) _InterlockedExchangeAdd(const_cast(reinterpret_cast(addr)), delta) #elif defined __GNUC__ - #if defined __clang__ && __clang_major__ >= 3 + #if defined __clang__ && __clang_major__ >= 3 && !defined __ANDROID__ #ifdef __ATOMIC_SEQ_CST #define CV_XADD(addr, delta) __c11_atomic_fetch_add((_Atomic(int)*)(addr), (delta), __ATOMIC_SEQ_CST) #else diff --git a/samples/android/tutorial-3-native/jni/jni_part.cpp b/samples/android/tutorial-3-native/jni/jni_part.cpp index 2448948d1..fa3c857ab 100644 --- a/samples/android/tutorial-3-native/jni/jni_part.cpp +++ b/samples/android/tutorial-3-native/jni/jni_part.cpp @@ -8,6 +8,8 @@ using namespace std; using namespace cv; extern "C" { +JNIEXPORT void JNICALL Java_org_opencv_samples_tutorial3_Sample3Native_FindFeatures(JNIEnv*, jobject, jlong addrGray, jlong addrRgba); + JNIEXPORT void JNICALL Java_org_opencv_samples_tutorial3_Sample3Native_FindFeatures(JNIEnv*, jobject, jlong addrGray, jlong addrRgba) { Mat* pMatGr=(Mat*)addrGray; diff --git a/samples/android/tutorial-4-mixed/jni/jni_part.cpp b/samples/android/tutorial-4-mixed/jni/jni_part.cpp index 6b0b48ee8..0c395d629 100644 --- a/samples/android/tutorial-4-mixed/jni/jni_part.cpp +++ b/samples/android/tutorial-4-mixed/jni/jni_part.cpp @@ -8,6 +8,8 @@ using namespace std; using namespace cv; extern "C" { +JNIEXPORT void JNICALL Java_org_opencv_samples_tutorial4_Sample4Mixed_FindFeatures(JNIEnv*, jobject, jlong addrGray, jlong addrRgba); + JNIEXPORT void JNICALL Java_org_opencv_samples_tutorial4_Sample4Mixed_FindFeatures(JNIEnv*, jobject, jlong addrGray, jlong addrRgba) { Mat* pMatGr=(Mat*)addrGray; From 5b148083fea54d0f5c9b4f06ddb5c77652e72750 Mon Sep 17 00:00:00 2001 From: Alexander Smorkalov Date: Tue, 20 Nov 2012 17:17:22 +0400 Subject: [PATCH 89/91] Libinfo build fix; Libinfo revision formating fix; HW dependent VersionCode for Manager implemented. --- CMakeLists.txt | 2 +- android/libinfo/info.c | 2 +- android/service/engine/AndroidManifest.xml | 4 ++-- android/service/engine/CMakeLists.txt | 18 ++++++++++++++++++ 4 files changed, 22 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0502fb899..8707e0155 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -467,7 +467,7 @@ if(BUILD_ANDROID_PACKAGE) add_subdirectory(android/package) endif() -if (ANDROID AND NOT BUILD_ANDROID_SERVICE AND NOT BUILD_ANDROID_PACKAGE AND NOT BUILD_CAMERA_WRAPER) +if (ANDROID) add_subdirectory(android/libinfo) endif() diff --git a/android/libinfo/info.c b/android/libinfo/info.c index f1e5bf01e..f0c2dd6a2 100644 --- a/android/libinfo/info.c +++ b/android/libinfo/info.c @@ -7,7 +7,7 @@ const char* GetLibraryList(void); JNIEXPORT jstring JNICALL Java_org_opencv_android_StaticHelper_getLibraryList(JNIEnv *, jclass); #define PACKAGE_NAME "org.opencv.lib_v" CVAUX_STR(CV_MAJOR_VERSION) CVAUX_STR(CV_MINOR_VERSION) "_" ANDROID_PACKAGE_PLATFORM -#define PACKAGE_REVISION CVAUX_STR(CV_SUBMINOR_VERSION) CVAUX_STR(ANDROID_PACKAGE_RELEASE) +#define PACKAGE_REVISION CVAUX_STR(CV_SUBMINOR_VERSION) "." CVAUX_STR(ANDROID_PACKAGE_RELEASE) const char* GetPackageName(void) { diff --git a/android/service/engine/AndroidManifest.xml b/android/service/engine/AndroidManifest.xml index 1e0652494..fdf6303d9 100644 --- a/android/service/engine/AndroidManifest.xml +++ b/android/service/engine/AndroidManifest.xml @@ -1,8 +1,8 @@ + android:versionCode="22@ANDROID_PLATFORM_VERSION_CODE@" + android:versionName="2.2" > diff --git a/android/service/engine/CMakeLists.txt b/android/service/engine/CMakeLists.txt index 529aef9bd..b0d8425ca 100644 --- a/android/service/engine/CMakeLists.txt +++ b/android/service/engine/CMakeLists.txt @@ -4,6 +4,24 @@ set(JNI_LIB_NAME ${engine} ${engine}_jni) unset(__android_project_chain CACHE) add_android_project(opencv_engine "${CMAKE_CURRENT_SOURCE_DIR}" SDK_TARGET 8 ${ANDROID_SDK_TARGET} IGNORE_JAVA ON) +set(ANDROID_PLATFORM_VERSION_CODE "0") + +if(ARMEABI_V7A) + set(ANDROID_PLATFORM_VERSION_CODE "2") + elseif(ARMEABI_V6) + set(ANDROID_PLATFORM_VERSION_CODE "1") + elseif(ARMEABI) + set(ANDROID_PLATFORM_VERSION_CODE "1") + elseif(X86) + set(ANDROID_PLATFORM_VERSION_CODE "3") + elseif(MIPS) + set(ANDROID_PLATFORM_VERSION_CODE "4") + else() + message(WARNING "Can not automatically determine the value for ANDROID_PLATFORM_VERSION_CODE") + endif() + +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/${ANDROID_MANIFEST_FILE}" "${OpenCV_BINARY_DIR}/android/service/engine/.build/${ANDROID_MANIFEST_FILE}" @ONLY) + link_directories("${ANDROID_SOURCE_TREE}/out/target/product/generic/system/lib" "${ANDROID_SOURCE_TREE}/out/target/product/${ANDROID_PRODUCT}/system/lib" "${ANDROID_SOURCE_TREE}/bin/${ANDROID_ARCH_NAME}") # -D__SUPPORT_ARMEABI_FEATURES key is also available From cfd634ca3e43bd9144dca74c88c828f8d2c96b4d Mon Sep 17 00:00:00 2001 From: Andrey Pavlenko Date: Tue, 20 Nov 2012 18:27:03 +0400 Subject: [PATCH 90/91] Improving compatibility with the latest Android SDK (r21) and NDK (r8c). - Adding Android SDK/ADT r21 compatibility; - fixing stl headers path for new ndk; - fixing native API level for Android projects --- .../java/android_lib/.settings/org.eclipse.jdt.core.prefs | 5 ----- .../android_test/.settings/org.eclipse.jdt.core.prefs | 7 +++---- samples/android/15-puzzle/.project | 2 +- .../15-puzzle/.settings/org.eclipse.jdt.core.prefs | 6 +++--- .../.settings/org.eclipse.jdt.core.prefs | 7 +++---- samples/android/face-detection/.cproject | 8 ++++---- .../face-detection/.settings/org.eclipse.jdt.core.prefs | 7 +++---- samples/android/face-detection/jni/Application.mk | 1 + .../.settings/org.eclipse.jdt.core.prefs | 7 +++---- .../.settings/org.eclipse.jdt.core.prefs | 7 +++---- .../.settings/org.eclipse.jdt.core.prefs | 7 +++---- .../.settings/org.eclipse.jdt.core.prefs | 7 +++---- samples/android/tutorial-3-native/.cproject | 8 ++++---- .../.settings/org.eclipse.jdt.core.prefs | 7 +++---- samples/android/tutorial-3-native/jni/Application.mk | 1 + samples/android/tutorial-4-mixed/.cproject | 8 ++++---- .../tutorial-4-mixed/.settings/org.eclipse.jdt.core.prefs | 7 +++---- samples/android/tutorial-4-mixed/jni/Application.mk | 1 + 18 files changed, 46 insertions(+), 57 deletions(-) delete mode 100644 modules/java/android_lib/.settings/org.eclipse.jdt.core.prefs diff --git a/modules/java/android_lib/.settings/org.eclipse.jdt.core.prefs b/modules/java/android_lib/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index 53e049515..000000000 --- a/modules/java/android_lib/.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,5 +0,0 @@ -#Wed Jun 29 04:36:40 MSD 2011 -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 -org.eclipse.jdt.core.compiler.compliance=1.5 -org.eclipse.jdt.core.compiler.source=1.5 diff --git a/modules/java/android_test/.settings/org.eclipse.jdt.core.prefs b/modules/java/android_test/.settings/org.eclipse.jdt.core.prefs index 53e049515..b080d2ddc 100644 --- a/modules/java/android_test/.settings/org.eclipse.jdt.core.prefs +++ b/modules/java/android_test/.settings/org.eclipse.jdt.core.prefs @@ -1,5 +1,4 @@ -#Wed Jun 29 04:36:40 MSD 2011 eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 -org.eclipse.jdt.core.compiler.compliance=1.5 -org.eclipse.jdt.core.compiler.source=1.5 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.source=1.6 diff --git a/samples/android/15-puzzle/.project b/samples/android/15-puzzle/.project index d9387703f..e7ad66040 100644 --- a/samples/android/15-puzzle/.project +++ b/samples/android/15-puzzle/.project @@ -1,6 +1,6 @@ - 15-puzzle + OpenCV Sample - 15 puzzle diff --git a/samples/android/15-puzzle/.settings/org.eclipse.jdt.core.prefs b/samples/android/15-puzzle/.settings/org.eclipse.jdt.core.prefs index f77b31c2d..b080d2ddc 100644 --- a/samples/android/15-puzzle/.settings/org.eclipse.jdt.core.prefs +++ b/samples/android/15-puzzle/.settings/org.eclipse.jdt.core.prefs @@ -1,4 +1,4 @@ eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 -org.eclipse.jdt.core.compiler.compliance=1.5 -org.eclipse.jdt.core.compiler.source=1.5 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.source=1.6 diff --git a/samples/android/color-blob-detection/.settings/org.eclipse.jdt.core.prefs b/samples/android/color-blob-detection/.settings/org.eclipse.jdt.core.prefs index 53e049515..b080d2ddc 100644 --- a/samples/android/color-blob-detection/.settings/org.eclipse.jdt.core.prefs +++ b/samples/android/color-blob-detection/.settings/org.eclipse.jdt.core.prefs @@ -1,5 +1,4 @@ -#Wed Jun 29 04:36:40 MSD 2011 eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 -org.eclipse.jdt.core.compiler.compliance=1.5 -org.eclipse.jdt.core.compiler.source=1.5 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.source=1.6 diff --git a/samples/android/face-detection/.cproject b/samples/android/face-detection/.cproject index 4b8f95d19..f57ae9006 100644 --- a/samples/android/face-detection/.cproject +++ b/samples/android/face-detection/.cproject @@ -28,8 +28,8 @@