如何使用主成分分析(PCA)来降低维度

3

输入:从一张图片中提取的LBP特征,维度为75520。因此,输入的LBP数据包含1行和75520列。

所需输出:对输入应用PCA以减小维度。

目前我的代码看起来像这样:

void PCA_DimensionReduction(Mat &src, Mat &dst){

    int PCA_DIMENSON_VAL 40
    Mat tmp = src.reshape(1,1); //1 rows X 75520 cols
    Mat projection_result;
    Mat input_feature_vector;
    Mat norm_tmp;
    normalize(tmp,input_feature_vector,0,1,NORM_MINMAX,CV_32FC1);
    PCA pca(input_feature_vector,Mat(),CV_PCA_DATA_AS_ROW, PCA_DIMENSON_VAL);
    pca.project(input_feature_vector,projection_result);
    dst = projection_result.reshape(1,1);
}

基本上,我使用这个功能来匹配两个图像之间的相似性,但是没有应用PCA时,我得不到适当的结果。
任何帮助将不胜感激...
问候
哈里斯...

您好,是的,Hi-Dim LBP 很酷😉 但是您是否应该为所有图像训练一个大的 PCA(离线),而不是每个图像都训练一个? - berak
1
嗨,@Haris,实际上,我正在尝试同样的想法。从pca到随机投影,再到Walsh-Hadamard,不要忘记小波变换,最终走向简单的dft->去除高频->dft_back,但最后 - 不使用lbp(u),而是一个更短的四块lbp特征(仅16个bin,而不是256 [甚至59对于lbpu],然后跳过任何特征压缩)对我来说效果更好。有什么评论吗?;) - berak
以与lbpu版本完全相同的方式。4x4补丁围绕地标点周围10个像素(目前使用dlib进行地标定位)。 - berak
让我们在聊天中继续这个讨论 - Haris
当然,为什么不呢。那边见。 - berak
显示剩余7条评论
1个回答

4

你需要从大量的图像中收集特征向量,制作一个单独的PCA(离线),然后在投影中使用平均值和特征向量。

// let's say, you have collected 10 feature vectors a 30 elements.
// flatten them to a single row (reshape(1,1)) and push_back into a big Data Mat

Mat D(10,30,CV_32F); // 10 rows(features) a 30 elements
randu(D,0,10);       // only for the simulation here
cerr << D.size() << endl;
// [30 x 10]


// now make a pca, that will only retain 6 eigenvectors
// so the later projections are shortened to 6 elements:

PCA p(D,Mat(),CV_PCA_DATA_AS_ROW,6);
cerr << p.eigenvectors.size() << endl;
// [30 x 6]

// now, that the training step is done, we can use it to
// shorten feature vectors:
// either keep the PCA around for projecting:

// a random test vector, 
Mat v(1,30,CV_32F);
randu(v,0,30);

// pca projection:
Mat vp = p.project(v);

cerr << vp.size() << endl;
cerr << vp << endl;
// [6 x 1]
// [-4.7032223, 0.67155731, 15.192059, -8.1542597, -4.5874329, -3.7452228]


// or, maybe, save the pca.mean and pca.eigenvectors only, and do your own projection:

Mat vp2 = (v - mean) * eigenvectors.t();

cerr << vp2.size() << endl;
cerr << vp2 << endl;
//[6 x 1]
//[-4.7032223, 0.67155731, 15.192059, -8.1542597, -4.5874329, -3.7452228]

好的,这里有个缺点:从4.4k个训练图像、75k个特征元素计算PCA需要一整天时间 ;)


嗨,@berak,谢谢你的回答,我会尝试理解你的回答,但在此之前还有一个问题,假设我需要比较两张图片,比如加载img1->计算LBP(1X75520)->应用PCA降维,然后对img2进行相同的过程,最后比较img1和img2的PCA输出以确定相似性。 - Haris
1
是的,完全正确。您比较了两个图像的预测(缩短)特征。 - berak
顺便问一下,intraface怎么样? - berak
我从GitHub的某个开源项目的其他地方获取了这个库。 - Haris
1
你需要保存pca.mean和pca.eigenvectors。后续的投影操作如下:从你的特征中减去平均值,然后与转置后的特征向量相乘。 - berak
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接