当前位置: 首页 > news >正文

OpenCV轮廓分析

1.轮廓发现

  • 基于联通组件
  • 反映图像拓扑结构
void outline_demo()
{QString appPath = QCoreApplication::applicationDirPath();QString imagePath = appPath + "/morph3.png";Mat img = cv::imread(imagePath.toStdString());if (img.empty()) {return;}namedWindow("input", WINDOW_AUTOSIZE);imshow("input", img);//高斯模糊:降噪GaussianBlur(img, img, Size(3, 3), 0);//To gray imageMat gray, binary;cvtColor(img, gray, COLOR_BGR2GRAY);imshow("gray", gray);//OTSUdouble m_otsu = threshold(gray, binary, 0, 255, THRESH_BINARY | THRESH_OTSU);imshow("BINARY", binary);vector<vector<Point>> contours;vector<Vec4i> hierachy;findContours(binary, contours, hierachy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point());drawContours(img, contours, -1, Scalar(0, 0, 255), 2, 8);imshow("outline", img);waitKey();destroyAllWindows();
}

2.轮廓分析

void outline_analysis_demo()
{QString appPath = QCoreApplication::applicationDirPath();QString imagePath = appPath + "/zhifang_ball.png";Mat img = cv::imread(imagePath.toStdString());if (img.empty()) {return;}namedWindow("input", WINDOW_AUTOSIZE);imshow("input", img);//高斯模糊:降噪GaussianBlur(img, img, Size(3, 3), 0);//To gray imageMat gray, binary;cvtColor(img, gray, COLOR_BGR2GRAY);imshow("gray", gray);//OTSUdouble m_otsu = threshold(gray, binary, 0, 255, THRESH_BINARY_INV | THRESH_OTSU);imshow("BINARY", binary);vector<vector<Point>> contours;vector<Vec4i> hierachy;findContours(binary, contours, hierachy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point());for (size_t t = 0; t < contours.size(); t++){double area = contourArea(contours[t]);double size = arcLength(contours[t],true);qDebug() << "area:" << area << "  " << "size:" << size;if (area < 100 || size < 10) continue;//最大矩形Rect box = boundingRect(contours[t]);rectangle(img,box,Scalar(0,0,255),2,8,0);//最小矩形RotatedRect rrt = minAreaRect(contours[t]);ellipse(img, rrt, Scalar(255, 0, 0), 2, 8);Point2f pts[4];rrt.points(pts);for (int i = 0; i < 4; i++){line(img, pts[i], pts[(i + 1) % 4], Scalar(0, 255, 0), 2, 8);}//绘制轮廓drawContours(img, contours, t, Scalar(0, 0, 255), 2, 8);}imshow("outline", img);waitKey();destroyAllWindows();
}

3.轮廓匹配

