分水岭算法分割和霍夫变换识别图像中的硬币

首先解释一下第一种分水岭算法:

一、分水岭算法

分水岭算法是一种基于拓扑学的图像分割技术,广泛应用于图像处理和计算机视觉领域。它将图像视为一个拓扑表面,其中亮度值代表高度。算法的目标是通过模拟雨水从山顶流到山谷的过程,将图像分割成若干独立的区域。

分水岭算法的步骤和原理:

  1. 距离变换

    • 首先对图像进行预处理,将图像转化为灰度图,并进行二值化处理(如Otsu算法)。
    • 对二值图像应用距离变换,计算每个前景像素到最近的背景像素的距离,生成距离图。距离变换后的图像可以看作是一幅"地形图",前景像素的距离值越大,代表的高度越高。
  2. 寻找局部极大值

    • 在距离图中找到局部极大值点。这些点通常位于目标物体的中心位置,将作为初始标记。局部极大值点是那些比其邻域像素值更大的点。
  3. 创建标记图

    • 创建一个与原始图像大小相同的标记图,将局部极大值点的位置赋值为不同的标签(从1开始编号),其余区域标记为0。
  4. 应用分水岭算法

    • 将距离图的负值作为输入图像,标记图作为初始标记,应用分水岭算法。分水岭算法通过模拟水从局部极大值点流向低谷的过程,不断合并像素,形成分割区域。
    • 在这个过程中,水从局部极大值点流向低谷,如果两个不同的标签的水流在某处相遇,该处将被标记为边界。
  5. 生成分割结果

    • 分水岭算法最终会将图像分割成多个区域,每个区域对应一个标签。边界区域通常被标记为0。

分水岭算法的优点和缺点:

优点

  • 分水岭算法可以生成闭合的区域边界,适用于目标物体具有明确边界的图像。
  • 算法可以自动确定分割区域的数量,无需事先设定。

缺点

  • 对噪声和边缘模糊敏感,容易产生过分割,即将一个目标物体分割成多个区域。
  • 需要进行预处理以减少噪声和增强边缘(如均值漂移滤波)。

示例代码解释:

# 计算每个二值像素到最近零像素的精确欧几里得距离, 然后找到此距离图中的局部峰值
D = ndimage.distance_transform_edt(thresh)
localMax = peak_local_max(D, footprint=np.ones((3, 3)), min_distance=40, labels=thresh)# 根据找到的局部峰值创建标记数组, 标记数组的值对应于每个硬币的序号
markers = np.zeros_like(thresh, dtype=np.int32)
markers[tuple(localMax.T)] = np.arange(1, len(localMax) + 1)# 应用分水岭算法, 将图像分割为不同的区域
labels = watershed(-D, markers, mask=thresh)
  1. 计算距离变换ndimage.distance_transform_edt(thresh) 计算每个前景像素到最近背景像素的欧几里得距离,生成距离图 D
  2. 寻找局部极大值peak_local_max(D, footprint=np.ones((3, 3)), min_distance=40, labels=thresh) 在距离图中寻找局部极大值,这些点将作为初始标记。
  3. 创建标记图markers 初始化为全零矩阵,将局部极大值点的位置赋值为不同的标签。
  4. 应用分水岭算法labels = watershed(-D, markers, mask=thresh) 使用分水岭算法对距离图的负值进行分割,生成标签图 labels

通过以上步骤,分水岭算法将输入图像分割成若干独立区域,每个区域代表一个目标物体。

以检测这张图为例子:
在这里插入图片描述

