OpenCV之发现轮廓中心点位置及轮廓方向
2022/5/5 23:13:47
本文主要是介绍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);
三、图像演示
这篇关于OpenCV之发现轮廓中心点位置及轮廓方向的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23增量更新怎么做?-icode9专业技术文章分享
- 2024-11-23压缩包加密方案有哪些?-icode9专业技术文章分享
- 2024-11-23用shell怎么写一个开机时自动同步远程仓库的代码?-icode9专业技术文章分享
- 2024-11-23webman可以同步自己的仓库吗?-icode9专业技术文章分享
- 2024-11-23在 Webman 中怎么判断是否有某命令进程正在运行?-icode9专业技术文章分享
- 2024-11-23如何重置new Swiper?-icode9专业技术文章分享
- 2024-11-23oss直传有什么好处?-icode9专业技术文章分享
- 2024-11-23如何将oss直传封装成一个组件在其他页面调用时都可以使用?-icode9专业技术文章分享
- 2024-11-23怎么使用laravel 11在代码里获取路由列表?-icode9专业技术文章分享
- 2024-11-22怎么实现ansible playbook 备份代码中命名包含时间戳功能?-icode9专业技术文章分享