OpenCV入门11:轮廓提取和形状识别
轮廓分析主要用于轮廓提取和形状识别等任务。在OpenCV中,轮廓提取和形状识别是图像处理和计算机视觉中常见的任务。下面是关于这两个知识点的一些基本内容:
-
轮廓提取:
轮廓提取是指从图像中提取出物体轮廓的过程。在OpenCV中,可以使用cv::findContours()
函数来实现轮廓提取。以下是一个简单的示例:
cv::Mat image = cv::imread("image.jpg", cv::IMREAD_GRAYSCALE); // 读取灰度图像
cv::Mat binaryImage;
cv::threshold(image, binaryImage, 128, 255, cv::THRESH_BINARY); // 二值化分割,大于阈值为255,小于阈值为0
std::vector<std::vector<cv::Point>> contours;
std::vector<cv::Vec4i> hierarchy;
// 遍历轮廓并绘制
cv::findContours(binaryImage, contours, hierarchy, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE);
cv::Mat contoursImage = cv::Mat::zeros(image.size(), CV_8UC3);
for (size_t i = 0; i < contours.size(); ++i)
{ cv::drawContours(contoursImage, contours, i, cv::Scalar(0, 0, 255), 2, cv::LINE_8, hierarchy, 0);
}
cv::imshow("Contours Image", contoursImage);
cv::waitKey(0);
在示例中,首先通过阈值分割将图像二值化,然后使用cv::findContours()
函数找到图像中的轮廓,最后通过cv::drawContours()
函数绘制轮廓。
-
轮廓面积与周长:
可以使用cv::contourArea()
函数计算轮廓的面积,并使用cv::arcLength()
函数计算轮廓的周长。这些特征可以用于识别不同形状的轮廓。例如,可以通过设定面积和周长的阈值来筛选特定大小的轮廓。
-
轮廓凸包:
凸包是将轮廓包围在一个最小凸多边形内的过程。OpenCV提供了cv::convexHull()
函数用于计算轮廓的凸包。通过比较凸包的顶点数量和轮廓的顶点数量,可以判断轮廓是否是凸形状。
-
轮廓形心:
形心是轮廓表示的几何中心,可以使用cv::moments()
函数计算轮廓的形心。形心坐标可以用于进一步的形状识别。
-
轮廓外接圆:
可以使用cv::minEnclosingCircle()
函数计算轮廓的外接圆。通过比较外接圆的半径和轮廓的尺寸,可以判断轮廓是否是圆形状。
-
轮廓外接矩形:
使用cv::boundingRect()
函数可以计算轮廓的外接矩形,其由矩形的左上角坐标和宽度、高度组成。外接矩形的宽高比可以用于识别特定宽高比的轮廓。
-
轮廓最小面积矩形:
可以使用cv::minAreaRect()
函数计算轮廓的最小面积矩形,该矩形是能够包围轮廓的最小面积矩形框。可以通过比较矩形的宽高比、角度等特征来识别轮廓的形状。
- 形状识别:
以上这些算法和特征可以进行轮廓形状识别的补充。通过结合多个特征和算法,可以更准确地识别不同形状的轮廓。
对于圆形识别和直线识别,OpenCV提供了相应的函数和算法。以下是一些常用的方法:
- 圆形识别:
使用霍夫圆变换(Hough Circle Transform)cv::HoughCircles()
函数来检测图像中的圆。该函数可以帮助你找到图像中的圆形轮廓,并返回识别到的圆形的圆心和半径。
cv::Mat image = cv::imread("image.jpg", cv::IMREAD_GRAYSCALE); // 读取灰度图像
cv::Mat blurredImage;
cv::GaussianBlur(image, blurredImage, cv::Size(5, 5), 0); // 高斯模糊
std::vector<cv::Vec3f> circles;
cv::HoughCircles(blurredImage, circles, cv::HOUGH_GRADIENT, 1, 100, 50, 30, 0, 0);
// 霍夫圆变换
// 绘制识别到的圆形
cv::Mat circlesImage = cv::Mat::zeros(image.size(), CV_8UC3);
for (size_t i = 0; i < circles.size(); ++i)
{ cv::Point center(cvRound(circles[i][0]), cvRound(circles[i][1])); int radius = cvRound(circles[i][2]); cv::circle(circlesImage, center, radius, cv::Scalar(0, 0, 255), 2, cv::LINE_8);
}
cv::imshow("Circles Image", circlesImage);
cv::waitKey(0);
- 直线识别:
使用霍夫直线变换(Hough Line Transform)cv::HoughLines()
函数来检测图像中的直线。该函数可以检测图像中的直线轮廓,并返回检测到的直线的参数。
cv::Mat image = cv::imread("image.jpg", cv::IMREAD_GRAYSCALE); // 读取灰度图像
cv::Mat blurredImage; cv::GaussianBlur(image, blurredImage, cv::Size(5, 5), 0); // 高斯模糊
cv::Canny(blurredImage, blurredImage, 50, 150); // 边缘检测
std::vector<cv::Vec2f> lines;
cv::HoughLines(blurredImage, lines, 1, CV_PI / 180, 100); // 霍夫直线变换
// 绘制识别到的直线
cv::Mat linesImage = cv::Mat::zeros(image.size(), CV_8UC3);
for (size_t i = 0; i < lines.size(); ++i)
{ float rho = lines[i][0]; float theta = lines[i][1]; double a = cos(theta); double b = sin(theta); double x0 = a * rho; double y0 = b * rho; cv::Point pt1(cvRound(x0 + 1000 * (-b)), cvRound(y0 + 1000 * (a))); cv::Point pt2(cvRound(x0 - 1000 * (-b)), cvRound(y0 - 1000 * (a))); cv::line(linesImage, pt1, pt2, cv::Scalar(0, 0, 255), 2, cv::LINE_8);
}
cv::imshow("Lines Image", linesImage);
cv::waitKey(0);
这些示例展示了如何使用OpenCV进行圆形和直线的识别。对于圆形识别,使用霍夫圆变换来检测图像中的圆;对于直线识别,使用霍夫直线变换来检测图像中的直线。
除了圆形和直线识别,OpenCV还提供了其他形状识别的方法。以下是一些常见的形状识别方法:
-
多边形识别:
通过多边形逼近方法,可以识别各种多边形形状,如三角形、四边形等。OpenCV提供了cv::approxPolyDP()
用于多边形逼近、cv::minAreaRect()
用于最小外接矩形等。以下是一个示例,演示如何识别并绘制矩形轮廓:
cv::Mat image = cv::imread("image.jpg", cv::IMREAD_GRAYSCALE); // 读取灰度图像
cv::Mat binaryImage;
cv::threshold(image, binaryImage, 128, 255, cv::THRESH_BINARY); // 二值化分割,大于阈值为255,小于阈值为0
std::vector<std::vector<cv::Point>> contours;
std::vector<cv::Vec4i> hierarchy;
cv::findContours(binaryImage, contours, hierarchy, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE);
cv::Mat contoursImage = cv::Mat::zeros(image.size(), CV_8UC3);
for (size_t i = 0; i < contours.size(); ++i)
{ // 对轮廓进行多边形逼近 std::vector<cv::Point> approx; cv::approxPolyDP(contours[i], approx, cv::arcLength(contours[i], true) * 0.02, true); // 如果逼近结果是一个四边形,则认为是矩形 if (approx.size() == 4) { cv::Scalar color(0, 0, 255); cv::polylines(contoursImage, approx, true, color, 2, cv::LINE_8); }
}
cv::imshow("Contours Image", contoursImage);
cv::waitKey(0);
在示例中,先计算轮廓的多边形逼近,然后通过判断逼近结果的顶点个数来识别是否是矩形。
除了前面提到的基于多边形逼近的方法外,还有一些常用的形状识别算法可以应用于轮廓识别。
-
椭圆识别:
通过椭圆拟合方法,可以识别椭圆形状。使用cv::fitEllipse()
函数对轮廓进行椭圆拟合,然后判断拟合程度以确定形状是否为椭圆。
cv::Mat image = cv::imread("image.jpg", cv::IMREAD_GRAYSCALE); // 读取灰度图像
cv::Mat blurredImage;
cv::GaussianBlur(image, blurredImage, cv::Size(5, 5), 0); // 高斯模糊
cv::Canny(blurredImage, blurredImage, 50, 150); // 边缘检测
std::vector<std::vector<cv::Point>> contours;
cv::findContours(blurredImage, contours, cv::RETR_EXTERNAL,
cv::CHAIN_APPROX_SIMPLE); // 查找轮廓
cv::Mat ellipseImage = cv::Mat::zeros(image.size(), CV_8UC3);
for (size_t i = 0; i < contours.size(); ++i)
{ cv::RotatedRect ellipse = cv::fitEllipse(contours[i]); // 椭圆拟合 cv::ellipse(ellipseImage, ellipse, cv::Scalar(0, 255, 0), 2);
}
cv::imshow("Ellipses Image", ellipseImage);
cv::waitKey(0);
-
几何矩识别:
使用几何矩方法可以计算轮廓的矩,并利用矩的特征来识别不同的形状,如面积、宽高比、中心距等。
cv::Mat image = cv::imread("image.jpg", cv::IMREAD_GRAYSCALE); // 读取灰度图像
cv::Mat blurredImage;
cv::GaussianBlur(image, blurredImage, cv::Size(5, 5), 0); // 高斯模糊
cv::threshold(blurredImage, blurredImage, 100, 255, cv::THRESH_BINARY); // 二值化
std::vector<std::vector<cv::Point>> contours;
cv::findContours(blurredImage, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE); // 查找轮廓
cv::Moments moments;
cv::Mat momentsImage = cv::Mat::zeros(image.size(), CV_8UC3);
for (size_t i = 0; i < contours.size(); ++i)
{ moments = cv::moments(contours[i]); // 计算几何矩 cv::Point centroid(moments.m10 / moments.m00, moments.m01 / moments.m00); // 形心坐标 cv::circle(momentsImage, centroid, 4, cv::Scalar(0, 255, 0), -1); double area = moments.m00; // 面积 double aspect_ratio = moments.m20 / moments.m02; // 宽高比 // 可根据需要判断其他矩的特征
}
cv::imshow("Moments Image", momentsImage);
cv::waitKey(0);
-
形状匹配:
通过形状匹配方法,可以将待识别的形状与已知形状进行比较,来确定形状的类别。常见的形状匹配方法包括轮廓匹配和模板匹配。
这些方法可以根据实际需求和具体应用选用。需要根据图像特征和形状的具体定义来选择适合的方法。可以结合多个特征和算法,进行更准确的形状识别。根据不同形状的特征,使用适当的函数和算法进行识别,并可针对需要的特征进行进一步的处理和分析。
相关文章:
OpenCV入门11:轮廓提取和形状识别
轮廓分析主要用于轮廓提取和形状识别等任务。在OpenCV中,轮廓提取和形状识别是图像处理和计算机视觉中常见的任务。下面是关于这两个知识点的一些基本内容: 轮廓提取: 轮廓提取是指从图像中提取出物体轮廓的过程。在OpenCV中,可…...