使用分水岭算法流程如下:

  1. 读取图像并应用均值漂移滤波

    • 使用 cv2.imread 读取输入图像。
    • 使用 cv2.pyrMeanShiftFiltering 对图像进行均值漂移滤波,平滑图像并减少噪点。
  2. 转换为灰度图并二值化

    • 使用 cv2.cvtColor 将平滑后的图像转换为灰度图。
    • 使用 cv2.threshold 结合 Otsu 算法进行自动阈值二值化,将图像转换为二值图像。
  3. 计算欧几里得距离并找到局部峰值

    • 使用 ndimage.distance_transform_edt 计算每个二值像素到最近零像素的欧几里得距离,生成距离变换图。
    • 使用 peak_local_max 找到距离图中的局部峰值,这些峰值将作为分水岭算法的初始标记。
  4. 创建标记数组并应用分水岭算法

    • 创建一个与二值图像大小相同的标记数组 markers,将局部峰值的位置赋值为不同的标签。
    • 使用 watershed 函数进行分水岭算法,将图像分割成不同区域,每个区域对应一个硬币。
  5. 遍历分割出的不同区域,绘制轮廓和标签

    • 遍历分割后的标签,跳过背景标签(标签为0)。
    • 为每个硬币创建一个掩码图像,设置对应标签区域为白色,其余区域为黑色。
    • 使用 cv2.findContours 查找掩码图像中的轮廓,并找到最大的轮廓(即硬币区域)。
    • 使用 cv2.minEnclosingCircle 计算最小外接圆的圆心坐标和半径。
    • 在原始图像上绘制圆形轮廓和标签。
  6. 显示最终结果图像

    • 使用 cv2.imshow 显示处理后的图像。
    • 使用 cv2.waitKeycv2.destroyAllWindows 控制显示窗口。

上述流程通过图像平滑、二值化、距离变换、局部峰值检测和分水岭算法,实现了对硬币图像的分割,并在分割后的图像上绘制了硬币的轮廓和编号标签。
完整代码如下:

import numpy as np
import cv2
from skimage.feature import peak_local_max
from skimage.segmentation import watershed
from scipy import ndimage
import imutils# 读取图像并应用均值漂移滤波来平滑图像,减少噪点
image = cv2.imread('/coins/1.jpg')
shifted = cv2.pyrMeanShiftFiltering(image, 21, 51)# 将图像转换为灰度图,然后使用Otsu算法自动确定阈值进行二值化
gray = cv2.cvtColor(shifted, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]# 计算每个二值像素到最近零像素的精确欧几里得距离,然后找到此距离图中的局部峰值
# 这些峰值将作为分水岭算法的初始标记
D = ndimage.distance_transform_edt(thresh)
localMax = peak_local_max(D, footprint=np.ones((3, 3)), min_distance=40, labels=thresh)# 根据找到的局部峰值创建标记数组,标记数组的值对应于每个硬币的序号
markers = np.zeros_like(thresh, dtype=np.int32)
markers[tuple(localMax.T)] = np.arange(1, len(localMax) + 1)# 应用分水岭算法,将图像分割为不同的区域
labels = watershed(-D, markers, mask=thresh)# 遍历分割出的不同区域,绘制出每个硬币的轮廓和标签
for label in np.unique(labels):if label == 0:continue# 创建一个掩码图像,将当前标签对应的区域设置为白色,其他区域设置为黑色mask = np.zeros(gray.shape, dtype="uint8")mask[labels == label] = 255# 查找掩码图像中的轮廓,并找到最大的轮廓(即硬币区域)cnts = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)cnts = imutils.grab_contours(cnts)c = max(cnts, key=cv2.contourArea)# 计算最小外接圆的圆心坐标和半径((x, y), r) = cv2.minEnclosingCircle(c)# 在原始图像上绘制圆形轮廓和标签cv2.circle(image, (int(x), int(y)), int(r), (0, 255, 0), 2)cv2.putText(image, "{}".format(label), (int(x) - 10, int(y)),cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 0, 255), 2)# 显示最终的结果图像
cv2.imshow("Output", image)
cv2.waitKey(0)
cv2.destroyAllWindows()

分割结果如下:
在这里插入图片描述

二、 霍夫变换

霍夫变换(Hough Transform)是图像处理中的一种重要技术,用于检测图像中的几何形状。霍夫圆检测(Hough Circle Transform)是霍夫变换的一个具体应用,用于检测图像中的圆形物体。

