opencv学习之路(39)、PCA
一、PCA理论介绍
网上已经有许多介绍pca原理的博客,这里就不重复介绍了。详情可参考
http://blog.csdn.net/zhongkelee/article/details/44064401
计算过程
数据互换
二、opencv代码
#include<opencv2/opencv.hpp> using namespace cv; using namespace std; void calcPCAOrientation(vector<Point>&pts, Mat &image){ int size = static_cast<int>(pts.size());//static_cast强制类型转换 Mat data_pts = Mat(size,2,CV_64FC1);//size个对象,2个维度(即平面坐标x,y) for (int i = 0; i < size; i++) { data_pts.at<double>(i, 0) = pts[i].x; data_pts.at<double>(i, 1) = pts[i].y; } //执行PCA的一系列步骤:样本数据-均值,算协方差,算特征值和特征向量…… PCA pca(data_pts, Mat(), CV_PCA_DATA_AS_ROW); //获取均值(中心)位置 Point cnt = Point(static_cast<int>(pca.mean.at<double>(0, 0)), static_cast<int>(pca.mean.at<double>(0, 1))); circle(image,cnt,2,Scalar(0,255,0),2,8,0); vector<Point2d>vecs(2); vector<double>vals(2); for (int i = 0; i < 2; i++) { vals[i] = pca.eigenvalues.at<double>(i, 0);//特征值 cout << "第" << i << "个特征值:" << vals[i]<<endl; vecs[i] = Point2d(pca.eigenvectors.at<double>(i, 0), //特征向量 (pca.eigenvectors.at<double>(i, 1))); } Point p1 = cnt + 0.02*Point(static_cast<int>(vecs[0].x*vals[0]), static_cast<int>(vecs[0].y*vals[0])); Point p2 = cnt - 0.05*Point(static_cast<int>(vecs[1].x*vals[1]), static_cast<int>(vecs[1].y*vals[1])); line(image, cnt, p1, Scalar(255, 0, 0), 2, 8, 0); line(image, cnt, p2, Scalar(255, 255, 0), 2, 8, 0); double angle = atan2(vecs[0].y,vecs[0].x); cout << "angle:" << 180 * (angle / CV_PI)<<endl; } void main() { Mat src = imread("E://2.jpg"); imshow("src", src); Mat gray, binary; cvtColor(src, gray,CV_BGR2GRAY); threshold(gray, binary,0,255, THRESH_BINARY|THRESH_OTSU);//自动阈值:OTSU找到一个它认为最好的阈值 //imshow("binary", binary); //轮廓提取 vector<Vec4i>hierarchy; vector<vector<Point>>contours; findContours(binary, contours, hierarchy, RETR_LIST, CHAIN_APPROX_NONE);//查找所有轮廓,存储所有轮廓点 Mat result = src.clone();//复制,不随原图改变 for (int i = 0; i < contours.size(); i++) { double area = contourArea(contours[i]); if (area>1e5 || area < 1e2) continue;//面积大于10^5或者小于10^2的轮廓,不要 drawContours(result, contours, i, Scalar(0, 0, 255), 2, 8); calcPCAOrientation(contours[i], result);//调用PCA } imshow("contours result", result); waitKey(0); }