【问题标题】:How to use Mahalanobis Distance in libfacerec while preforming PCA in OPENCV v2 API?在 OPENCV v2 API 中执行 PCA 时,如何在 libfacerec 中使用 Mahalanobis 距离?
【发布时间】:2012-05-21 08:22:44
【问题描述】:

我正在从事人脸识别项目,我正在使用 libfacerec。在预测标签时,库使用计算绝对差的 norm()。如何使用 Mahalanobis 距离来提高准确性? OpenCV2有一个功能:

double Mahalanobis(InputArray vec1, InputArray vec2, InputArray icovar)

这需要我使用计算 icovar

void calcCovarMatrix(InputArray samples, OutputArray covar, OutputArray mean, int flags, int ctype=CV_64F)

但是,此函数希望将样本存储为单独的矩阵或单个矩阵的行/列。我不知道如何为这个函数提供数据,即如何使样本分离矩阵或作为单个矩阵的行。请帮忙。 我希望更改以下代码:

int Eigenfaces::predict(InputArray _src) const {
// get data
Mat src = _src.getMat();
// project into PCA subspace
Mat q = project(_eigenvectors, _mean, src.reshape(1,1));
double minDist = numeric_limits<double>::max();
int minClass = -1;
for(unsigned int sampleIdx = 0; sampleIdx < _projections.size(); sampleIdx++) {
    //Change Here------------------------------------------------
    Mat icovar;
    Mat mean;
    calcCovarMatrix(Mat(),icovar,mean,CV_COVAR_SCRAMBLED);
    double dist = Mahalanobis(q, sampleIdx, icovar);
    //-----------------------------------------------------------
    //double dist = norm(_projections[sampleIdx], q, NORM_L2);
    if(dist < minDist) {
        minDist = dist;
        minClass = _labels[sampleIdx];
    }
}
return minClass;
}

【问题讨论】:

    标签: opencv computer-vision face-detection face-recognition pca


    【解决方案1】:

    我一直在为我的作业做这件事的方式是展平每张图片。因此,如果图像是 24x24,我将其重塑为 1x1024。

    然后我将要比较的 2 张图像堆叠到一个数组中。所以现在你有一个 2x1024 矩阵/数组。

    我将 2x1024 放入 calcCovarMatrix() 以获取协方差数组(使用 COVAR_ROWS 标志)。然后你使用 invert() 反转它。

    然后你将你的两个图像和你的反向协方差传递给 Mahalanobis()

    【讨论】:

      【解决方案2】:

      简介

      首先。根据我的个人经验,我可以告诉你,对于 PCA,距离度量对识别率并没有任何显着影响。我知道有些论文报告了它,但我无法在我的图像数据库中承认它。至于你关于如何计算马氏距离的问题。 PCA 和 Mahalanobis 距离之间有密切的关系,请参阅 http://www.cognotics.com/opencv/servo_2007_series/part_5/page_5.html 上的“改进特征脸”,这也在 [1] 中给出。为了完整起见,本文所指的项目位于:https://github.com/bytefish/libfacerec

      代码

      如果没有任何进一步的测试,我会将认知学的东西改写成:

      int cv::Eigenfaces::predict(InputArray _src) const {
        // get data
        Mat src = _src.getMat();
        // project into PCA subspace
        Mat q = subspace::project(_eigenvectors, _mean, src.reshape(1,1));
        double minDist = numeric_limits<double>::max();
        int minClass = -1;
        for(int sampleIdx = 0; sampleIdx < _projections.size(); sampleIdx++) {
          Mat diff0, diff1;
          // perform element wise multiplication and division
          multiply(q - _projections[sampleIdx], q - _projections[sampleIdx], diff0);
          divide(diff0.reshape(1,1), _eigenvalues.reshape(1,1), diff1);
          double dist = sum(diff1).val[0];
          if(dist < minDist) {
            minDist = dist;
            minClass = _labels[sampleIdx];
          }
        }
        return minClass;
      }
      

      参考文献

      [1] Moghaddam, B. 和 Pentland, A.“对象表示的概率视觉学习”在 模式分析和机器智能,IEEE Transactions on 卷。 19, No. 7. (1997), pp. 696-710

      【讨论】:

      • 1.我已经在cognotics.com/opencv/servo_2007_series 浏览了整个系列,但那是使用旧的 API。我只是想使用使用 API 来计算马氏距离。 2. 我特意使用了标签,以便得到您的回复。抱歉,我忘了提及您的项目的链接。 3、如果我们可以通过你这里使用的方法计算马氏距离,那么OpenCV提供的马氏距离有什么用?
      • 我会试试这个代码,让你知道它是否有效以及它是否有任何改进。
      • 这给了我更糟糕的结果。您确定这是计算马氏距离的正确方法吗?
      • 我已经在我的帖子中添加了相关出版物,请参阅[1] Eq. 7 等式的推导。如果您在上面的代码中发现错误,请随时更正。如果您在出版物中发现错误 ([1]),也请随时与作者联系。但是,我从来没有说过 Mahalabonis 距离表现更好。
      猜你喜欢
      • 1970-01-01
      • 2014-07-09
      • 1970-01-01
      • 2013-04-22
      • 1970-01-01
      • 2013-09-10
      • 1970-01-01
      • 2020-05-06
      • 2021-06-25
      相关资源
      最近更新 更多