1. 程式人生 > 其它 >OpenCV之發現輪廓中心點位置及輪廓方向

OpenCV之發現輪廓中心點位置及輪廓方向

一、概述

  案例:使用PCA發現輪廓的中心點位置及輪廓方向

  PAC API介紹:

PCA(InputArray data, InputArray mean, int flags, int maxComponents = 0);
data:輸入資料,一般是輪廓點集合
mean:資料均值如果為空則自動計算
flags:資料的提供方式,分為行和列兩種
maxComponents:保留多少特徵值(預設保留全部)

PCA的方法:
mean:均值資料,其中第一個資料即為資料集的中心點
eigenvalues:特徵值集合
eigenvectors:特徵向量集合

  演算法實現步驟:

    1.載入輸入影象

    2.影象灰度化

    3.影象二值化

    4.使用findContours發現輪廓

    5.迴圈繪製輪廓

    6.迴圈使用PCA檢測每個輪廓

      6.1.初始化PCA

      6.2.找到輪廓中心點

      6.3.繪製輪廓中心點

      6.4.根據特徵向量及特徵值找到向量座標

      6.5.繪製向量直線

      6.6.找到輪廓方向角度

 

二、程式碼示例

  Mat src = imread(filePath);
    if(src.empty()){
        qDebug()<<"輸入影象為空";
        return;
    }
    imshow(
"src",src); Mat gray,binary; cvtColor(src,gray,COLOR_BGR2GRAY);//灰度化 //二值化 threshold(gray,binary,0,255,THRESH_BINARY|THRESH_OTSU); imshow("binary",binary); //發現輪廓 vector<vector<Point>> contours; vector<Vec4i> heri; findContours(binary,contours,RETR_LIST,CHAIN_APPROX_NONE); Mat result
= src.clone();//clone一個副本 for(size_t i = 0;i<contours.size();i++){ //過濾掉面積較小的區域 double area = contourArea(contours[i]); if (area > 1e5 || area < 1e2) continue; drawContours(result,contours,i,Scalar(0,0,255),3,LINE_8);//繪製輪廓 pcaAnalyze(contours[i],result); } imshow("result",result); } /** * 使用PCA分析輪廓,找到中心點位置以及輪廓方向 * @brief Face_PCA::pcaAnalyze * @param points * @param result */ void Face_PCA::pcaAnalyze(vector<Point> &points,Mat &result){ int size = points.size(); Mat data_pts = Mat(size,2,CV_64FC1); for(int i=0;i<size;i++){ data_pts.at<double>(i,0) = points[i].x; data_pts.at<double>(i,1) = points[i].y; } qDebug()<<"開始pca分析"; //使用PCA進行分析 PCA pca_analyze(data_pts,Mat(),PCA::DATA_AS_ROW);//例項化PCA //找出輪廓的圓心:均值資料的第一個值即為資料中心點 Point center = Point(pca_analyze.mean.at<double>(0,0),pca_analyze.mean.at<double>(0,1)); //繪製輪廓中心點 circle(result,center,3,Scalar(0,0,255),3,LINE_8); qDebug()<<"準備利用pca尋找輪廓方向"; //找出並繪製出輪廓方向 vector<Point2d> vecs(2);//特徵向量 vector<double> vals(2);//特徵值 for(int i=0;i<2;i++){ vals[i] = pca_analyze.eigenvalues.at<double>(i,0); vecs[i] = Point2d(pca_analyze.eigenvectors.at<double>(i,0),pca_analyze.eigenvectors.at<double>(i,1)); } Point p1 = center+ 0.02*Point(static_cast<int>(vecs[0].x*vals[0]), static_cast<int>(vecs[0].y*vals[0])); Point p2 = center - 0.05*Point(static_cast<int>(vecs[1].x*vals[1]), static_cast<int>(vecs[1].y*vals[1])); line(result,center,p1,Scalar(0,255,0),3,LINE_8); line(result,center,p2,Scalar(0,255,0),3,LINE_8); double angle = atan2(vecs[0].y,vecs[0].x); qDebug()<<"角度:"<<180*(angle/CV_PI);

 

三、影象演示