竞赛选题 深度学习疲劳检测 驾驶行为检测 - python opencv cnn
文章目录 0 前言1 课题背景2 相关技术2.1 Dlib人脸识别库2.2 疲劳检测算法2.3 YOLOV5算法 3 效果展示3.1 眨眼3.2 打哈欠3.3 使用手机检测3.4 抽烟检测3.5 喝水检测 4 最后 0 前言 🔥 优质竞赛项目系列,今天要分享的是 🚩 **基于深度学习加…...

Java编程--定时器/线程池/工厂模式/ ThreadPoolExecutor
前言 逆水行舟,不进则退!!! 目录 什么是定时器 实现一个定时器 自己实现一个定时器 什么是线程池 线程池的使用: 什么是工厂模式? 自己实现一个线程池: ThreadPoolExecutor 类…...

【python】Django——django简介、django安装、创建项目、快速上手
笔记为自我总结整理的学习笔记,若有错误欢迎指出哟~ Django基础——django安装、创建django项目、django快速上手 django简介django安装1. conda创建环境pydjango2. pip安装django3. django目录 创建项目1. 打开终端(cmd)2. 进入某个目录3.创建项目命令4.django项目…...

未来之选:为什么向量数据库是您的数据管理利器
文章目录 前言什么是向量数据库?向量数据库的机制向量数据库的优点查询向量数据库 什么是向量Embedding?Amazon OpenSearch Service总结 前言 向量数据库擅长处理复杂的高维数据,正在彻底改变商业世界的数据检索和分析。它们执行相似性搜索…...

