(八)OpenCV人脸识别_03_PCA主成分分析

Vanna ·
更新时间:2024-11-13
· 809 次阅读

PCA原理:(一个分析多维分布并且从中提取出带有最多信息量的维度子集的方法)(无监督:基于方差提取最有价值的信息)
通过对高维数据分析发现他们的相同与不同表达为一个低维数据模式
主成分不变、细微损失、高维数据到低维数据 PCA:样本数据、减去均值、计算协方差矩阵(标准差、方差越大,离散程度越大)、计算特征值与特征向量、根据特征值排序保留前K个主成分特征向量、形成新的数据样本。 输出数据 = 前K个特征向量组合 x 均值调整之后的数据 #include #include using namespace std; using namespace cv; double calcPCA(vector& contours, Mat& dst);//PCA主成分分析计算 //https://www.cnblogs.com/little-monkey/p/8111309.html int main(int argc, char** argv) { Mat src,gray,temp_threshold,temp_contours,dst; src = imread("../path.jpg"); if (src.empty()) { cout << "could not load image..." << endl; return -1; } //namedWindow("src", WINDOW_AUTOSIZE); //imshow("src", src); cvtColor(src, gray, COLOR_BGR2GRAY);//转为灰度图 threshold(gray,temp_threshold,0, 255, THRESH_BINARY | THRESH_OTSU);//二值化 vector hierarchy; vector<vector> contours; findContours(temp_threshold,contours,hierarchy, RETR_LIST, CHAIN_APPROX_NONE);//查找轮廓 temp_contours = src.clone(); for (int i = 0; i 1e5 || area < 1e2) continue;//过滤掉轮廓面积大于10^5和小于10^2的轮廓 drawContours(temp_contours, contours, i, Scalar(0, 0, 255), 2, 8);//绘制轮廓 double theta = calcPCA(contours[i], temp_contours);//PCA主成分分析 } imshow("PCA", temp_contours); waitKey(0); return 0; } double calcPCA(vector& contours, Mat& dst) { int size = static_cast(contours.size());//static_cast强制类型转换 Mat data_contours = Mat(size, 2, CV_64FC1);//用来获取contours中的点的坐标//size个对象,2个维度(即平面坐标x,y) for (int i = 0; i < size; i++) { data_contours.at(i, 0) = contours[i].x; data_contours.at(i, 1) = contours[i].y; } //执行PCA的一系列步骤:样本数据-均值,算协方差,算特征值和特征向量…… PCA pca(data_contours, Mat(), PCA::DATA_AS_ROW); //新的PCA基的中心值 Point center = Point(static_cast(pca.mean.at(0, 0)), static_cast(pca.mean.at(0, 1))); circle(dst, center, 2, Scalar(255, 0, 255), 2, 8);//绘制中心点 vector vecs(2);//特征矩阵 vector vals(2);//特征向量 for (int i = 0; i < 2; i++) { vals[i] = pca.eigenvalues.at(i, 0); vecs[i] = Point2d(pca.eigenvectors.at(i, 0), pca.eigenvectors.at(i, 1)); } //将原直角坐标系中的数据在下面新的一组基中表示,使得数据特征最大化 Point p1 = center + 0.02*Point(static_cast(vecs[0].x * vals[0]), static_cast(vecs[0].y * vals[0])); Point p2 = center - 0.05*Point(static_cast(vecs[1].x * vals[1]), static_cast(vecs[1].y * vals[1])); line(dst, center, p1, Scalar(0, 255, 0), 2, 8);//新的基一//主特征方向 line(dst, center, p2, Scalar(255, 255, 0), 2, 8);//新的基二 //角度 double theta = atan2(vecs[0].y, vecs[0].x); cout << "基角度为:" << 180 * (theta / CV_PI) << endl; return 0; }

src为:
在这里插入图片描述
输出结果:
在这里插入图片描述


作者:丶小早



opencv人脸识别 pca opencv

需要 登录 后方可回复, 如果你还没有账号请 注册新账号