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

opencv——识别图片颜色并绘制轮廓

图像边缘检测

本实验要用到Canny算法,Canny边缘检测方法常被誉为边缘检测的最优方法。
首先,Canny算法的输入端应为图像的二值化结果,接收到二值化图像后,需要按照如下步骤进行:
  1. 高斯滤波。
  2. 计算图像的梯度和方向。
  3. 非极大值抑制。
  4. 双阈值筛选。

1. 高斯滤波

边缘检测本身属于锐化操作,对噪点比较敏感,所以需要进行平滑处理。这里使用的是一个5*5的高斯核对图像进行消除噪声。上一个实验中已经介绍了高斯滤波的具体过程,这里就不再过多叙述,只展示一下用到的5*5的高斯核:

2. 计算图像的梯度与方向

这里使用了sobel算子来计算图像的梯度值,sobel算子其实就是一个核值固定的卷积核,如下所示:
这个角度值其实是当前边缘的梯度的方向,与边缘的方向刚好垂直。通过这个公式我们就可以计算出图片中所有的像素点的梯度值与梯度方向,然后根据梯度方向获取边缘的方向。得到θ的值之后,就可以对边缘方向进行分类,一般将其归为四个方向:水平方向、垂直方向、45°方向、135°方向。并且:
当θ值为-22.5°~22.5°,或-157.5°~157.5°,则认为边缘为水平边缘;
当法线方向为22.5°~67.5°,或-112.5°~-157.5°,则认为边缘为45°边缘;
当法线方向为67.5°~112.5°,或-67.5°~-112.5°,则认为边缘为垂直边缘;
当法线方向为112.5°~157.5°,或-22.5°~-67.5°,则认为边缘为135°边缘;

3. 非极大值抑制

得到每个边缘的方向之后,其实把它们连起来边缘检测就算完了,但是为什么还有这一步与下一步呢?是因为经过第二步得到的边缘不经过处理是没办法使用的,因为高斯滤波的原因,边缘会变得模糊,导致经过第二步后得到的边缘像素点非常多,因此我们需要对其进行一些过滤操作,而非极大值抑制就是一个很好的方法,它会对得到的边缘像素进行一个排除,使边缘尽可能细一点。
在该步骤中,我们需要检查每个像素点的梯度方向上的相邻像素,并保留梯度值最大的像素,将其他像素抑制为零。假设当前像素点为(x,y),其梯度方向是0°,梯度值为G(x,y),那么我们就需要比较G(x,y)与两个相邻像素的梯度值:G(x-1,y)和G(x+1,y)。如果G(x,y)是三个值里面最大的,就保留该像素值,否则将其抑制为零。
并且如果梯度方向不是0°、45°、90°、135°这种特定角度,那么就要用到插值算法来计算当前像素点在其方向上进行插值的结果了,然后进行比较并判断是否保留该像素点。这里使用的是 单线性插值,通过A1和A2两个像素点获得dTmp1与dTmp2处的插值,然后与中心点C进行比较。

4. 双阈值筛选