霍夫圆检测的原理和步骤:

  1. 边缘检测

    • 首先对图像进行边缘检测,常用的方法是Canny边缘检测。边缘检测可以提取出图像中的显著边缘,减少数据量并突出目标物体的轮廓。
  2. 参数空间定义

    • 在检测圆的过程中,需要定义圆的参数空间。一个圆由三个参数定义:圆心坐标 (x, y) 和半径 r。霍夫圆检测将在参数空间中搜索圆的可能位置和大小。
  3. 投票累加

    • 在边缘检测后的二值图像中,每个边缘点 (x, y) 都会在参数空间中投票支持可能的圆心和半径组合。具体而言,对于每个边缘点 (x, y) 和每个可能的半径 r,可以根据圆的方程计算圆心坐标 (a, b):
      [
a = x - r \cdot \cos(\theta)
]
[
b = y - r \cdot \sin(\theta)
]

    • 在参数空间中累加 (a, b) 的投票次数。

  4. 检测局部最大值

    • 在参数空间中,投票次数最多的位置即为最可能的圆心和半径组合。通过检测参数空间中的局部最大值,确定圆的存在和位置。
  5. 绘制检测到的圆

    • 根据检测到的圆心坐标和半径,在原始图像上绘制圆形轮廓。

示例代码:

以下是一个使用OpenCV进行霍夫圆检测的示例代码:

