Функции Виолы и Джонса Хаара в OpenCV 4.0.0 - PullRequest
0 голосов
/ 22 марта 2019

В haarfeatures.cpp в OpenCV я вижу следующую реализацию функций 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 конфигурация:

enter image description here

, поэтому первый прямоугольник (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, конфигурация:

enter image description here

Здесь первый прямоугольник (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) конфигурация:

enter image description here

, поэтому первый прямоугольник (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 говорится, что

"Функция трех прямоугольников вычисляет сумму в двух внешних прямоугольниках, вычтенных изсумма в центре прямоугольника "

enter image description here

Я читаю это как B - (A + C), а не 2 * B- (A + C)!.

Я что-то здесь упускаю?или это ошибка?Кто-нибудь может это подтвердить?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...