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

使用opencv实现图像中几何图形检测

1 几何图形检测介绍

1.1 轮廓(contours)

什么是轮廓,简单说轮廓就是一些列点相连组成形状、它们拥有同样的颜色、轮廓发现在图像的对象分析、对象检测等方面是非常有用的工具,在OpenCV
中使用轮廓发现相关函数时候要求输入图像是二值图像,这样便于轮廓提取、边缘提取等操作。轮廓发现的函数与参数解释如下:

函数原型:

findContours(image, mode, method, contours=None, hierarchy=None, offset=None)

参数:

  • image输入/输出的二值图像
  • mode 迒回轮廓的结构、可以是List、Tree、External
  • method 轮廓点的编码方式,基本是基于链式编码
  • contours 迒回的轮廓集合
  • hieracrchy 迒回的轮廓层次关系
  • offset 点是否有位移

1.2 多边形逼近

多边形逼近,是通过对轮廓外形无限逼近,删除非关键点、得到轮廓的关键点,不断逼近轮廓真实形状的方法,OpenCV中多边形逼近的函数与参数解释如下:

函数原型:

approxPolyDP(curve, epsilon, closed, approxCurve=None)

参数:

  • curve 表示输入的轮廓点集合
  • epsilon 表示逼近曲率,越小表示相似逼近越厉害
  • close 是否闭合

1.3 几何距计算

图像几何距是图像的几何特征,高阶几何距中心化之后具有特征不变性,可以产生Hu距输出,用于形状匹配等操作,这里我们通过计算一阶几何距得到指定轮廓的中心位置,计算几何距的函数与参数解释如下:

函数原型:

moments(array, binaryImage=None)

参数:

  • array表示指定输入轮廓
  • binaryImage默认为None

2 基于opencv实现几何图形检测

整个代码实现分为如下几步完成

  • 加载图像,
  • 图像二值化
  • 轮廓发现
  • 几何形状识别
  • 测量周长、面积、计算中心
  • 颜色提取

2.1 加载图像并进行二值化处理

的二值化,就是将图像上的像素点的灰度值设置为0或255,也就是将整个图像呈现出明显的只有黑和白的视觉效果。

一幅图像包括目标物体、背景还有噪声,要想从多值的数字图像中直接提取出目标物体,常用的方法就是设定一个阈值T,用T将图像的数据分成两部分:大于T的像素群和小于T的像素群。这是研究灰度变换的最特殊的方法,称为图像的二值化(Binarization)。

函数原型:

def threshold(src: Any,thresh: Any,maxval: Any,type: Any,dst: Any = None) -> None

src:源图像,可以为8位的灰度图,也可以为32位的彩色图像。(两者由区别)

dst:输出图像

thresh:阈值

maxval:dst图像中最大值

type:阈值类型,可以具体类型如下:

           enum ThresholdTypes {THRESH_BINARY     = 0,            //黑白

                                                 THRESH_BINARY_INV = 1,        //黑白反转

                                                 THRESH_TRUNC      = 2,        //得到图像多像素值

                                                 THRESH_TOZERO     = 3,        //当前点值大于阈值时,不改

                                                                                                    变,否则设置为0

                                                 THRESH_TOZERO_INV = 4,        //当前点值大于阈值时,

                                                                                                    设置为0,否则不改变

                                                  THRESH_MASK       = 7,

                                                  THRESH_OTSU       = 8,        //自适应阈值

                                                  THRESH_TRIANGLE   = 16
             };

具体实现代码:

frame = cv.imread("./data/jihe2.png")# 二值化图像
gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY_INV | cv.THRESH_OTSU)
cv.imshow("input image", frame)

2.2 轮廓检测与逼近

当需要对图像进行形状分析时,需要使用多边形逼近一个轮廓,使得顶点数目变少,算法原理比较简单,核心就是不断找多边形最远的点加入形成新的多边形,直到最短距离小于指定的精度。OpenCV里面用函数approxPolyDP()实现。approxPolyDP()用另一条顶点较少的曲线来逼近一条曲线或者一个多边形,这样两条曲线之间的距离小于或等于指定的精度。同时也有使闭合逼近曲线的选项(那就是说,起始点和终止点相同)。

