Merge pull request #4074 from vpisarev:objdetect_fixes

This commit is contained in:
Vadim Pisarevsky
2015-05-28 19:43:51 +00:00
9 changed files with 331 additions and 31 deletions

View File

@@ -627,33 +627,33 @@ void HaarEvaluator::computeChannels(int scaleIdx, InputArray img)
int sqy = sy + (sqofs / sbufSize.width);
UMat sum(usbuf, Rect(sx, sy, s.szi.width, s.szi.height));
UMat sqsum(usbuf, Rect(sx, sqy, s.szi.width, s.szi.height));
sqsum.flags = (sqsum.flags & ~UMat::DEPTH_MASK) | CV_32F;
sqsum.flags = (sqsum.flags & ~UMat::DEPTH_MASK) | CV_32S;
if (hasTiltedFeatures)
{
int sty = sy + (tofs / sbufSize.width);
UMat tilted(usbuf, Rect(sx, sty, s.szi.width, s.szi.height));
integral(img, sum, sqsum, tilted, CV_32S, CV_32F);
integral(img, sum, sqsum, tilted, CV_32S, CV_32S);
}
else
{
UMatData* u = sqsum.u;
integral(img, sum, sqsum, noArray(), CV_32S, CV_32F);
CV_Assert(sqsum.u == u && sqsum.size() == s.szi && sqsum.type()==CV_32F);
integral(img, sum, sqsum, noArray(), CV_32S, CV_32S);
CV_Assert(sqsum.u == u && sqsum.size() == s.szi && sqsum.type()==CV_32S);
}
}
else
{
Mat sum(s.szi, CV_32S, sbuf.ptr<int>() + s.layer_ofs, sbuf.step);
Mat sqsum(s.szi, CV_32F, sum.ptr<int>() + sqofs, sbuf.step);
Mat sqsum(s.szi, CV_32S, sum.ptr<int>() + sqofs, sbuf.step);
if (hasTiltedFeatures)
{
Mat tilted(s.szi, CV_32S, sum.ptr<int>() + tofs, sbuf.step);
integral(img, sum, sqsum, tilted, CV_32S, CV_32F);
integral(img, sum, sqsum, tilted, CV_32S, CV_32S);
}
else
integral(img, sum, sqsum, noArray(), CV_32S, CV_32F);
integral(img, sum, sqsum, noArray(), CV_32S, CV_32S);
}
}
@@ -689,18 +689,23 @@ bool HaarEvaluator::setWindow( Point pt, int scaleIdx )
return false;
pwin = &sbuf.at<int>(pt) + s.layer_ofs;
const float* pq = (const float*)(pwin + sqofs);
const int* pq = (const int*)(pwin + sqofs);
int valsum = CALC_SUM_OFS(nofs, pwin);
float valsqsum = CALC_SUM_OFS(nofs, pq);
unsigned valsqsum = (unsigned)(CALC_SUM_OFS(nofs, pq));
double nf = (double)normrect.area() * valsqsum - (double)valsum * valsum;
double area = normrect.area();
double nf = area * valsqsum - (double)valsum * valsum;
if( nf > 0. )
{
nf = std::sqrt(nf);
varianceNormFactor = (float)(1./nf);
return area*varianceNormFactor < 1e-1;
}
else
nf = 1.;
varianceNormFactor = (float)(1./nf);
return true;
{
varianceNormFactor = 1.f;
return false;
}
}
@@ -1402,8 +1407,10 @@ bool CascadeClassifierImpl::Data::read(const FileNode &root)
else if( featureTypeStr == CC_LBP )
featureType = FeatureEvaluator::LBP;
else if( featureTypeStr == CC_HOG )
{
featureType = FeatureEvaluator::HOG;
CV_Error(Error::StsNotImplemented, "HOG cascade is not supported in 3.0");
}
else
return false;
@@ -1580,6 +1587,43 @@ bool CascadeClassifier::read(const FileNode &root)
return ok;
}
void clipObjects(Size sz, std::vector<Rect>& objects,
std::vector<int>* a, std::vector<double>* b)
{
size_t i, j = 0, n = objects.size();
Rect win0 = Rect(0, 0, sz.width, sz.height);
if(a)
{
CV_Assert(a->size() == n);
}
if(b)
{
CV_Assert(b->size() == n);
}
for( i = 0; i < n; i++ )
{
Rect r = win0 & objects[i];
if( r.area() > 0 )
{
objects[j] = r;
if( i > j )
{
if(a) a->at(j) = a->at(i);
if(b) b->at(j) = b->at(i);
}
j++;
}
}
if( j < n )
{
objects.resize(j);
if(a) a->resize(j);
if(b) b->resize(j);
}
}
void CascadeClassifier::detectMultiScale( InputArray image,
CV_OUT std::vector<Rect>& objects,
double scaleFactor,
@@ -1589,6 +1633,7 @@ void CascadeClassifier::detectMultiScale( InputArray image,
{
CV_Assert(!empty());
cc->detectMultiScale(image, objects, scaleFactor, minNeighbors, flags, minSize, maxSize);
clipObjects(image.size(), objects, 0, 0);
}
void CascadeClassifier::detectMultiScale( InputArray image,
@@ -1601,6 +1646,7 @@ void CascadeClassifier::detectMultiScale( InputArray image,
CV_Assert(!empty());
cc->detectMultiScale(image, objects, numDetections,
scaleFactor, minNeighbors, flags, minSize, maxSize);
clipObjects(image.size(), objects, &numDetections, 0);
}
void CascadeClassifier::detectMultiScale( InputArray image,
@@ -1616,6 +1662,7 @@ void CascadeClassifier::detectMultiScale( InputArray image,
cc->detectMultiScale(image, objects, rejectLevels, levelWeights,
scaleFactor, minNeighbors, flags,
minSize, maxSize, outputRejectLevels);
clipObjects(image.size(), objects, &rejectLevels, &levelWeights);
}
bool CascadeClassifier::isOldFormatCascade() const

View File

@@ -5,6 +5,9 @@
namespace cv
{
void clipObjects(Size sz, std::vector<Rect>& objects,
std::vector<int>* a, std::vector<double>* b);
class FeatureEvaluator
{
public:

View File

@@ -41,6 +41,7 @@
//M*/
#include "precomp.hpp"
#include "cascadedetect.hpp"
#include "opencv2/core/core_c.h"
#include "opencl_kernels_objdetect.hpp"
@@ -1823,7 +1824,9 @@ static bool ocl_detectMultiScale(InputArray _img, std::vector<Rect> &found_locat
all_candidates.push_back(Rect(Point2d(locations[j]) * scale, scaled_win_size));
}
found_locations.assign(all_candidates.begin(), all_candidates.end());
cv::groupRectangles(found_locations, (int)group_threshold, 0.2);
groupRectangles(found_locations, (int)group_threshold, 0.2);
clipObjects(imgSize, found_locations, 0, 0);
return true;
}
#endif //HAVE_OPENCL
@@ -1879,6 +1882,7 @@ void HOGDescriptor::detectMultiScale(
groupRectangles_meanshift(foundLocations, foundWeights, foundScales, finalThreshold, winSize);
else
groupRectangles(foundLocations, foundWeights, (int)finalThreshold, 0.2);
clipObjects(imgSize, foundLocations, 0, &foundWeights);
}
void HOGDescriptor::detectMultiScale(InputArray img, std::vector<Rect>& foundLocations,

View File

@@ -160,7 +160,7 @@ void runHaarClassifier(
__global const int* psum = psum1;
#endif
__global const float* psqsum = (__global const float*)(psum1 + sqofs);
__global const int* psqsum = (__global const int*)(psum1 + sqofs);
float sval = (psum[nofs.x] - psum[nofs.y] - psum[nofs.z] + psum[nofs.w])*invarea;
float sqval = (psqsum[nofs0.x] - psqsum[nofs0.y] - psqsum[nofs0.z] + psqsum[nofs0.w])*invarea;
float nf = (float)normarea * sqrt(max(sqval - sval * sval, 0.f));