经过非极大值抑制之后,我们还需要设置阈值来进行筛选,当阈值设的太低,就会出现假边缘,而阈值设的太高,一些较弱的边缘就会被丢掉,因此使用了双阈值来进行筛选,推荐高低阈值的比例为2:1到3:1之间,其原理如下图所示:
当某一像素位置的幅值超过最高阈值时,该像素必是边缘像素;当幅值低于最低像素时,该像素必不是边缘像素;幅值处于最高像素与最低像素之间时,如果它能连接到一个高于阈值的边缘时,则被认为是边缘像素,否则就不会被认为是边缘。也就是说,上图中的A和C是边缘,B不是边缘。因为C虽然不超过最高阈值,但其与A相连,所以C就是边缘。
至此,Canny边缘检测就完成了。在本实验中的双阈值筛选组件中,可以自定义高低阈值的大小,如下图所示:
cv2.Canny(image, threshold1, threshold2, edges, apertureSize, L2gradient)
功能:用于边缘检测的函数
参数:
‌image‌: 输入图像,它 应该是一个灰度图像(单通道)。
‌threshold1‌: 第一个阈值,用于边缘检测的滞后过程。这个值较低,用于确定边缘的初始点。
‌threshold2‌: 第二个阈值,用于边缘检测的滞后过程。这个值较高,用于确定边缘的最终点。如果某个像素点的梯度值高于这个阈值,它被认为是边缘;如果低于这个值但高于threshold1,并且与高于threshold2的像素点相连,它也被认为是边缘。
‌edges‌: 输出图像,与输入图像大小相同,但通常是二值图像(即只包含边缘和非边缘的像素)。
‌apertureSize‌(可选,默认为3): Sobel算子的大小,它决定了梯度计算的邻域大小。它必须是1、3、5或7之一。
‌L2gradient‌(可选,默认为False): 一个布尔值,指示是否使用更精确的L2范数进行梯度计算。如果为True,则使用L2范数(即欧几里得距离);如果为False,则使用L1范数(即曼哈顿距离)。L2范数通常更精确,但计算成本也更高。
import cv2
import numpy as npimg = cv2.imread('../1iamge/color_1.png')
img = cv2.resize(img,(825,632))img_hsv = cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
yellow_min = np.array([20,43,46])
yellow_max = np.array([34,255,255])img_mask = cv2.inRange(img_hsv,yellow_min,yellow_max)
img_mask_color = cv2.bitwise_and(img,img,mask=img_mask)img_blur = cv2.medianBlur(img_mask,3)
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5))
img_erode = cv2.erode(img_blur,kernel)
img_dilate = cv2.dilate(img_erode,kernel)
contours,_ = cv2.findContours(img_dilate,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)img_copy = img.copy()
cv2.drawContours(img_copy,contours,-1,(0,0,255),2)cv2.imshow('img',img)
cv2.imshow("img_copy",img_copy)
cv2.waitKey(0)

原图: 

效果:

相关文章:

opencv——识别图片颜色并绘制轮廓

图像边缘检测 本实验要用到Canny算法,Canny边缘检测方法常被誉为边缘检测的最优方法。 首先,Canny算法的输入端应为图像的二值化结果,接收到二值化图像后,需要按照如下步骤进行: 高斯滤波。计算图像的梯度和方向。非极…...

docker简单私有仓库的创建

1:下载Registry镜像 导入镜像到本地中 [rootlocalhost ~]# docker load -i registry.tag.gz 进行检查 2:开启Registry registry开启的端口号为5000 [rootlocalhost ~]# docker run -d -p 5000:5000 --restartalways registry [rootlocalhost ~]# dock…...

etcd常见运维事件

1、etcd扩/缩容 参考:etcd节点扩/缩容-CSDN博客 2、etcd数据备份/恢复 数据备份 数据备份要从leader节点进行备份,否则可能存在数据同步延迟导致数据不一致; etcdctl --endpoints"https://10.119.48.166:2379" snapshot save /d…...

[代码随想录17]二叉树之最大二叉树、合并二叉树、二搜索树中的搜索、验证二叉搜索树。

前言 二叉树的题目还是要会一流程构造函数之类的。其中还有回溯的思想 题目链接 654. 最大二叉树 - 力扣(LeetCode) 一、最大二叉树 思路:还是考察构造二叉树,简单来说就是给你一个数组去构建一个二叉树,递归来解决就…...

前端三大框架 Vue、React 和 Angular 的市场占比分析

一、引言 ?? 随着前端技术的迅速发展,Vue.js、React 和 Angular 已成为全球最受欢迎的三大前端框架。在国内外,不同的框架在市场中的占比和流行程度存在显著差异。本文将从全球和中国市场的角度,对这三大框架的市场占比进行分析&#xff0…...

12.3【JAVA-EXP4-DEBUGSTUDY】

