【问题标题】:MeanShift formula understandingMeanShift公式理解
【发布时间】:2017-09-21 08:33:59
【问题描述】:

我正在实现用于对象跟踪的 MeanShift 算法,使用来自这里的想法:http://www.cse.psu.edu/~rtc12/CSE598C/meanShiftColor.pdf

现在我有后续帧的反投影图像。此类图像中的每个像素都标记了属于被跟踪对象的概率:

上述来源中的 MeanShift 公式如下所示:

w(xi) = 反投影图像中的像素。
x = 当前中心像素。

我不明白spatial kernel 是什么。
假设它可以是大小为 5x5 的 2D 高斯核,则 K(xi-x)*w(xi) 可以替换为 pre-图像模糊。

我的代码是这样的:

    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;
    }

所以我只是通过平滑的反投影图像进行迭代,并且对于每个像素:
将其值添加到分母
将其值乘以从当前中心到分母的偏移。

它在第二次迭代时收敛,但是 shift 是错误的,我不知道如何调试它。可能是公式实现中的问题。

请用人类语言向我解释什么是空间内核以及如何将其应用于权重图像。谢谢!

【问题讨论】:

    标签: image-processing video-tracking mean-shift back-projection


    【解决方案1】:

    嗯,我明白了。空间掩码是搜索窗口。反投影不需要模糊。应用于整个图像,1 位于搜索窗口内,0 位于外部。在this的第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;
        }
    

    【讨论】:

      猜你喜欢
      • 2019-11-22
      • 2013-10-02
      • 2011-04-05
      • 1970-01-01
      • 2015-03-08
      • 1970-01-01
      • 2022-08-16
      • 1970-01-01
      • 2016-12-05
      相关资源
      最近更新 更多