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

news2024/11/25 23:27:11

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实现几何图形检测

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

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

完整代码:

import cv2 as cv
import numpy as np


class ShapeAnalysis:
    def __init__(self):
        self.shapes = {'triangle': 0, 'rectangle': 0, 'polygons': 0, 'circles': 0}

    def analysis(self, frame):
        h, w, ch = frame.shape
        result = 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:
                continue

            if corners == 3:
                count = self.shapes['triangle']
                count = count + 1
                self.shapes['triangle'] = count
                shape_type = "三角形"
            if corners == 4:
                count = self.shapes['rectangle']
                count = count + 1
                self.shapes['rectangle'] = count
                shape_type = "矩形"
            if corners >= 10:
                count = self.shapes['circles']
                count = count + 1
                self.shapes['circles'] = count
                shape_type = "圆形"
            if 4 < corners < 10:
                count = self.shapes['polygons']
                count = count + 1
                self.shapes['polygons'] = count
                shape_type = "多边形"


            # 求解中心位置
            mm = cv.moments(contours[cnt])

            if mm['m00'] == 0:
                continue

            cx = 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.shapes


if __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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1325434.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python学习笔记(六):函数的多返回值、函数的多种参数使用形式、匿名函数、文件的读取操作、文件的写入 、文件的追加

目录 一、函数的多返回值 二、函数的多种参数使用形式 2.1位置参数 2.2关键字参数 2.3缺省参数 2.4不定长参数 三、匿名函数 3.1 函数作为参数传递 3.2 函数的定义 3.3 匿名函数定义语法&#xff1a; 四、文件的读取操作 4.1 open&#xff08;&#xff09;打开函数…

【WPF.NET开发】样式和模板

本文内容 示例样式ControlTemplateDataTemplate触发器视觉状态共享资源和主题 Windows Presentation Foundation (WPF) 样式设置和模板化是指一套功能&#xff0c;这套功能使开发者和设计者能够为其产品创建极具视觉表现力的效果和一致的外观。 自定义应用的外观时&#xff0…

【精选】Lombok概述及常用注解使用方法

Lombok概述 Lombok项目是一个java库&#xff0c;它可以自动插入到编辑器和构建工具中&#xff0c;增强java的性能。不需要再写getter、setter或equals方法&#xff0c;只要有一个注解&#xff0c;就有一个功能齐全的构建器、自动记录变量等等。 以前的Java项目中&#xff0c;充…

2002年AMC8数学竞赛中英文真题典型考题、考点分析和答案解析

今天是2023年12月21日&#xff0c;距离2024年的AMC8正式考试倒计时已不足30天了。 六分成长继续和您一起&#xff0c;从历年的真题中来了解考试题型、考试形式、对知识点查漏补缺。如果您有任何关于AMC8比赛的任何问题都可以问我&#xff0c;关于题目的解析也可以交流。敲黑板…

Ansible的脚本----playbook剧本

Playbook组成部分 tasks 任务&#xff1a;包含要在目标主机上执行的操作&#xff0c;使用模块定义这些操作。每个任务都是一个模块的调用。Variables 变量&#xff1a;存储和传递数据。变量可以自定义&#xff0c;可以在playbook当中定义全局变量&#xff0c;可以外部传参。T…

ARM GIC(二)中断分类

一、中断状态 对于每一个中断而言,有以下4个状态: inactive:中断处于无效状态 pending:中断处于有效状态,但是cpu没有响应该中断 active:cpu在响应该中断 active and pending:cpu在响应该中断,但是该中断源又发送中断过来 以下是中断状态的转移图。至于图中的转移…

基于Redis限流(aop切面+redis实现“令牌桶算法”)

令牌桶算法属于流量控制算法&#xff0c;在一定时间内保证一个键&#xff08;key&#xff09;的访问量不超过某个阈值。这里的关键是设置一个令牌桶&#xff0c;在某个时间段内生成一定数量的令牌&#xff0c;然后每次访问时从桶中获取令牌&#xff0c;如果桶中没有令牌&#x…

U-MixFormer:用于高效语义分割的类unet结构的混合注意力Transformer

论文&#xff1a; 代码&#xff1a;GitHub - RecklessRonan/MuSE 感觉这篇比较优雅无痛涨点欸.....最近要期末了没时间看文章和做实验了&#xff08;摊 摘要 语义分割在Transformer架构的适应下取得了显著的进步。与Transformer的进步并行的是基于CNN的U-Net在高质量医学影…

数据可视化---直方图

