PCA图像转正C++

拜拜、爱过 提交于 2019-12-20 00:11:03

PCA图像转正C++

MaskRotation.h

//
// Created by surui on 2019/12/17.
//

#ifndef IDEATRAINER_MASKROTATION_H
#define IDEATRAINER_MASKROTATION_H

#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

#define PI acos(-1)


class MaskRotation {

public:

    /**
     * input mask foreground pixels' value is 255
     * @param mask
     * @param points
     */
    static void getAllForeGroundPoints(Mat mask, Mat &points);

    /**
     * pca fit data
     * @param Points
     * @return angle
     */
    static float pca(const Mat &Points);

    /**
     * rotate mask to upright by pca's angle
     * @param angle
     * @param mask
     */
    static void rotateToUpright(float angle, Mat &mask);

};


#endif //IDEATRAINER_MASKROTATION_H


MaskRotation.cpp

//
// Created by surui on 2019/12/17.
//

void MaskRotation::getAllForeGroundPoints(Mat mask, Mat &points) {
    int height = mask.rows;
    int width = mask.cols;
    for (int i = 0; i < height; ++i) {
        const uchar *rowi = mask.ptr<uchar>(i);
        for (int j = 0; j < width; ++j) {
            if (rowi[j] == 255) {
                Mat point = Mat(cv::Size(2, 1), CV_32FC1);
                point.at<float>(0, 0) = i;
                point.at<float>(0, 1) = j;
                points.push_back(point);
            }
        }
    }
}


float MaskRotation::pca(const Mat &Points) {
    int components = 2;
    float angle = 0.0;
    try {
        cv::PCA pca(Points, cv::Mat(), CV_PCA_DATA_AS_ROW, components);
        cv::Mat eigValue = pca.eigenvalues.clone();
        cv::Mat eigenVec = pca.eigenvectors.clone();

        float scx = eigenVec.at<float>(0, 0);
        float scy = eigenVec.at<float>(0, 1);

        float cosx = scy / sqrt(scx * scx + scy * scy);
        angle = (float) ((acos(cosx) - PI / 2) / PI * 180);

    } catch (cv::Exception e) {
        cout << "Error pca : " << e.msg << endl;
    }
    return angle;
}


void MaskRotation::rotateToUpright(float angle, Mat &mask) {
    int height = mask.rows;
    int width = mask.cols;
    try {
        Point2f center(width / 2, height / 2);
        Mat M = cv::getRotationMatrix2D(center, angle, 1.0);
        Mat inputMask = mask.clone();
        cv::warpAffine(mask, mask, M, cv::Size(width, height), cv::INTER_LINEAR, cv::BORDER_REPLICATE);
    } catch (cv::Exception e) {
        cout << "Error image rotate : " << e.msg << endl;
    }

}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!