我正在研究this paper中描述的GMG背景扣除算法。由于OpenCV 3.0还具有GMG算法的实现(作为附加包opencv_contrib),因此我尝试一起研究两者。但是,我不确定这两个参数maxFeaturesquantizationLevels的含义,因为我想将它们映射到本文的描述中。

引用OpenCV 3.0中的源代码(文件模块\ bgsegm \ src \ bgfg_gmg.cpp):

//! Total number of distinct colors to maintain in histogram.
int maxFeatures;


//! Number of discrete levels in each channel to be used in histograms.
int quantizationLevels;

并引用该论文(第II B部分)(由于此处不支持LaTex,因此修改了一些数学符号和变量名):

“...在T个观察到的特征中,选择F_tot F_max,则观察到的不同特征的数量F_tot可能会超过极限F_max。在这种情况下,我们丢弃最旧的观测值,以使F_tot
通过以上描述,我最初确信OpenCV 3.0中的maxFeatures指的是F_max,而quantizationLevels指的是F_tot。但是,这听起来不对,原因有二:(1)本文提到“F_tot是观察到的不同特征的数量”,并且(2)OpenCV源代码在maxFeaturesquantizationLevels之间没有任何关系,尽管本文很清楚建议前者应大于或等于后者。

那么,maxFeaturesquantizationLevels的含义是什么? quantizationLevels是OpenCV引入的用于计算直方图的参数吗?

最佳答案

在进一步研究OpenCV中的源代码之后,我相信maxFeatures指的是F_max,而quantizationLevels实际上是直方图中的bin数。原因如下:

insertFeature()函数中,该函数包含以下代码:

static bool insertFeature(unsigned int color, float weight, unsigned int* colors, float* weights, int& nfeatures, int maxFeatures)
{
    int idx = -1;
    for (int i = 0; i < nfeatures; ++i) {
        if (color == colors[i]) {
            // feature in histogram
            weight += weights[i];
            idx = i;
            break;
        }
    }
    if (idx >= 0) {                          // case 1
        // move feature to beginning of list
        ::memmove(colors + 1, colors, idx * sizeof(unsigned int));
        ::memmove(weights + 1, weights, idx * sizeof(float));
        colors[0] = color;
        weights[0] = weight;
    }
    else if (nfeatures == maxFeatures) {     // case 2
        // discard oldest feature
        ::memmove(colors + 1, colors, (nfeatures - 1) * sizeof(unsigned int));
        ::memmove(weights + 1, weights, (nfeatures - 1) * sizeof(float));
        colors[0] = color;
        weights[0] = weight;
    }
    else {                                   // case 3
        colors[nfeatures] = color;
        weights[nfeatures] = weight;
        ++nfeatures;
        return true;
    }
    return false;
}

情况1:当颜色与colors[]数组中的一项匹配时,将获得相应的数组元素。

情况2:当颜色与colors[]数组中的任何项目都不匹配并且达到maxFeatures(nFeatures存储数组中存储的项目数)时,将为新颜色删除最旧的功能。

情况3:当颜色与colors[]数组中的任何项目都不匹配并且maxFeatures尚未达到时,将颜色添加到数组的新项目中,并且nFeatures递增1。

因此,maxFeatures应该对应于论文中的F_max(最大特征数)。

另外,在函数apply()中:
static unsigned int apply(const void* src_, int x, int cn, double minVal, double maxVal, int quantizationLevels)
{
    const T* src = static_cast<const T*>(src_);
    src += x * cn;

    unsigned int res = 0;
    for (int i = 0, shift = 0; i < cn; ++i, ++src, shift += 8)
        res |= static_cast<int>((*src - minVal) * quantizationLevels / (maxVal - minVal)) << shift;

    return res;
}

此函数根据src_maxValminVal的值将指针quantizationLevels指向的像素的颜色强度映射到bin,这样,如果quantizationLevels = q,则代码的结果为:
static_cast<int>((*src - minVal) * quantizationLevels / (maxVal - minVal))

必须为[0,q-1]范围内的整数。但是,可能存在cn通道(例如,在RGB中,cn = 3,因此,移位操作和可能的bin数量(表示为b)因此是quantizationLevels等于cn的幂。因此,如果b> F_max,我们必须舍弃(b-F_max)最旧的特征。

因此,在OpenCV中,如果我们将maxFeatures设置为> = quantizationLevels ^ cn,那么我们就不必丢弃最旧的功能,因为我们允许的存储箱数量足够多,或不同的独特功能也足够多。

10-02 03:59