qq_37589257 2019-04-20 18:25 采纳率: 25%
浏览 1632

C++代码改Python实现PCA算法:从一组照片中获取特征脸(特征向量)?

PCA处理的基本步骤为:

1、获取m个样本,每个样本有n个特征。

2、每个样本作为一行,构成m*n的举证A。

3、将矩阵转置再乘以自己得到C=A(t)*A。

4、求出矩阵C的特征值及特征向量,特征向量即为特征脸。
以下是C++实现代码,求解决一份Python实现出的代码

#include "stdafx.h"
#include <string>
#include <opencv2\opencv.hpp> 
using namespace std;
using namespace cv;

int _tmain(int argc, _TCHAR* argv[])
{
    //获取了mean_face
    int num_sample = 38;
    int norm_row = 64, norm_col = 56;
    int num;
    Mat imgs = loadImages(num);
    Mat mean_face = Mat(norm_row, norm_col, CV_8UC1);
    vector<int> mean_face_total;
    mean_face_total.resize(norm_row * norm_col);

    for (int i = 0; i < num; i++)
    {
        for (int j = 0; j < norm_row * norm_col; j++)
        {
            mean_face_total.at(j) += imgs.at<uchar>(i * norm_row * norm_col + j);
            //eigen_face_total[j] += imgs.at<uchar>(i * 192 * 168 + j);
        }
    }
    for (int j = 0; j < norm_row * norm_col; j++)
    {
        mean_face.at<uchar>(j) = (uchar)(mean_face_total.at(j) / num);
    }

    imwrite("C:/Users/dhj555/Desktop/YelaFaces/eigen_face/0001.jpg", mean_face);
    imshow("eigen_face", mean_face);

    //1、初始化数据
    CvMat* pData = cvCreateMat(num_sample, norm_row * norm_col, CV_32FC1);
    CvMat* pMean = cvCreateMat(1, norm_row * norm_col, CV_32FC1);
    //每个数标志一个特征值
    CvMat* pEigVals = cvCreateMat(1, min(num_sample, norm_row * norm_col), CV_32FC1);
    //每行表示一个特征向量
    CvMat* pEigVecs = cvCreateMat(min(num_sample, norm_row * norm_col), norm_row * norm_col, CV_32FC1);

    for (int i = 0; i < num_sample; i++)
    {
        for (int j = 0; j < norm_row * norm_col; j++)
            cvmSet(pData, i, j, imgs.at<uchar>(i * norm_row * norm_col + j));
    }

    //2、PCA处理
    cvCalcPCA(pData, pMean, pEigVals, pEigVecs, CV_PCA_DATA_AS_ROW);

    //3、选出前P个特征向量(主成份),然后投影,结果保存在pResult中,pResult中包含了P个系数
    //CvMat* pResult = cvCreateMat(num_sample, 20, CV_32FC1);
    //cvProjectPCA(pData, pMean, pEigVecs, pResult);

    //4、重构, 结果保存在pRecon中
    //CvMat* pRecon = cvCreateMat(num_sample, norm_row*norm_col, CV_32FC1);
    //cvBackProjectPCA(pResult, pMean, pEigVecs, pRecon);

    //5、显示重构的图像
    //Mat mRecon = Mat(pRecon);


    //4、显示与保存特征向量
    for (int i = 0; i < min(num_sample, norm_row * norm_col); i++)
    {
        float min = LLONG_MAX, max = LLONG_MIN, span = 0.0;
        for (int index = 0; index < norm_row*norm_col; index++)
        {
            float d = cvmGet(pEigVecs, i, index);
            if (d>max)
                max = d;
            if (d < min)
                min = d;
        }
        span = max - min;
        Mat eigen_face = Mat(norm_row, norm_col, CV_8UC1);
        for (int index = 0; index < norm_row*norm_col; index++)
        {
            float d = cvmGet(pEigVecs, i, index);
            eigen_face.at<uchar>(index) = (d - min) / span * 255.0;
        }
        char buffer[128];
        sprintf_s(buffer, "C:/Users/dhj555/Desktop/YelaFaces/eigen_face/001/1-000%d.jpg", i);
        string imgPath(buffer);
        imshow(imgPath, eigen_face);
        printf("%d st:\t%f\n", i, cvmGet(pEigVals, 0, i));
        imwrite(imgPath, eigen_face);
    }
}
  • 写回答

1条回答 默认 最新

  • 吃鸡王者 2019-04-22 17:47
    关注

    https://www.cnblogs.com/clnchanpin/p/7199713.html 参考一下这个吧,python只要几行即可

    评论

报告相同问题?

悬赏问题

  • ¥15 安卓adb backup备份应用数据失败
  • ¥15 eclipse运行项目时遇到的问题
  • ¥15 关于#c##的问题:最近需要用CAT工具Trados进行一些开发
  • ¥15 南大pa1 小游戏没有界面,并且报了如下错误,尝试过换显卡驱动,但是好像不行
  • ¥15 没有证书,nginx怎么反向代理到只能接受https的公网网站
  • ¥50 成都蓉城足球俱乐部小程序抢票
  • ¥15 yolov7训练自己的数据集
  • ¥15 esp8266与51单片机连接问题(标签-单片机|关键词-串口)(相关搜索:51单片机|单片机|测试代码)
  • ¥15 电力市场出清matlab yalmip kkt 双层优化问题
  • ¥30 ros小车路径规划实现不了,如何解决?(操作系统-ubuntu)