java升级版本 JDK 1.8 是 Java Development Kit 的第 8 版本,发布于 2014 年 3 月 18 日。这个版本是 Java SE(Standard Edition)的一部分,包含了 Java 编程语言的实现、编译器、调试工具和其他相关组件 JDK 1.8: 这里的 1.8 表…...

flutter命令行直接指定设备

> flutter driver Found 3 connected devices:sdk gphone16k x86 64 (mobile) • emulator-5554 • android-x64 • Android 15 (API 35) (emulator)Linux (desktop) • linux • linux-x64 • Ubuntu 22.04.5 LTS 6.8.0-49-genericChrome (…...

Spring核心--Bean后处理器

Spring的后处理器(Spring核心重点) Spring的后处理器是Spring对外开发的重要扩展点,允许我们介入到Bean的整个实例化流程中来,以达到动态注册BeanDefinition,动态修改BeanDefinition,以及动态修改Bean的作用。Spring主要有两种后处理器: ​ BeanFactoryPostProcessor: Bean工…...

Windows子系统Ubuntu本地部署xinference以及接入dify详解

背景介绍 系统:Ubuntu 22.04.5 LTSpython环境管理工具:mincondadify版本:0.13.2本文参考 Xinference在线文档和dify的官方介绍模型接入 1. Github拉取Xinference代码 首选去Xinference的Github地址拉取代码 2. 在minconda创建隔离环境 - xinfernce 是我本地创建的环境名…...

如何实现接口继承与实现继承的区别?如何处理多态性与性能的平衡?

在面向对象编程中,接口继承和实现继承是两个重要的概念,同时多态性也是面向对象编程的一大特性,但在追求多态性的同时,我们也需要考虑性能问题。本文将详细探讨接口继承与实现继承的区别,以及如何处理多态性与性能的平…...

VR虚拟展厅的实时互动是如何实现的?

VR虚拟展厅的实时互动是通过一系列技术和流程实现的,这些技术和流程共同确保了用户在虚拟环境中的互动体验能够及时响应和更新。 接下来,由专业从事VR虚拟展厅制作的圆桌3D云展厅平台为大家介绍一下实现VR虚拟展厅实时互动的几个关键要素: 高…...

Java、鸿蒙与嵌入式开发:技术选择与职业发展分析

在当今快速发展的科技领域中,Java、鸿蒙和嵌入式开发代表着不同的技术方向和职业机遇。每个方向都有其独特的市场价值和发展前景,让我们深入分析这三个领域的特点、发展趋势和职业规划。 Java开发方向已经发展了二十多年,仍然在软件开发领域…...

28. Three.js案例-创建圆角矩形并进行拉伸

28. Three.js案例-创建圆角矩形并进行拉伸 实现效果 知识点 WebGLRenderer (WebGL渲染器) WebGLRenderer 是 Three.js 中用于渲染 3D 场景的主要渲染器。 构造器 WebGLRenderer( parameters : Object ) 参数类型描述parametersObject渲染器的配置参数,可选。 …...

Shopee算法分析 - x-sap-ri

去除干扰项 在上篇文章中说到, 我们主动调用了几次,返回结果都是不同的 相同参数, 我们主动多次call. 可以看到结果是不同的. 只有一个Key不同. 接下来, 引用龙哥的文章 引用自龙哥文章, 我仅仅是对关键信息做加粗 1.1 引言 在使用 Unidbg 模拟执行以及辅助算法还原时&#x…...

日志相关的学习记录

Logger.error还不知道怎么传参打印?看完这个你就明白了-CSDN博客 日志使用的方式 使用e.getMessage()、e .toString() 都不会打印堆栈信息,最好直接打印e。 当使用两个参数error(String message, Throwable t),且第二个参数为Throwable(就是…...

HTML和JavaScript实现商品购物系统

下面是一个更全面的商品购物系统示例,包含新增商品、商品的增加删除以及结算找零的功能。这个系统使用HTML和JavaScript实现。 1.功能说明: 这个应用程序使用纯HTML和JavaScript实现。 包含一个商品列表和一个购物车区域。商品列表中有几个示例商品&a…...

深度学习中的激活函数

激活函数(activation function)是应用于网络中各个神经元输出的简单变换,为其引入非线性属性,使网络能够对更复杂的数据进行建模,使其能够学习更复杂的模式。如果没有激活函数,神经元只会对输入进行枯燥的线性数学运算。这意味着&…...

编写php项目所需环境

需要编写php项目,需要看到编写的代码展现的效果,这里我选择用xampp来展现 准备工作: https://learncodingfast.com/how-to-install-xampp-and-brackets/#Installing_and_Running_XAMPP xampp下载地址:https://www.apachefriends.…...

华为机试HJ108 求最小公倍数

首先看一下题 描述 正整数A和正整数B 的最小公倍数是指 能被A和B整除的最小的正整数值,设计一个算法,求输入A和B的最小公倍数。 数据范围: 1≤a,b≤100000 输入描述: 输入两个正整数A和B。 输出描述: 输出A和B的最小公…...

【Python技术】同花顺wencai涨停分析基础上增加连板分析

周末,有读者加我, 说 之前的涨停分析 是否可以增加连板分析。 这个可以加上。 先看效果 这里附上完整代码: import streamlit as st import pywencai import pandas as pd from datetime import datetime, timedelta import plotly.graph_o…...

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...

大数据学习栈记——Neo4j的安装与使用

本文介绍图数据库Neofj的安装与使用&#xff0c;操作系统&#xff1a;Ubuntu24.04&#xff0c;Neofj版本&#xff1a;2025.04.0。 Apt安装 Neofj可以进行官网安装&#xff1a;Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...

Day131 | 灵神 | 回溯算法 | 子集型 子集

Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a; 笔者写过很多次这道题了&#xff0c;不想写题解了&#xff0c;大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...

在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module

1、为什么要修改 CONNECT 报文&#xff1f; 多租户隔离&#xff1a;自动为接入设备追加租户前缀&#xff0c;后端按 ClientID 拆分队列。零代码鉴权&#xff1a;将入站用户名替换为 OAuth Access-Token&#xff0c;后端 Broker 统一校验。灰度发布&#xff1a;根据 IP/地理位写…...

Python实现prophet 理论及参数优化

文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候&#xff0c;写过一篇简单实现&#xff0c;后期随着对该模型的深入研究&#xff0c;本次记录涉及到prophet 的公式以及参数调优&#xff0c;从公式可以更直观…...

【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表

1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...

【项目实战】通过多模态+LangGraph实现PPT生成助手

PPT自动生成系统 基于LangGraph的PPT自动生成系统&#xff0c;可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析&#xff1a;自动解析Markdown文档结构PPT模板分析&#xff1a;分析PPT模板的布局和风格智能布局决策&#xff1a;匹配内容与合适的PPT布局自动…...

【HTML-16】深入理解HTML中的块元素与行内元素

HTML元素根据其显示特性可以分为两大类&#xff1a;块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...

Java数值运算常见陷阱与规避方法

整数除法中的舍入问题 问题现象 当开发者预期进行浮点除法却误用整数除法时,会出现小数部分被截断的情况。典型错误模式如下: void process(int value) {double half = value / 2; // 整数除法导致截断// 使用half变量 }此时...

在Mathematica中实现Newton-Raphson迭代的收敛时间算法(一般三次多项式)

考察一般的三次多项式&#xff0c;以r为参数&#xff1a; p[z_, r_] : z^3 (r - 1) z - r; roots[r_] : z /. Solve[p[z, r] 0, z]&#xff1b; 此多项式的根为&#xff1a; 尽管看起来这个多项式是特殊的&#xff0c;其实一般的三次多项式都是可以通过线性变换化为这个形式…...