zoukankan      html  css  js  c++  java
  • 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);
    }      

  • 相关阅读:
    数据可视化之DAX篇(二十五)PowerBI常用的度量值:累计至今
    数据可视化之DAX篇(二十四)Power BI应用技巧:在总计行实现条件格式
    Type-generic math (Numerics) – C 中文开发手册
    Bootstrap4 卡片
    Linux let 命令
    PHP ftp_fput() 函数
    如何从SQL Server DateTime数据类型返回日期
    ID选择器 | ID selectors (Selectors) – CSS 中文开发手册
    git write-tree (Plumbing Commands) – Git 中文开发手册
    C 库函数 – strtod()
  • 原文地址:https://www.cnblogs.com/little-monkey/p/8111309.html
Copyright © 2011-2022 走看看