findContours后的轮廓信息contours可能过于复杂不平滑,可以用approxPolyDP函数对该多边形曲线做适当近似,approxPolyDP 主要功能是把一个连续光滑曲线折线化,对图像轮廓点进行多边形拟合。

具体实现代码:

contours, hierarchy = cv.findContours(binary, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)
for cnt in range(len(contours)):# 提取与绘制轮廓cv.drawContours(result, contours, cnt, (0, 255, 0), 2)# 轮廓逼近epsilon = 0.01 * cv.arcLength(contours[cnt], True)approx = cv.approxPolyDP(contours[cnt], epsilon, True)

2.3 几何形状判断

根据corners数量对形状进行判断。

approx = cv.approxPolyDP(contours[cnt], epsilon, True)# 分析几何形状
corners = len(approx)
shape_type = ""if corners < 3:continueif corners == 3:count = self.shapes['triangle']count = count + 1self.shapes['triangle'] = countshape_type = "三角形"
if corners == 4:count = self.shapes['rectangle']count = count + 1self.shapes['rectangle'] = countshape_type = "矩形"
if corners >= 10:count = self.shapes['circles']count = count + 1self.shapes['circles'] = countshape_type = "圆形"
if 4 < corners < 10:count = self.shapes['polygons']count = count + 1self.shapes['polygons'] = countshape_type = "多边形"

2.4 面积周长计算

