add NMS according to Dollar's paper.
This commit is contained in:
		@@ -534,12 +534,14 @@ public:
 | 
			
		||||
        int shrinkage;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    enum { NO_REJECT = 1, DOLLAR = 2, /*PASCAL = 4,*/ DEFAULT = NO_REJECT};
 | 
			
		||||
 | 
			
		||||
    // 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.
 | 
			
		||||
    CV_WRAP 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 rejCriteria = 1);
 | 
			
		||||
 | 
			
		||||
    CV_WRAP virtual ~SCascade();
 | 
			
		||||
 | 
			
		||||
@@ -571,7 +573,7 @@ private:
 | 
			
		||||
    double maxScale;
 | 
			
		||||
 | 
			
		||||
    int   scales;
 | 
			
		||||
    int   rejfactor;
 | 
			
		||||
    int   rejCriteria;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
CV_EXPORTS bool initModule_objdetect(void);
 | 
			
		||||
 
 | 
			
		||||
@@ -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, "rejCriteria", obj.rejCriteria));
 | 
			
		||||
 | 
			
		||||
bool initModule_objdetect(void)
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -422,7 +422,7 @@ struct cv::SCascade::Fields
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
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) {}
 | 
			
		||||
: fields(0), minScale(mins), maxScale(maxs), scales(nsc), rejCriteria(rej) {}
 | 
			
		||||
 | 
			
		||||
cv::SCascade::~SCascade() { delete fields;}
 | 
			
		||||
 | 
			
		||||
@@ -439,6 +439,68 @@ bool cv::SCascade::load(const FileNode& fn)
 | 
			
		||||
    return fields->fill(fn);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
namespace {
 | 
			
		||||
typedef cv::SCascade::Detection Detection;
 | 
			
		||||
typedef std::vector<Detection>  dvector;
 | 
			
		||||
 | 
			
		||||
struct NMS
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    virtual ~NMS(){}
 | 
			
		||||
    virtual void apply(dvector& objects) const = 0;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
struct ConfidenceLess
 | 
			
		||||
{
 | 
			
		||||
    bool operator()(const Detection& a, const Detection& b) const
 | 
			
		||||
    {
 | 
			
		||||
        return a.confidence > b.confidence;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct DollarNMS: public NMS
 | 
			
		||||
{
 | 
			
		||||
    virtual ~DollarNMS(){}
 | 
			
		||||
 | 
			
		||||
    static float overlap(const cv::Rect &a, const cv::Rect &b)
 | 
			
		||||
    {
 | 
			
		||||
        int w = std::min(a.x + a.width,  b.x + b.width)  - std::max(a.x, b.x);
 | 
			
		||||
        int h = std::min(a.y + a.height, b.y + b.height) - std::max(a.y, b.y);
 | 
			
		||||
 | 
			
		||||
        return (w < 0 || h < 0)? 0.f : (float)(w * h);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual void apply(dvector& objects) const
 | 
			
		||||
    {
 | 
			
		||||
        std::sort(objects.begin(), objects.end(), ConfidenceLess());
 | 
			
		||||
 | 
			
		||||
        for (dvector::iterator dIt = objects.begin(); dIt != objects.end(); ++dIt)
 | 
			
		||||
        {
 | 
			
		||||
            const Detection &a = *dIt;
 | 
			
		||||
            for (dvector::iterator next = dIt + 1; next != objects.end(); )
 | 
			
		||||
            {
 | 
			
		||||
                const Detection &b = *next;
 | 
			
		||||
 | 
			
		||||
                const float ovl =  overlap(a.bb, b.bb) / std::min(a.bb.area(), b.bb.area());
 | 
			
		||||
 | 
			
		||||
                if (ovl > 0.65f)
 | 
			
		||||
                    next = objects.erase(next);
 | 
			
		||||
                else
 | 
			
		||||
                    ++next;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
cv::Ptr<NMS> createNMS(int type)
 | 
			
		||||
{
 | 
			
		||||
    CV_Assert(type == cv::SCascade::DOLLAR);
 | 
			
		||||
    return cv::Ptr<NMS>(new DollarNMS);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cv::SCascade::detectNoRoi(const cv::Mat& image, std::vector<Detection>& objects) const
 | 
			
		||||
{
 | 
			
		||||
    Fields& fld = *fields;
 | 
			
		||||
@@ -459,6 +521,9 @@ void cv::SCascade::detectNoRoi(const cv::Mat& image, std::vector<Detection>& obj
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (rejCriteria != NO_REJECT)
 | 
			
		||||
        createNMS(rejCriteria)->apply(objects);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cv::SCascade::detect(cv::InputArray _image, cv::InputArray _rois, std::vector<Detection>& objects) const
 | 
			
		||||
@@ -506,6 +571,9 @@ void cv::SCascade::detect(cv::InputArray _image, cv::InputArray _rois, std::vect
 | 
			
		||||
             }
 | 
			
		||||
         }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (rejCriteria != NO_REJECT)
 | 
			
		||||
    	createNMS(rejCriteria)->apply(objects);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cv::SCascade::detect(InputArray _image, InputArray _rois,  OutputArray _rects, OutputArray _confs) const
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user