mirror of
https://github.com/opencv/opencv.git
synced 2024-11-25 03:30:34 +08:00
improvements in Haar CascadeClassifier: 1) use CV_32S instead of CV_32F for the integral of squares (which is more accurate and more efficient); 2) skip the window if its contrast is too low
This commit is contained in:
parent
036c438904
commit
5a94a95fbf
@ -318,6 +318,7 @@ static void integral_##suffix( T* src, size_t srcstep, ST* sum, size_t sumstep,
|
||||
{ integral_(src, srcstep, sum, sumstep, sqsum, sqsumstep, tilted, tiltedstep, size, cn); }
|
||||
|
||||
DEF_INTEGRAL_FUNC(8u32s, uchar, int, double)
|
||||
DEF_INTEGRAL_FUNC(8u32s32s, uchar, int, int)
|
||||
DEF_INTEGRAL_FUNC(8u32f64f, uchar, float, double)
|
||||
DEF_INTEGRAL_FUNC(8u64f64f, uchar, double, double)
|
||||
DEF_INTEGRAL_FUNC(16u64f64f, ushort, double, double)
|
||||
@ -505,6 +506,8 @@ void cv::integral( InputArray _src, OutputArray _sum, OutputArray _sqsum, Output
|
||||
func = (IntegralFunc)GET_OPTIMIZED(integral_8u32s);
|
||||
else if( depth == CV_8U && sdepth == CV_32S && sqdepth == CV_32F )
|
||||
func = (IntegralFunc)integral_8u32s32f;
|
||||
else if( depth == CV_8U && sdepth == CV_32S && sqdepth == CV_32S )
|
||||
func = (IntegralFunc)integral_8u32s32s;
|
||||
else if( depth == CV_8U && sdepth == CV_32F && sqdepth == CV_64F )
|
||||
func = (IntegralFunc)integral_8u32f64f;
|
||||
else if( depth == CV_8U && sdepth == CV_32F && sqdepth == CV_32F )
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -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));
|
||||
|
Loading…
Reference in New Issue
Block a user