# 计算面积与周长
p = cv.arcLength(contours[cnt], True)
area = cv.contourArea(contours[cnt])
print("周长: %.3f, 面积: %.3f 颜色: %s 形状: %s " % (p, area, color_str, 

2.5 完整代码:

import cv2 as cv
import numpy as npclass ShapeAnalysis:def __init__(self):self.shapes = {'triangle': 0, 'rectangle': 0, 'polygons': 0, 'circles': 0}def analysis(self, frame):h, w, ch = frame.shaperesult = np.zeros((h, w, ch), dtype=np.uint8)# 二值化图像print("start to detect lines...\n")gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY_INV | cv.THRESH_OTSU)cv.imshow("input image", frame)contours, hierarchy = cv.findContours(binary, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)for cnt in range(len(contours)):# 提取与绘制轮廓cv.drawContours(result, contours, cnt, (0, 255, 0), 2)# 轮廓逼近epsilon = 0.01 * cv.arcLength(contours[cnt], True)approx = cv.approxPolyDP(contours[cnt], epsilon, True)# 分析几何形状corners = len(approx)shape_type = ""if corners < 3:continueif corners == 3:count = self.shapes['triangle']count = count + 1self.shapes['triangle'] = countshape_type = "三角形"if corners == 4:count = self.shapes['rectangle']count = count + 1self.shapes['rectangle'] = countshape_type = "矩形"if corners >= 10:count = self.shapes['circles']count = count + 1self.shapes['circles'] = countshape_type = "圆形"if 4 < corners < 10:count = self.shapes['polygons']count = count + 1self.shapes['polygons'] = countshape_type = "多边形"# 求解中心位置mm = cv.moments(contours[cnt])if mm['m00'] == 0:continuecx = int(mm['m10'] / mm['m00'])cy = int(mm['m01'] / mm['m00'])cv.circle(result, (cx, cy), 3, (0, 0, 255), -1)# 颜色分析color = frame[cy][cx]color_str = "(" + str(color[0]) + ", " + str(color[1]) + ", " + str(color[2]) + ")"# 计算面积与周长p = cv.arcLength(contours[cnt], True)area = cv.contourArea(contours[cnt])print("周长: %.3f, 面积: %.3f 颜色: %s 形状: %s " % (p, area, color_str, shape_type))cv.imshow("Analysis Result", result)print("triangle: ", self.shapes['triangle'])print("rectangle: ", self.shapes['rectangle'])print("polygons: ", self.shapes['polygons'])print("circles: ", self.shapes['circles'])return self.shapesif __name__ == "__main__":src = cv.imread("./data/jihe2.png")ld = ShapeAnalysis()ld.analysis(src)cv.waitKey(0)cv.destroyAllWindows()

原始图像:

运行结果显示:

周长: 553.973, 面积: 11687.500 颜色: (190, 146, 112) 形状: 矩形 
周长: 479.556, 面积: 14743.500 颜色: (232, 162, 0) 形状: 矩形 
周长: 543.144, 面积: 18333.500 颜色: (21, 0, 136) 形状: 多边形 
周长: 341.421, 面积: 7593.000 颜色: (164, 73, 163) 形状: 多边形 
周长: 761.796, 面积: 13221.500 颜色: (87, 122, 185) 形状: 圆形 
周长: 594.257, 面积: 24703.500 颜色: (39, 127, 255) 形状: 圆形 
周长: 592.000, 面积: 14508.000 颜色: (36, 28, 237) 形状: 矩形 
周长: 432.291, 面积: 11939.500 颜色: (204, 72, 63) 形状: 多边形 
周长: 280.451, 面积: 4917.000 颜色: (190, 146, 112) 形状: 多边形 
周长: 531.588, 面积: 10587.000 颜色: (164, 73, 163) 形状: 矩形 
周长: 405.262, 面积: 4172.500 颜色: (76, 177, 34) 形状: 圆形 
周长: 370.191, 面积: 9746.000 颜色: (232, 162, 0) 形状: 圆形 
周长: 486.000, 面积: 14762.000 颜色: (232, 162, 0) 形状: 矩形 
triangle:  0
rectangle:  5
polygons:  4
circles:  4

相关文章:

使用opencv实现图像中几何图形检测

1 几何图形检测介绍 1.1 轮廓(contours) 什么是轮廓&#xff0c;简单说轮廓就是一些列点相连组成形状、它们拥有同样的颜色、轮廓发现在图像的对象分析、对象检测等方面是非常有用的工具&#xff0c;在OpenCV 中使用轮廓发现相关函数时候要求输入图像是二值图像&#xff0c;这…...

补题与周总结:leetcode第 376 场周赛

文章目录 复盘与一周总结2967. 使数组成为等数数组的最小代价&#xff08;中位数贪心 回文数判断&#xff09;2968. 执行操作使频率分数最大&#xff08;中位数贪心 前缀和 滑窗&#xff09; 复盘与一周总结 wa穿了第3题&#xff0c;赛时其实想到了思路&#xff1a;中位数贪心…...

js指纹库,可跟踪用户唯一性

fingerprintjs官网 资料&#xff1a; Browserleaks - Check your browser for privacy leaks...

Shell三剑客:awk(内部变量)

一、$0 &#xff1a;完整的输入记录 [rootlocalhost ~]# awk -F: {print $0} passwd.txt root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/s…...

JVM中的虚拟机栈的动态链接部分存放到底是什么

在Java虚拟机&#xff08;JVM&#xff09;中&#xff0c;每个线程在执行一个方法时都会创建一个栈帧&#xff08;Stack Frame&#xff09;&#xff0c;栈帧中包含了方法的运行时数据。栈帧通常包括局部变量表、操作数栈、动态链接、方法返回地址等部分。 动态链接 动态链接&a…...

Leetcode 55 跳跃游戏

题意理解&#xff1a; 非负整数数组 nums, 最初位于数组的 第一个下标 。 数组中的每个元素代表你在该位置可以跳跃的最大长度。 需要跳到nums最后一个元素即为成功。 目标&#xff1a;是否能够跳到最后一个元素。 解题思路&#xff1a; 使用贪心算法来解题&#xff0c;需要理解…...

构建陪诊预约系统:技术实战指南

在医疗科技的飞速发展中&#xff0c;陪诊预约系统的应用为患者和陪诊人员提供了更为便捷和贴心的服务。本文将带领您通过技术实现&#xff0c;构建一个简单而实用的陪诊预约系统&#xff0c;以提升医疗服务的效率和用户体验。 技术栈选择 在开始之前&#xff0c;我们需要选择…...

windows和linux将文件删除至回收站【C++】【Go】语言实现

目录 C Windows平台 Linux平台 开平台&#xff0c;代码合并 Go 实现步骤 Go语言实现示例 go单独的windows版本实现 代码解释 C 在C中&#xff0c;将文件移动到回收站的实现在Linux和Windows平台上是不同的。首先&#xff0c;我会为你提供在Windows平台上实现的代码示例…...

10 Vue3中v-html指令的用法

概述 v-html主要是用来渲染富文本内容&#xff0c;比如评论信息&#xff0c;新闻信息&#xff0c;文章信息等。 v-html是一个特别不安全的指令&#xff0c;因为它会将文本以HTML的显示进行渲染&#xff0c;一旦文本里面包含一些恶意的js代码&#xff0c;可能会导致整个网页发…...

华为数通方向HCIP-DataCom H12-831题库(多选题:181-200)

第181题 如图所示,R1、R2、R3、R4都部署为SPF区域0,链路的cost值如图中标识。R1、R2R3、R4的Loopback0通告入OSPF。R1、R2、R3与R4使用Loopback0作为连接接口,建立BGP对等体关系,其中R4为RR设备,R1、R2、R3是R4的客户端。当R4的直连地址172.20,1,4/32通告入BGP后,以下关R…...

DC-磁盘管理

2023年全国网络系统管理赛项真题 模块B-Windows解析 题目 在DC2上安装及配置软RAID 5。在安装好的DC2虚拟机中添加三块10G虚拟磁盘。组成RAID 5,磁盘分区命名为卷标H盘:Raid5。手动测试破坏一块磁盘,做RAID磁盘修复,确认RAID 5配置完毕。配置步骤 关闭虚拟机,添加3块10G磁…...

使用Docker运行镜像文件与设置端口

1&#xff0c;创建镜像文件前准备 # 使用基础镜像FROM alpine:latest# 设置工作目录WORKDIR /app# 复制应用程序文件到镜像中COPY . .# 暴露容器的端口 不会自动将容器的端口映射到宿主机上 docker run -d -p <宿主机端口>:7080 <镜像名称>EXPOSE 7080# 定义容器启…...

Centos 8.5 Oracle12c安装

由于多次安装踩坑&#xff0c;所以本次写了一份12c安装的完整版。可以直接使用。 一、安装数据库基本信息 名称 值 主机名 database 操作系统 CentOS Linux release 8.5.2111 Oracle用户名/密码 oracle Oracle 版本 12c Enterprise Edition Release 12.2.0.1.0 oracle…...

Apache Tomcat httpoxy 安全漏洞 CVE-2016-5388 已亲自复现

Apache Tomcat httpoxy 安全漏洞 CVE-2016-5388 已亲自复现 漏洞名称漏洞描述影响版本 漏洞复现环境搭建漏洞利用 修复建议总结 漏洞名称 漏洞描述 在Apache Tomcat中发现了一个被归类为关键的漏洞&#xff0c;该漏洞在8.5.4(Application Server Soft ware)以下。受影响的是组…...

ChatGLM3-6B 的调用参数说明,chat 与stream_chat 接口函数的参数说明

ChatGLM3-6B 是一个语言大模型&#xff0c;最近在评估这个模型&#xff0c;但发现它的文档有限&#xff0c;只能从demo代码中猜测调用的参数的含义&#xff0c;准确度是有限的&#xff1b;于是&#xff0c;通过查看源代码来研究&#xff0c;目前整理笔记如下&#xff1a; Chat…...

Vuex的学习-2

Vuex的核心概念 StateMutationAction 1.State State提供唯一的公共数据源&#xff0c;所有共享的数据都统一放在Store的State中进行存储。 const store new Vuex.Store({state : { count: 0 } }) 这是渲染的页面 组件访问数据的第一种方式 组件访问数据的第二种方式 // 1…...

智慧安防视频监控EasyCVR如何通过回调接口向第三方平台推送RTSP视频通道离线通知

安防视频监控系统EasyCVR能在局域网、公网、专网等复杂的网络环境中部署&#xff0c;可支持4G、5G、WiFi、有线等方式进行视频的接入与传输、处理和分发。平台能将接入的视频流进行汇聚、转码、多格式输出和分发&#xff0c;具体包括&#xff1a;RTMP、RTSP、HTTP-FLV、WebSock…...

Scrum项目管理流程及免费敏捷工具

​ 项目启动&#xff1a; 团队明确项目愿景、目标和范围&#xff0c;确定项目范围和优先级&#xff0c;并建立团队以及开展初步计划。 制定产品待办事项清单&#xff08;Product Backlog&#xff09;&#xff1a; 定义项目所需功能、任务和需求列表&#xff0c;并按优先级排序…...

大型医院PACS系统源码,影像存储与传输系统源码,支持多种图像处理及三维重建功能

PACS系统是医院影像科室中应用的一种系统&#xff0c;主要用于获取、传输、存档和处理医学影像。它通过各种接口&#xff0c;如模拟、DICOM和网络&#xff0c;以数字化的方式将各种医学影像&#xff0c;如核磁共振、CT扫描、超声波等保存起来&#xff0c;并在需要时能够快速调取…...

HDFS NFS Gateway(环境配置,超级详细!!)

HDFS NFS Gateway简介: ​ HDFS NFS Gateway是Hadoop Distributed File System&#xff08;HDFS&#xff09;中的一个组件&#xff0c;它允许客户端通过NFS&#xff08;Network File System&#xff0c;网络文件系统&#xff09;与HDFS进行交互。具体来说&#xff0c;HDFS NFS…...

Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件

今天呢&#xff0c;博主的学习进度也是步入了Java Mybatis 框架&#xff0c;目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学&#xff0c;希望能对大家有所帮助&#xff0c;也特别欢迎大家指点不足之处&#xff0c;小生很乐意接受正确的建议&…...

(二)TensorRT-LLM | 模型导出(v0.20.0rc3)

0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述&#xff0c;后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作&#xff0c;其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...

django filter 统计数量 按属性去重

在Django中&#xff0c;如果你想要根据某个属性对查询集进行去重并统计数量&#xff0c;你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求&#xff1a; 方法1&#xff1a;使用annotate()和Count 假设你有一个模型Item&#xff0c;并且你想…...

python如何将word的doc另存为docx

将 DOCX 文件另存为 DOCX 格式&#xff08;Python 实现&#xff09; 在 Python 中&#xff0c;你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是&#xff0c;.doc 是旧的 Word 格式&#xff0c;而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...

HBuilderX安装(uni-app和小程序开发)

下载HBuilderX 访问官方网站&#xff1a;https://www.dcloud.io/hbuilderx.html 根据您的操作系统选择合适版本&#xff1a; Windows版&#xff08;推荐下载标准版&#xff09; Windows系统安装步骤 运行安装程序&#xff1a; 双击下载的.exe安装文件 如果出现安全提示&…...

土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等

&#x1f50d; 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术&#xff0c;可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势&#xff0c;还能有效评价重大生态工程…...

EtherNet/IP转DeviceNet协议网关详解

一&#xff0c;设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络&#xff0c;本网关连接到EtherNet/IP总线中做为从站使用&#xff0c;连接到DeviceNet总线中做为从站使用。 在自动…...

Unit 1 深度强化学习简介

Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库&#xff0c;例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体&#xff0c;比如 SnowballFight、Huggy the Do…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用

1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...

【JavaWeb】Docker项目部署

引言 之前学习了Linux操作系统的常见命令&#xff0c;在Linux上安装软件&#xff0c;以及如何在Linux上部署一个单体项目&#xff0c;大多数同学都会有相同的感受&#xff0c;那就是麻烦。 核心体现在三点&#xff1a; 命令太多了&#xff0c;记不住 软件安装包名字复杂&…...