隧道施工工艺流程vr线上虚拟展示成为产品3D说明书
行业内都知道,汽车生产的大部分都需要冲压加工来完成,因此汽车冲压工艺是汽车制造过程中的重要环节,传统的展示方式往往局限于二维图纸和实地操作,难以充分展现工艺的细节和流程。然而,随着技术的进步,汽车…...
Nacos(含安装)
Nacos是一个开源的动态服务发现、配置和管理平台。它提供了服务发现、服务健康检查、动态配置管理、服务元数据管理等功能,支持多种服务发现和注册方式。Nacos可以帮助开发者快速构建一个具有弹性和高可用性的微服务应用程序。Nacos的全称是Named after Configurati…...

本地跑项目解决跨域问题
跨域问题: 指的是浏览器不能执行其他网站的脚本,它是由浏览器的同源策略造成的,是浏览器对 javascript 施加的安全限制。 同源策略: 是指协议(protocol)、域名(host)、端口号&…...
聊聊logback的isDebugEnabled
序 本文主要研究一下logback的isDebugEnabled isDebugEnabled public final class Loggerimplements org.slf4j.Logger, LocationAwareLogger, LoggingEventAware, AppenderAttachable<ILoggingEvent>, Serializable {//......public boolean isDebugEnabled() {retur…...

ChatGPT+Roblox,元宇宙的AI叙事逻辑#Leveling Up
MixCopilot 嗨,亲爱的听众朋友们!欢迎收听我们的播客节目!我是你们的主播:MixCopilot 混合副驾。今天我们要为大家带来的是我们的AI革命系列节目之一。这个系列节目聚焦于AI领域的一些最有影响力的建设者,他们将会讨论…...

Spark算子
一、编写spark程序的准备工作(程序入口 SparkContext) 1.创建SparkConf val conf new SparkConf().setMaster("local[2]").setAppName("hello-app") 2.创建sparkContext val sc: SparkContext new SparkContext(conf) 二、基…...

Containerd接入Harbor仓库
在使用容器时,避免不了会使用到私有仓库,一般都是采用 harbor 作为私有仓库,docker 对接 harbor 仓库非常简单,哪 containerd 如何对接 harbor 呢? 在内网使用 harbor 根据个人习惯,一般都是非 http 并且是…...
Angular 组件介绍及使用(一)
Angular 概述 Angular 是一个用于构建 Web 应用程序的开源前端框架,由 Google 团队开发和维护。它采用 TypeScript 编程语言,并借鉴了一些传统的 Web 开发模式和最佳实践,提供了强大而灵活的工具和特性。 以下是 Angular 的一些概述要点&am…...

2023.11.13 hive数据仓库之分区表与分桶表操作,与复杂类型的运用
目录 0.hadoop hive的文档 1.一级分区表 2.一级分区表练习2 3.创建多级分区表 4.分区表操作 5.分桶表 6. 分桶表进行排序 7.分桶的原理 8.hive的复杂类型 9.array类型: 又叫数组类型,存储同类型的单数据的集合 10.struct类型: 又叫结构类型,可以存储不同类型单数据的集合…...

Spring Cloud学习(七)【Docker 容器】
文章目录 初识 DockerDocker 介绍Docker与虚拟机Docker架构安装 Docker Docker 基本操作镜像相关命令容器相关命令数据卷 Dockerfile 自定义镜像镜像结构Dockerfile DockerComposeDockerCompose介绍安装DockerCompose Docker镜像仓库常见镜像仓库服务私有镜像仓库 初识 Docker …...

好题分享(2023.11.5——2023.11.11)
目录 前情回顾: 前言: 题目一:补充《移除链表元素》 题目二:《反转链表》 解法一:三指针法 解法二:头插法 题目三: 《相交链表》 题目四:《合并两个有序数列》 题目五&…...

第二章 03Java基础-IDEA相关叙述
文章目录 前言一、IDEA概述二、IDEA下载和安装三、IDEA项目结构介绍四、IDEA的项目和模块操作总结前言 今天我们学习Java基础,IDEA下载以及相关配置和基础使用方法 一、IDEA概述 1.IDEA全称IntelliJ IDEA,是用于Java语言开发的集成工具,是业界公认的目前用于Java程序开发最…...

第三阶段第二章——Python高阶技巧
时间过得很快,这么快就来到了最后一篇Python基础的学习了。话不多说直接进入这最后的学习环节吧!!! 期待有一天 春风得意马蹄疾,一日看尽长安花 o(* ̄︶ ̄*)o 1.闭包 什么是闭包? 答…...

【Git】Git分支与应用分支Git标签与应用标签
一,Git分支 1.1 理解Git分支 在 Git 中,分支是指一个独立的代码线,并且可以在这个分支上添加、修改和删除文件,同时作为另一个独立的代码线存在。一个仓库可以有多个分支,不同的分支可以独立开发不同的功能࿰…...

本地PHP搭建简单Imagewheel私人云图床,在外远程访问——“cpolar内网穿透”
文章目录 1.前言2. Imagewheel网站搭建2.1. Imagewheel下载和安装2.2. Imagewheel网页测试2.3.cpolar的安装和注册 3.本地网页发布3.1.Cpolar临时数据隧道3.2.Cpolar稳定隧道(云端设置)3.3.Cpolar稳定隧道(本地设置) 4.公网访问测…...

网络编程(Modbus进阶)
思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...

【OSG学习笔记】Day 18: 碰撞检测与物理交互
物理引擎(Physics Engine) 物理引擎 是一种通过计算机模拟物理规律(如力学、碰撞、重力、流体动力学等)的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互,广泛应用于 游戏开发、动画制作、虚…...

《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)
CSI-2 协议详细解析 (一) 1. CSI-2层定义(CSI-2 Layer Definitions) 分层结构 :CSI-2协议分为6层: 物理层(PHY Layer) : 定义电气特性、时钟机制和传输介质(导线&#…...
Java - Mysql数据类型对应
Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...

苍穹外卖--缓存菜品
1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得,如果用户端访问量比较大,数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据,减少数据库查询操作。 缓存逻辑分析: ①每个分类下的菜品保持一份缓存数据…...

【配置 YOLOX 用于按目录分类的图片数据集】
现在的图标点选越来越多,如何一步解决,采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集(每个目录代表一个类别,目录下是该类别的所有图片),你需要进行以下配置步骤&#x…...

2025盘古石杯决赛【手机取证】
前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来,实在找不到,希望有大佬教一下我。 还有就会议时间,我感觉不是图片时间,因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...

网络编程(UDP编程)
思维导图 UDP基础编程(单播) 1.流程图 服务器:短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...

Selenium常用函数介绍
目录 一,元素定位 1.1 cssSeector 1.2 xpath 二,操作测试对象 三,窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四,弹窗 五,等待 六,导航 七,文件上传 …...

宇树科技,改名了!
提到国内具身智能和机器人领域的代表企业,那宇树科技(Unitree)必须名列其榜。 最近,宇树科技的一项新变动消息在业界引发了不少关注和讨论,即: 宇树向其合作伙伴发布了一封公司名称变更函称,因…...