Понимание формулы MeanShift

Я реализую алгоритм MeanShift для отслеживания объектов, используя идеи здесь: http://www.cse.psu.edu/~rtc12/CSE598C/meanShiftColor.pdf

Теперь у меня есть изображение обратной проекции для последующего кадра. Каждый пиксель на таком изображении отмечает вероятность принадлежности к отслеживаемому объекту: введите описание изображения здесь

Формула MeanShift в вышеупомянутом источнике выглядит так: введите описание изображения здесь

w (xi) = пиксель в изображении обратной проекции.
х = текущий центральный пиксель.

Я не понимаю что такое spatial kernel,
Предполагая, что это может быть двумерное гауссово ядро ​​размером, скажем, 5x5, K (xi-x) * w (xi) можно заменить пикселем предварительно размытого изображения.

Мой код выглядит так:

    fvect2 findMeanShift(const PlainImage<uint8>& weights_smoothed, fvect2 old_center, DebugOutput& debug)
    {
        //LOGE("first center: %.2f %.2f", old_center.x, old_center.y);

        const int w=weights_smoothed.getWidth(), h=weights_smoothed.getHeight();

        int iter_count = 0;
        fvect2 total_shift(0.0,0.0);

        while(iter_count++ < 20)
        {
            fvect2 fTop(0,0);
            float fBottom=0.0;
            for(int y=0;y<h;++y)
                for(int x=0;x<w;++x)
                {
                    fvect2 cur_center(x, y);
                    float mult = weights_smoothed.at(x, y)[0]/255.0;
                    fBottom += mult;
                    fTop += (cur_center-old_center) * mult;
                }
            fvect2 mean_shift = fTop/fBottom;
            //printf("mean_shift: %.2f %.2f", mean_shift.x, mean_shift.y);

            debug.addArrow(old_center, old_center+mean_shift);

            old_center += mean_shift;
            //printf("old_center: %.2f %.2f", old_center.x, old_center.y);

            total_shift += mean_shift;

            if(mean_shift.lengthF()<0.1)
                break;
        }

        return total_shift;
    }

Поэтому я просто повторяю по сглаженному изображению обратной проекции и для каждого пикселя:
добавить его значение к знаменателю
добавьте его значение, умноженное на смещение от текущего центра к денумератору.

Он сходится на второй итерации, но сдвиг неправильный, и я не знаю, как его отладить. Вероятно, проблема в реализации формулы. введите описание изображения здесь

Пожалуйста, объясните мне на человеческом языке, что такое пространственное ядро ​​и как применить его к весовому изображению. Спасибо!

2 ответа

Решение

Ну я поняла Пространственная маска - это окно поиска. Обратное проецирование не должно быть размытым. Применяя ко всему изображению, 1внутри окна поиска и 0на улице. На странице 2 это более простое объяснение.

Если искать вдали от отслеживаемого объекта, результаты плохие. Таким образом, неправильная точка смещения в вопросе, вероятно, является центром масс всего изображения.

Теперь мой функционал выглядит так:

    fvect2 findMeanShift(const PlainImage<uint8>& weights, const ImageRect& spatial_roi, fvect2 old_center, DebugOutput& debug)
    {
        const int w=weights.getWidth(), h=weights.getHeight();

        int iter_count = 0;
        fvect2 total_shift(0.0,0.0);

        while(iter_count++ < 20)
        {
            fvect2 fTop(0,0);
            float fBottom=0.0;

            for(int y=std::max(spatial_roi.m_y, 0);y<std::min(h, spatial_roi.m_y+spatial_roi.m_height);++y)
                for(int x=std::max(spatial_roi.m_x, 0);x<std::min(w, spatial_roi.m_x+spatial_roi.m_width);++x)
                {
                    assert(y>=0 && x>=0 && y<h && x<w);

                    fvect2 cur_center(x, y);
                    float mult = weights.at(x, y)[0]/255.0;
                    fBottom += mult;
                    fTop += (cur_center-old_center) * mult;
                }
            fvect2 mean_shift = fTop/fBottom;
            //LOGE("mean_shift: %.2f %.2f", mean_shift.x, mean_shift.y);

            debug.addArrow(old_center, old_center+mean_shift);

            old_center += mean_shift;
            //LOGE("old_center: %.2f %.2f", old_center.x, old_center.y);

            total_shift += mean_shift;

            if(mean_shift.lengthF()<0.1)
                break;
        }

        return total_shift;
    }

(xi-x) — расстояние от центроида до характерной точки. Если вы используете ядро ​​Гаусса, вычислите 1/sqrt(2pi)*exp(-0,5(xi-x)**2), который представляет собой пространственный вес. Кончик этого ядра находится в центроиде.

Другие вопросы по тегам