内容导航 类别内容导航机器学习机器学习算法应用场景与评价指标机器学习算法—分类机器学习算法—回归机器学习算法—聚类机器学习算法—异常检测机器学习算法—时间序列数据可视化数据可视化—折线图数据可视化—箱线图数据可视化—柱状图数据可视化—饼图、环形图、雷达图统…

HarmonyOS概述

HarmonyOS概述 HarmonyOS系统架构 内核层—系统服务层—框架层—应用层 内核层&#xff1a; 内核子系统: HarmonyOS采用多内核设计&#xff0c;支持针对不同资源受限设备 &#xff0c;选用适合的OS内核&#xff0c;为上层提供基础操作系统能力。驱动子系统: 硬件驱动框架(H…

【Spring Security】打造安全无忧的Web应用--入门篇

&#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 接下来看看由辉辉所写的关于Spring Security的相关操作吧 目录 &#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 一.Spring Security是什么 1.概…

小鹅通基于 TSE 云原生 API 网关的落地实践

导语 2023腾讯全球数字生态大会已于9月7-8日完美落幕&#xff0c;40专场活动展示了腾讯最新的前沿技术、核心产品、解决方案。 微服务与消息队列专场&#xff0c;我们邀请到了小鹅通的基础架构组负责人黄徐震为我们带来了《小鹅通基于 TSE 云原生网关的落地实践》的精彩演讲。…

java 4.数组

文章目录 4.数组4.1数组的概念4.2 数组的定义4.3 数组的初始化4.4 数组下标的有效范围与常见异常4.5 数组内存分析4.6 二维数组4.6.1 创建二维数组4.6.2 二维数组的赋值4.6.3 多维数组4.6.4 通过二维数组输出不同版式的古诗 4.7 不规则数组4.8 数组的基本操作4.8.1 数组遍历4.8…

前后端分离下的鸿鹄电子招投标系统:使用Spring Boot、Mybatis、Redis和Layui实现源码与立项流程

在数字化时代&#xff0c;采购管理也正经历着前所未有的变革。全过程数字化采购管理成为了企业追求高效、透明和规范的关键。该系统通过Spring Cloud、Spring Boot2、Mybatis等先进技术&#xff0c;打造了从供应商管理到采购招投标、采购合同、采购执行的全过程数字化管理。通过…

hadoop格式化报错

在var/bigdata/hadoop/ha/dfs/jn/下没有mycluster目录增加后就格式化成功了

C/C++、Java、Python:主要编程语言的演进与未来趋势

导言 C/C、Java、Python作为主要的编程语言&#xff0c;在软件开发领域扮演着重要角色。本文将深入研究这三者的发展历程、遇到的问题、解决过程&#xff0c;以及未来的可用范围。同时&#xff0c;分析它们之间的联系与区别&#xff0c;探讨哪一门语言可能在未来占据主导地位&a…

Opencv入门6(读取彩色视频并转换为对数极坐标视频)

源码如下&#xff1a; #include <opencv2/opencv.hpp> #include <iostream> int main(int argc, char* argv[]) { cv::namedWindow("Example2_11", cv::WINDOW_AUTOSIZE); cv::namedWindow("Log_Polar", cv::WINDOW_AUTOSIZE); c…

在mt4上怎么查看CHFJPY品种的合约细则?

在MetaTrader 4 (MT4) 上查看CHFJPY品种的合约细则的方法如下&#xff1a; FXCM福汇官方个人注册登录流程 1.打开MT4软件并登录到您的交易账户。 2.在MT4界面的"市场观察"窗格中&#xff0c;找到并右键单击"CHFJPY"货币对。如果您无法找到"市场观察…

Android: Ubuntu下交叉环境编译常用调试工具demo for lspci命令(ARM设备)

lspci命令交叉环境编译(ARM设备) 交叉编译工具下载&#xff1a; https://releases.linaro.org/components/toolchain/binaries https://releases.linaro.org/components/toolchain/binaries/6.3-2017.05/aarch64-linux-gnu/ lspci命令交叉环境编译(ARM设备)&#xff1a; 1&a…

solidity 重入漏洞

目录 1. 重入漏洞的原理 2. 重入漏洞的场景 2.1 msg.sender.call 转账 2.2 修饰器中调用地址可控的函数 1. 重入漏洞的原理 重入漏洞产生的条件&#xff1a; 合约之间可以进行相互间的外部调用 恶意合约 B 调用了合约 A 中的 public funcA 函数&#xff0c;在函数 funcA…