import cv2
import numpy as np# 读取图像
image = cv2.imread('image.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)# 应用高斯模糊,减少噪声
blurred = cv2.GaussianBlur(gray, (9, 9), 2)# 使用霍夫圆检测
circles = cv2.HoughCircles(blurred, cv2.HOUGH_GRADIENT, dp=1.2, minDist=20,param1=50, param2=30, minRadius=15, maxRadius=30)# 如果检测到圆
if circles is not None:circles = np.round(circles[0, :]).astype("int")for (x, y, r) in circles:# 绘制圆的轮廓cv2.circle(image, (x, y), r, (0, 255, 0), 4)# 绘制圆心cv2.rectangle(image, (x - 5, y - 5), (x + 5, y + 5), (0, 128, 255), -1)# 显示结果图像
cv2.imshow("output", image)
cv2.waitKey(0)
cv2.destroyAllWindows()

代码详解:

  1. 读取图像并转换为灰度图

    image = cv2.imread('image.jpg')
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    
  2. 应用高斯模糊

    • 使用高斯模糊(Gaussian Blur)来平滑图像,减少噪声。
    blurred = cv2.GaussianBlur(gray, (9, 9), 2)
    
  3. 使用霍夫圆检测

    • 调用 cv2.HoughCircles 函数进行霍夫圆检测。参数解释如下:
      • blurred:输入的灰度图像。
      • cv2.HOUGH_GRADIENT:检测方法,使用梯度信息。
      • dp=1.2:累加器分辨率与图像分辨率的反比关系。
      • minDist=20:检测到的圆之间的最小距离。
      • param1=50:Canny边缘检测的高阈值。
      • param2=30:累加器阈值,用于检测圆的阈值,越小越容易检测到不明显的圆。
      • minRadius=15maxRadius=30:检测圆的半径范围。
    circles = cv2.HoughCircles(blurred, cv2.HOUGH_GRADIENT, dp=1.2, minDist=20,param1=50, param2=30, minRadius=15, maxRadius=30)
    
  4. 绘制检测到的圆

    • 如果检测到圆,将其绘制在原始图像上。
    if circles is not None:circles = np.round(circles[0, :]).astype("int")for (x, y, r) in circles:cv2.circle(image, (x, y), r, (0, 255, 0), 4)cv2.rectangle(image, (x - 5, y - 5), (x + 5, y + 5), (0, 128, 255), -1)
    
  5. 显示结果图像

    • 显示绘制了圆的结果图像。
    cv2.imshow("output", image)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

通过上述步骤和代码,霍夫圆检测可以在图像中自动识别和绘制圆形目标。
识别图中硬币的完整代码如下:

import cv2
import numpy as np# 读取图像并转换为灰度图像
image = cv2.imread('/coins/1.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)# 应用高斯模糊
gray = cv2.GaussianBlur(gray, (15, 15), 0)# 使用霍夫圆变换检测圆
circles = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT, dp=1.2, minDist=50, param1=50, param2=30, minRadius=20,maxRadius=60)# 确保至少检测到一个圆
if circles is not None:circles = np.round(circles[0, :]).astype("int")for (i, (x, y, r)) in enumerate(circles):# 绘制圆圈和中心点cv2.circle(image, (x, y), r, (0, 255, 0), 2)cv2.putText(image, str(i + 1), (x - 10, y), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 0, 255), 2)# 显示最终结果图像
cv2.imshow("Detected Coins", image)
cv2.waitKey(0)
cv2.destroyAllWindows()

检测结果如下:
在这里插入图片描述

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

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

相关文章

经纬恒润助力红旗转向技术新突破

近日,红旗研发新视界发布《国内首发!红旗大输出力冗余平行轴式电动助力转向器让用户出行经济又安全!》 ,创新突破“输出力20kN以上的冗余平行轴式电动助力转向器(R-EPS)”。该产品支持整车实现L2/L3级自动驾…

路由器重启真的好吗?多久重启一次更好?

前言 小白前段时间发现自己家的OpenWRT软路由上网特别慢,有时候通话还有点卡顿。 然而有个朋友用的普通路由器也有类似的问题,而且有时候根本上不去网。 解决的办法很简单:重启路由器。 重启路由器? 但路由器重启是真的好吗&a…

L45---506.相对名次(java)--排序

1.题目描述 2.知识点 (1)String.join(" ", words) 是 Java 中的一个语法,用于将数组或集合中的元素连接成一个单独的字符串,连接时使用指定的分隔符。这里的 " " 是作为分隔符使用的一个空格字符串。 Strin…

Windows mstsc

windows mstsc 局域网远程计算机192.168.0.113为例,远程控制命令mstsc

Message forwarding mechanism (消息转发机制)

iOS的消息转发机制 iOS的消息转发机制是在消息发送给对象时,找不到对应的实例方法的情况下启动的。消息转发允许对象在运行时处理无法识别的消息,提供了一种动态的、灵活的消息处理方式。 消息转发机制主要分为三个阶段: 动态方法解析快速…

香港高才通计划续签,很可能大部分人都要烂尾

自2022年12月28日推出以来,截至2024年2月29日,高才通计划申请人数超过了7万宗,获批人数将近6万。 这张表格是从2022年到2023年每个月申请人数情况,高峰时间段达到了一个月7166人申请: 香港高才通计划申请人数72508人&…

PostgreSQL基础(九):PostgreSQL的事务介绍

文章目录 PostgreSQL的事务介绍 一、什么是ACID(常识) 二、事务的基本使用 三、保存点(了解) PostgreSQL的事务介绍 一、什么是ACID(常识) 在日常操作中,对于一组相关操作,通常…

python数据分析-问卷数据分析(地理课)

学生问卷 分析学生背景:班级分布、每周地理课数量、地理成绩分布 根据问卷,可以知道: 班级分布: 七年级有118名学生。 八年级有107名学生。 每周地理课的数量: 有28名学生每周有1节地理课。 有99名学生每周有2…

重新学习STM32(2)NVIC

概念简介 NVIC,即嵌套向量中断控制器,控制着中断相关的功能,是内核里面的一个外设。 中断在单片机编程中的作用是使单片机能及时响应需要立即处理的事件,但是这些事件也分紧急和非紧急,因此需要优先级来区分。…

Spring AI 第二讲 之 Chat Model API 第八节Anthropic 3 Chat

Anthropic Claude 是一系列基础人工智能模型,可用于各种应用。对于开发人员和企业来说,您可以利用 API 访问,直接在 Anthropic 的人工智能基础架构之上进行构建。 Spring AI 支持用于同步和流式文本生成的 Anthropic 消息 API。 Anthropic …

二轴机器人大米装箱机:技术创新引领智能包装新潮流

在科技日新月异的今天,自动化和智能化已成为各行各业追求高效、精准生产的关键。作为粮食加工行业的重要一环,大米装箱机的技术创新与应用价值日益凸显。其中,二轴机器人大米装箱机以其高效、稳定、智能的特点,成为市场的新宠。星…

使用 IPSET 添加 CDN 节点 IP(IPv4/IPv6)到防火墙白名单

明月的服务器一直使用的是 iptables,随着近几年 IPv6 的普及,明月切身体会到还是 IPSET 最方便了,无论你是 IPv4 还是 IPv6 都可以方便的管理,无论你是加入白名单还是黑名单,都非常的简单高效!今天就参照明月自己的实操…

Python 机器学习 基础 之 【实战案例】新闻内容分类实战

Python 机器学习 基础 之 【实战案例】新闻内容分类实战 目录 Python 机器学习 基础 之 【实战案例】新闻内容分类实战 一、简单介绍 二、新闻内容分类实战 三、数据准备 四、分词与清洗工作 1、读取数据 2、使用 jieba 分词器进行分词,使用 Pandas 创建Data…

R语言探索与分析19-CPI的分析和研究

一、选题背景 CPI(居民消费价格指数)作为一个重要的宏观经济指标,扮演着评估通货膨胀和居民生活水平的关键角色。在湖北省这个经济活跃的地区,CPI的波动对于居民生活、企业经营以及政府宏观经济政策制定都具有重要的影响。因此&a…

Java——面向对象进阶(一)

前言 面向对象进阶(一):static,继承,this和super关键字 文章目录 一、static1.1 静态变量1.2 静态方法1.3 静态变量和静态方法在内存中 二、继承2.1 概念2.2 继承的特点和能继承什么2.3 继承中的重写2.4 this和super关键字 一、static 在 Jav…

Java学习笔记(六):Array List、学生管理系统、学生管理系统升级版

目录 一、ArrayList 1.1集合和数组的优势对比: 1.2 ArrayList类概述 1.3 ArrayList类常用方法 1.3.1 构造方法 1.3.2 成员方法 1.4 ArrayList存储字符串并遍历 1.5 ArrayList存储学生对象并遍历 1.6 查找用户的索引 1.7 添加手机对象并返回要求的数据 二…

谈AI 时代网站的未来趋势

以大语言模型为代表的AI 技术迅速发展,将会影响原有信息网络的方式。其中一个明显的趋势是通过chatGPT 对话代替搜索引擎和浏览器来获取信息。 互联网时代,主要是通过网站(website)提供信息。网站主要为人类阅读的方式构建的。主要…

数据结构笔记1 绪论,线性表

学习视频: 第01周c--1.2基本概念和术语1_哔哩哔哩_bilibili 01《数据结构》绪论_哔哩哔哩_bilibili 数据: 1.数值型的数据:整数,实数 2.非数值型的数据:文字、图像.. 数据元素:(元素&#xf…

人类语言处理nlp部分笔记——四、GPT3

参考自李宏毅课程-人类语言处理 四、GPT3 1. 介绍 GPT-3是一个language model,它的参数量相当巨大,是ELMO的2000倍。 2. GPT-3的野心 虽然GPT-3和BERT等模型一样,但是GPT-3是不需要针对特定的task做finetune的,也就是说GPT-3…

React 18

创建 React 18 脚手架项目 全局安装 create-react-app npm install -g create-react-app yarn global add create-react-app . 确认是否已安装 create-react-app npm list -g create-react-app yarn global list | grep create-react-app . 如果安装失败 有时&#xff0…