opencv PCA 求轮廓的形心

来源:互联网 发布:淘宝售后问题大全 编辑:程序博客网 时间:2024/05/21 03:25

PCA的详细功能不是很了解。但是,发现用它来求形心非常好。输入为findcontours之后的轮廓点,输出为形心的坐标。

话不多说,上代码。

//开发环境,opencv3.1.0+vs2013#include <iostream>#include <opencv2/opencv.hpp>using namespace std;using namespace cv;cv::Point chao_getCentroid(std::vector<cv::Point> list);//得到形心坐标,int main(){Mat src = imread("1.png");if (!src.data || src.empty()){cout << "Problem loading image!!!" << endl;return -1;}imshow("src", src);Mat gray;cvtColor(src, gray, COLOR_BGR2GRAY);Mat bw;threshold(gray, bw, 50, 255, CV_THRESH_BINARY | CV_THRESH_OTSU);vector<Vec4i> hierarchy;vector<vector<Point> > contours;Mat bw_back = 255 - bw;findContours(bw_back, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);for (size_t i = 0; i < contours.size(); ++i){drawContours(src, contours, static_cast<int>(i), Scalar(0, 0, 255), 2, 8, hierarchy, 0);Point center = chao_getCentroid(contours[i]);circle(src,center,5,Scalar(0,0,255),-1,8);}imshow("output", src);    waitKey(0);return 0;}cv::Point chao_getCentroid(std::vector<cv::Point> list){Point result_point(0,0);//Construct a buffer used by the pca analysisint sz = static_cast<int>(list.size());Mat data_pts = Mat(sz, 2, CV_64FC1);for (int i = 0; i < data_pts.rows; ++i){data_pts.at<double>(i, 0) = list[i].x;data_pts.at<double>(i, 1) = list[i].y;}//Perform PCA analysisPCA pca_analysis(data_pts, Mat(), CV_PCA_DATA_AS_ROW);//Store the center of the objectPoint cntr = Point(static_cast<int>(pca_analysis.mean.at<double>(0, 0)),static_cast<int>(pca_analysis.mean.at<double>(0, 1)));return cntr;}
效果如下图所示




关于PCA详细使用,可参考官方例程,opencv3.1.0\sources\samples\cpp\tutorial_code\ml\introduction_to_pca文件夹下的introduction_to_pca.cpp文件

2 0
原创粉丝点击