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;
}
}
来源:CSDN
作者:秋叶法师
链接:https://blog.csdn.net/weixin_42464187/article/details/103611959