在OpenCV的haarfeatures.cpp
中,我看到了V&J Haar功能的以下实现:
void CvHaarEvaluator::generateFeatures()
{
int mode = ((const CvHaarFeatureParams*)((CvFeatureParams*)featureParams))->mode;
int offset = winSize.width + 1;
for( int x = 0; x < winSize.width; x++ )
{
for( int y = 0; y < winSize.height; y++ )
{
for( int dx = 1; dx <= winSize.width; dx++ )
{
for( int dy = 1; dy <= winSize.height; dy++ )
{
// haar_x2
if ( (x+dx*2 <= winSize.width) && (y+dy <= winSize.height) )
{
features.push_back( Feature( offset, false,
x, y, dx*2, dy, -1,
x+dx, y, dx , dy, +2 ) );
}
// haar_y2
if ( (x+dx <= winSize.width) && (y+dy*2 <= winSize.height) )
{
features.push_back( Feature( offset, false,
x, y, dx, dy*2, -1,
x, y+dy, dx, dy, +2 ) );
}
// haar_x3
if ( (x+dx*3 <= winSize.width) && (y+dy <= winSize.height) )
{
features.push_back( Feature( offset, false,
x, y, dx*3, dy, -1,
x+dx, y, dx , dy, +3 ) );
}
// haar_y3
if ( (x+dx <= winSize.width) && (y+dy*3 <= winSize.height) )
{
features.push_back( Feature( offset, false,
x, y, dx, dy*3, -1,
x, y+dy, dx, dy, +3 ) );
}
// x2_y2
if ( (x+dx*2 <= winSize.width) && (y+dy*2 <= winSize.height) )
{
features.push_back( Feature( offset, false,
x, y, dx*2, dy*2, -1,
x, y, dx, dy, +2,
x+dx, y+dy, dx, dy, +2 ) );
}
}
}
}
}
numFeatures = (int)features.size();
}
每个特征由两个(haar_x2,haar_y2,haar_x3,haar_y3)或三个(x2_y2)矩形和相应权重表示,以便从积分图像计算特征。
inline float CvHaarEvaluator::Feature::calc( const cv::Mat &_sum, const cv::Mat &_tilted, size_t y) const
{
const int* img = tilted ? _tilted.ptr<int>((int)y) : _sum.ptr<int>((int)y);
float ret = rect[0].weight * (img[fastRect[0].p0] - img[fastRect[0].p1] - img[fastRect[0].p2] + img[fastRect[0].p3] ) +
rect[1].weight * (img[fastRect[1].p0] - img[fastRect[1].p1] - img[fastRect[1].p2] + img[fastRect[1].p3] );
if( rect[2].weight != 0.0f )
ret += rect[2].weight * (img[fastRect[2].p0] - img[fastRect[2].p1] - img[fastRect[2].p2] + img[fastRect[2].p3] );
return ret;
}
对于haar_x2,配置为:
所以第一个矩形(x, y, dx*2, dy)
代表总和A + B(权重为-1)
第二个矩形(x+dx, y, dx, dy)
仅代表B(权重为+2)
与权重求和得出-(A + B)+ 2 * B = B-A。 haar_y2也是如此
对于x2_y2,配置为:
第一个矩形(x, y, dx*2, dy*2)
代表(A + B + C + D),
第二个矩形(x, y, dx, dy)
代表A
第三个矩形(x+dx, y+dy, dx, dy)
代表D
所以权重为-(A + B + C + D)+ 2 * A + 2 * D = A + D-(B + C)
尽我们所能。
但是对于haar_x3(和y3),配置为:
所以第一个矩形(x, y, dx*3, dy)
代表(A + B + C)
第二个矩形(x+dx, y, dx, dy)
代表B。
现在,有了权重,我们得到-(A + B + C)+ 3 * B = 2 * B-(A + C) 而V&J论文指出
“三个矩形特征计算两个外部之和 从中心矩形的总和中减去的矩形”
我将其读为B-(A + C),而不是2 * B-(A + C)!。
我在这里错过了什么吗?还是这是一个错误?有人可以确认吗?