void outline_match_demo()
{QString appPath = QCoreApplication::applicationDirPath();Mat img1 = cv::imread(appPath.toStdString() + "/abc.png");Mat img2 = cv::imread(appPath.toStdString() + "/a5.png");if (img1.empty() || img2.empty()) {return;}imshow("input1", img1);imshow("input2", img2);vector<vector<Point>> contours1,contours2;contour_info(img1, contours1);contour_info(img2, contours2);Moments mm2 = moments(contours2[0]);Mat hu2;HuMoments(mm2, hu2);for (size_t t = 0; t < contours1.size(); t++){Moments mm = moments(contours1[t]);double cx = mm.m10 / mm.m00;double cy = mm.m01 / mm.m00;circle(img1,Point(cx, cy), 3, Scalar(255, 0, 0), 2,8, 0);Mat hu;HuMoments(mm, hu);double dist = matchShapes(hu, hu2, CONTOURS_MATCH_I1,0);if (dist < 1.0){drawContours(img1, contours1, t, Scalar(0, 0, 255), 2, 8);}}imshow("match contrours demo", img1);waitKey();destroyAllWindows();
}void contour_info(Mat &image, vector<vector<Point>> &contours)
{//高斯模糊:降噪GaussianBlur(image, image, Size(3, 3), 0);//To gray imageMat gray, binary;cvtColor(image, gray, COLOR_BGR2GRAY);//OTSUdouble m_otsu = threshold(gray, binary, 0, 255, THRESH_BINARY | THRESH_OTSU);vector<Vec4i> hierachy;findContours(binary, contours, hierachy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point());}

4.多边形逼近

void outline_fit_clicked()
{QString appPath = QCoreApplication::applicationDirPath();QString imagePath = appPath + "/contours.png";Mat img = cv::imread(imagePath.toStdString());if (img.empty()) {return;}namedWindow("input", WINDOW_AUTOSIZE);imshow("input", img);//高斯模糊:降噪GaussianBlur(img, img, Size(3, 3), 0);//To gray imageMat gray, binary;cvtColor(img, gray, COLOR_BGR2GRAY);imshow("gray", gray);//OTSUdouble m_otsu = threshold(gray, binary, 0, 255, THRESH_BINARY | THRESH_OTSU);imshow("BINARY", binary);vector<vector<Point>> contours;vector<Vec4i> hierachy;findContours(binary, contours, hierachy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point());//多边形逼近for (size_t t = 0; t < contours.size(); t++){Moments mm = moments(contours[t]);double cx = mm.m10 / mm.m00;double cy = mm.m01 / mm.m00;circle(img, Point(cx, cy), 3, Scalar(255, 0, 0), 2, 8, 0);double area = contourArea(contours[t]);double clen = arcLength(contours[t], true);Mat result;approxPolyDP(contours[t], result, 4, true);qDebug() << result.rows << " " << result.cols;if (result.rows == 6){putText(img, "poly", Point(cx,cy-10), FONT_HERSHEY_PLAIN, 1.0, Scalar(0, 0, 255), 1,8);}if (result.rows == 4){putText(img, "rectangle", Point(cx, cy - 10), FONT_HERSHEY_PLAIN, 1.0, Scalar(0, 0, 255), 1, 8);}if (result.rows == 3){putText(img, "trriangle", Point(cx, cy - 10), FONT_HERSHEY_PLAIN, 1.0, Scalar(0, 0, 255), 1, 8);}if (result.rows >10){putText(img, "circle", Point(cx, cy - 10), FONT_HERSHEY_PLAIN, 1.0, Scalar(0, 0, 255), 1, 8);}}imshow("多边形逼近", img);waitKey();destroyAllWindows();
}

5.拟合圆和椭圆

void actual::fit_circle_demo(Mat &image)
{//To gray imageMat gray, binary;cvtColor(image, gray, COLOR_BGR2GRAY);//OTSUdouble m_otsu = threshold(gray, binary, 0, 255, THRESH_BINARY | THRESH_OTSU);vector<vector<Point>> contours;vector<Vec4i> hierachy;findContours(binary, contours, hierachy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point());//多边形逼近for (size_t t = 0; t < contours.size(); t++){RotatedRect rrt = fitEllipse(contours[t]);float w = rrt.size.width;float h = rrt.size.height;Point center = rrt.center;circle(image, center, 3, Scalar(255.0, 0), 2, 8, 0);ellipse(image, rrt, Scalar(0, 255, 0), 2, 8);}imshow("拟合圆和椭圆", image);
}

相关文章:

  • BUG分析以及BUG定位
  • 深度学习基础模型之Mamba
  • .NET使用HttpClient以multipart/form-data形式post上传文件及其相关参数
  • 【微服务篇】深入理解微服务注册中心与配置中心
  • 使用Spring的缓存抽象来集成不同的缓存提供者,如Ehcache、Redis等
  • 大数据面试专题 -- kafka
  • 算法提高篇基础算法第一章 - 贪心算法
  • 乡村数字化转型:科技赋能打造智慧农村新生态
  • JAVA面试大全之数据库篇
  • 无论PC还是Mac,都能畅快地使用移动硬盘 Mac使用NTFS移动硬盘不能读写
  • Mistral 7B v0.2 基础模型开源,大模型微调实践来了
  • Linux网络配置(超详细)
  • 本地项目上传到GitHub
  • leetcode283-Move Zeroes
  • vue实现相机拍摄,可录视频、拍照片、前置后置切换(简单小demo)
  • #Java异常处理
  • gops —— Go 程序诊断分析工具
  • HTTP那些事
  • IDEA 插件开发入门教程
  • Java程序员幽默爆笑锦集
  • MyEclipse 8.0 GA 搭建 Struts2 + Spring2 + Hibernate3 (测试)
  • Web Storage相关
  • 如何设计一个微型分布式架构?
  • 算法-插入排序
  • 我看到的前端
  • ​sqlite3 --- SQLite 数据库 DB-API 2.0 接口模块​
  • ​学习一下,什么是预包装食品?​
  • #前后端分离# 头条发布系统
  • (02)Cartographer源码无死角解析-(03) 新数据运行与地图保存、加载地图启动仅定位模式
  • (02)vite环境变量配置
  • (10)Linux冯诺依曼结构操作系统的再次理解
  • (17)Hive ——MR任务的map与reduce个数由什么决定?
  • (论文阅读32/100)Flowing convnets for human pose estimation in videos
  • (篇九)MySQL常用内置函数
  • (七)MySQL是如何将LRU链表的使用性能优化到极致的?
  • (三)Pytorch快速搭建卷积神经网络模型实现手写数字识别(代码+详细注解)
  • (十三)Flask之特殊装饰器详解
  • (四)Linux Shell编程——输入输出重定向
  • ***微信公众号支付+微信H5支付+微信扫码支付+小程序支付+APP微信支付解决方案总结...
  • .babyk勒索病毒解析:恶意更新如何威胁您的数据安全
  • .NET/C# 中你可以在代码中写多个 Main 函数,然后按需要随时切换
  • .NET和.COM和.CN域名区别
  • .NET开源全面方便的第三方登录组件集合 - MrHuo.OAuth
  • ::before和::after 常见的用法
  • @Builder用法
  • @ConfigurationProperties注解对数据的自动封装
  • [ vulhub漏洞复现篇 ] JBOSS AS 4.x以下反序列化远程代码执行漏洞CVE-2017-7504
  • [20190401]关于semtimedop函数调用.txt
  • [BZOJ1060][ZJOI2007]时态同步 树形dp
  • [C++]18:set和map的使用
  • [C++基础]-入门知识
  • [CF]Codeforces Round #551 (Div. 2)
  • [docker] Docker容器服务更新与发现之consul
  • [Enterprise Library]调用Enterprise Library时出现的错误事件之关闭办法
  • [halcon案例2] 足球场的提取和射影变换