mirror of
https://github.com/opencv/opencv.git
synced 2024-11-28 21:20:18 +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); }
|
{ integral_(src, srcstep, sum, sumstep, sqsum, sqsumstep, tilted, tiltedstep, size, cn); }
|
||||||
|
|
||||||
DEF_INTEGRAL_FUNC(8u32s, uchar, int, double)
|
DEF_INTEGRAL_FUNC(8u32s, uchar, int, double)
|
||||||
|
DEF_INTEGRAL_FUNC(8u32s32s, uchar, int, int)
|
||||||
DEF_INTEGRAL_FUNC(8u32f64f, uchar, float, double)
|
DEF_INTEGRAL_FUNC(8u32f64f, uchar, float, double)
|
||||||
DEF_INTEGRAL_FUNC(8u64f64f, uchar, double, double)
|
DEF_INTEGRAL_FUNC(8u64f64f, uchar, double, double)
|
||||||
DEF_INTEGRAL_FUNC(16u64f64f, ushort, 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);
|
func = (IntegralFunc)GET_OPTIMIZED(integral_8u32s);
|
||||||
else if( depth == CV_8U && sdepth == CV_32S && sqdepth == CV_32F )
|
else if( depth == CV_8U && sdepth == CV_32S && sqdepth == CV_32F )
|
||||||
func = (IntegralFunc)integral_8u32s32f;
|
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 )
|
else if( depth == CV_8U && sdepth == CV_32F && sqdepth == CV_64F )
|
||||||
func = (IntegralFunc)integral_8u32f64f;
|
func = (IntegralFunc)integral_8u32f64f;
|
||||||
else if( depth == CV_8U && sdepth == CV_32F && sqdepth == CV_32F )
|
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);
|
int sqy = sy + (sqofs / sbufSize.width);
|
||||||
UMat sum(usbuf, Rect(sx, sy, s.szi.width, s.szi.height));
|
UMat sum(usbuf, Rect(sx, sy, s.szi.width, s.szi.height));
|
||||||
UMat sqsum(usbuf, Rect(sx, sqy, 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)
|
if (hasTiltedFeatures)
|
||||||
{
|
{
|
||||||
int sty = sy + (tofs / sbufSize.width);
|
int sty = sy + (tofs / sbufSize.width);
|
||||||
UMat tilted(usbuf, Rect(sx, sty, s.szi.width, s.szi.height));
|
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
|
else
|
||||||
{
|
{
|
||||||
UMatData* u = sqsum.u;
|
UMatData* u = sqsum.u;
|
||||||
integral(img, sum, sqsum, noArray(), CV_32S, CV_32F);
|
integral(img, sum, sqsum, noArray(), CV_32S, CV_32S);
|
||||||
CV_Assert(sqsum.u == u && sqsum.size() == s.szi && sqsum.type()==CV_32F);
|
CV_Assert(sqsum.u == u && sqsum.size() == s.szi && sqsum.type()==CV_32S);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Mat sum(s.szi, CV_32S, sbuf.ptr<int>() + s.layer_ofs, sbuf.step);
|
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)
|
if (hasTiltedFeatures)
|
||||||
{
|
{
|
||||||
Mat tilted(s.szi, CV_32S, sum.ptr<int>() + tofs, sbuf.step);
|
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
|
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;
|
return false;
|
||||||
|
|
||||||
pwin = &sbuf.at<int>(pt) + s.layer_ofs;
|
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);
|
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. )
|
if( nf > 0. )
|
||||||
|
{
|
||||||
nf = std::sqrt(nf);
|
nf = std::sqrt(nf);
|
||||||
|
varianceNormFactor = (float)(1./nf);
|
||||||
|
return area*varianceNormFactor < 1e-1;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
nf = 1.;
|
{
|
||||||
varianceNormFactor = (float)(1./nf);
|
varianceNormFactor = 1.f;
|
||||||
|
return false;
|
||||||
return true;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -160,7 +160,7 @@ void runHaarClassifier(
|
|||||||
__global const int* psum = psum1;
|
__global const int* psum = psum1;
|
||||||
#endif
|
#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 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 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));
|
float nf = (float)normarea * sqrt(max(sqval - sval * sval, 0.f));
|
||||||
|
Loading…
Reference in New Issue
Block a user