iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Python+OpenCV实现分水岭分割算法的示例代码
  • 388
分享到

Python+OpenCV实现分水岭分割算法的示例代码

2024-04-02 19:04:59 388人浏览 独家记忆

Python 官方文档:入门教程 => 点击学习

摘要

目录前言1.使用分水岭算法进行分割2.Watershed与random walker分割对比前言 分水岭算法是用于分割的经典算法,在提取图像中粘连或重叠的对象时特别有用,例如下图中的

前言

分水岭算法是用于分割的经典算法,在提取图像中粘连或重叠的对象时特别有用,例如下图中的硬币。

使用传统的图像处理方法,如阈值和轮廓检测,我们将无法从图像中提取每一个硬币,但通过利用分水岭算法,我们能够检测和提取每一个硬币。

在使用分水岭算法时,我们必须从用户定义的标记开始。这些标记可以通过点击手动定义,或者我们可以使用阈值和/或形态学操作等方法自动或启发式定义它们。

基于这些标记,分水岭算法将输入图像中的像素视为地形——该方法通过“淹没”山谷,从标记开始向外移动,直到不同标记相遇。为了获得准确的分水岭分割,必须正确放置标记。

在这篇文章的剩下部分,我将向您展示如何使用分水岭算法来分割和提取图像中既粘连又重叠的对象。

为此,我们将使用各种 python 包,包括 SciPy、scikit-image 和 OpenCV

在上图中,您可以看到使用简单阈值和轮廓检测无法提取对象,由于这些对象是粘连的、重叠的或两者兼有,

因此简单的轮廓提取会将粘连的对象视为单个对象,而不是多个对象。

1.使用分水岭算法进行分割

# 打开一个新文件,将其命名为 watershed.py ,然后插入以下代码:

# 打开一个新文件,将其命名为 watershed.py ,然后插入以下代码:

# 导入必要的包
from skimage.feature import peak_local_max
from skimage.morphology import watershed
from scipy import ndimage
import numpy as np
import argparse
import imutils
import cv2

# 构造参数解析并解析参数
ap = argparse.ArgumentParser()
# ap.add_argument("-i", "--image", default="HFOUG.jpg", help="path to input image")
ap.add_argument("-i", "--image", default="watershed_coins_01.jpg", help="path to input image")
args = vars(ap.parse_args())
# 加载图像并执行金字塔均值偏移滤波以辅助阈值化步骤
image = cv2.imread(args["image"])
shifted = cv2.pyrMeanShiftFiltering(image, 21, 51)
cv2.imshow("Input", image)
# 将图像转换为灰度,然后应用大津阈值
gray = cv2.cvtColor(shifted, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
cv2.imshow("Thresh", thresh)

# 计算从每个二进制图像中的像素到最近的零像素的精确欧氏距离,然后找出这个距离图中的峰值
D = ndimage.distance_transfORM_edt(thresh)

# 可视化距离函数
D_show = cv2.normalize(D, None, 0, 1, cv2.NORM_MINMAX)
# print(np.max(D_show))
cv2.imshow("D_show", D_show)


# 以坐标列表(indices=True)或布尔掩码(indices=False)的形式查找图像中的峰值。峰值是2 * min_distance + 1区域内的局部最大值。
# (即峰值之间至少相隔min_distance)。此处我们将确保峰值之间至少有20像素的距离。
localMax = peak_local_max(D, indices=False, min_distance=20, labels=thresh)
# 可视化localMax
temp = localMax.astype(np.uint8)
cv2.imshow("localMax", temp * 255)
# 使用8-连通性对局部峰值进行连接成分分析,然后应用分水岭算法
# scipy.ndimage.label(input, structure=None, output=None)
# input :待标记的数组对象。输入中的任何非零值都被视为待标记对象,零值被视为背景。
# structure:定义要素连接的结构化元素。对于二维数组。默认是四连通, 此处选择8连通
#
markers = ndimage.label(localMax, structure=np.ones((3, 3)))[0]  # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

# 可视化markers
temp_markers = markers.astype(np.uint8)
cv2.imshow("temp_markers", temp_markers * 20)

# 由于分水岭算法假设我们的标记代表距离图中的局部最小值(即山谷),因此我们取 D 的负值。
labels = watershed(-D, markers, mask=thresh)
print("[INFO] {} unique segments found".format(len(np.unique(labels)) - 1))

# 循环遍历分水岭算法返回的标签
for label in np.unique(labels):
    # 0表示背景,忽略它
    if label == 0:
        continue
    # 否则,为标签区域分配内存并将其绘制在掩码上
    mask = np.zeros(gray.shape, dtype="uint8")
    mask[labels == label] = 255
    # 在mask中检测轮廓并抓取最大的一个
    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)

2.Watershed与random walker分割对比

示例比较了两种分割方法,以分离两个相连的磁盘:分水岭算法和随机游走算法。 两种分割方法都需要种子,即明确属于某个区域的像素。在这里,到背景的距离图的局部最大值被用作种子。

import numpy as np
from skimage.segmentation import watershed
from skimage.feature import peak_local_max
from skimage import measure
from skimage.segmentation import random_walker
import matplotlib.pyplot as plt
from scipy import ndimage
# import cv2

# Generate an initial image with two overlapping circles
x, y = np.indices((80, 80))
x1, y1, x2, y2 = 28, 28, 44, 52
r1, r2 = 16, 20
mask_circle1 = (x - x1) ** 2 + (y - y1) ** 2 < r1 ** 2
mask_circle2 = (x - x2) ** 2 + (y - y2) ** 2 < r2 ** 2
image = np.logical_or(mask_circle1, mask_circle2)
# Now we want to separate the two objects in image
# Generate the markers as local maxima of the distance
# to the background
distance = ndimage.distance_transform_edt(image)

D_show = distance/np.max(distance)

# D_show = cv2.normalize(distance, None, 0, 1, cv2.NORM_MINMAX)

local_maxi = peak_local_max(
    distance, indices=False, footprint=np.ones((3, 3)), labels=image)
markers = measure.label(local_maxi)
labels_ws = watershed(-distance, markers, mask=image)

markers[~image] = -1
labels_rw = random_walker(image, markers)

plt.figure(figsize=(12, 3.5))
plt.subplot(141)
plt.imshow(image, cmap='gray', interpolation='nearest')
plt.axis('off')
plt.title('image')
plt.subplot(142)
plt.imshow(D_show, cmap='Spectral',interpolation='nearest')
plt.axis('off')
plt.title('distance map')
plt.subplot(143)
plt.imshow(labels_ws, cmap='Spectral', interpolation='nearest')
plt.axis('off')
plt.title('watershed segmentation')
plt.subplot(144)
plt.imshow(labels_rw, cmap='Spectral', interpolation='nearest')
plt.axis('off')
plt.title('random walker segmentation')

plt.tight_layout()
plt.show()

到此这篇关于Python+OpenCV实现分水岭分割算法的示例代码的文章就介绍到这了,更多相关Python OpenCV分水岭分割算法内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Python+OpenCV实现分水岭分割算法的示例代码

本文链接: https://www.lsjlt.com/news/119780.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Python+OpenCV实现分水岭分割算法的示例代码
    目录前言1.使用分水岭算法进行分割2.Watershed与random walker分割对比前言 分水岭算法是用于分割的经典算法,在提取图像中粘连或重叠的对象时特别有用,例如下图中的...
    99+
    2024-04-02
  • C++中实现OpenCV图像分割与分水岭算法
    分水岭算法是一种图像区域分割法,在分割的过程中,它会把跟临近像素间的相似性作为重要的参考依据,从而将在空间位置上相近并且灰度值相近的像素点互相连接起来构成一个封闭的轮廓,封闭性是分水...
    99+
    2024-04-02
  • OpenCV-Python使用分水岭算法实现图像的分割与提取
    目录图像分割分水岭算法waterShed函数形态学分割distanceTransform函数确定未知区域ConnectedComponents函数实战分水岭算法随着当今世界的发展,计...
    99+
    2024-04-02
  • C++中怎么实现OpenCV图像分割与分水岭算法
    小编给大家分享一下C++中怎么实现OpenCV图像分割与分水岭算法,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!分水岭算法是一种图像区域分割法,在分割的过程中,它...
    99+
    2023-06-15
  • OpenCV基于分水岭算法的图像分割怎么实现
    本文小编为大家详细介绍“OpenCV基于分水岭算法的图像分割怎么实现”,内容详细,步骤清晰,细节处理妥当,希望这篇“OpenCV基于分水岭算法的图像分割怎么实现”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。1. ...
    99+
    2023-07-05
  • Python实现基于标记的分水岭分割算法
    目录1. 原理2.代码实现2.1 利用OpenCV和c++实现分水岭算法2.2 Python实现分水岭分割(1)2.3 Python实现分水岭分割(2)分水岭技术是一种众所周知的分割...
    99+
    2024-04-02
  • OpenCV实战记录之基于分水岭算法的图像分割
    目录0. 前言1. 分水岭算法2. 分水岭算法直观理解3. 完整代码总结0. 前言 分水岭变换是一种流行的图像处理算法,用于快速将图像分割成同质区域。分水岭变换主要基于以下思想:当图...
    99+
    2023-02-22
    opencv 分水岭算法 opencv图像分割算法 opencv 分水岭算法应用
  • OpenCV-Python怎么使用分水岭算法实现图像分割与提取功能
    小编给大家分享一下OpenCV-Python怎么使用分水岭算法实现图像分割与提取功能,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!随着当今世界的发展,计算机视觉技...
    99+
    2023-06-15
  • OpenCV基于距离变换和分水岭实现图像分割
    目录一.图像分割二.基于距离变换和分水岭的图像分割代码实现图像处理效果一.图像分割 图像分割是根据灰度、颜色、纹理和形状等特征,把图像分成若干个特定的、具有独特性质的区域,这些特征在...
    99+
    2024-04-02
  • Python基于均值漂移算法和分水岭算法实现图像分割
    目录一.基于均值漂移算法的图像分割二.基于分水岭算法的图像分割三.总结一.基于均值漂移算法的图像分割 均值漂移(Mean Shfit)算法是一种通用的聚类算法,最早是1975年Fuk...
    99+
    2023-01-11
    Python均值漂移算法 图像分割 Python 分水岭算法 图像分割 Python图像分割
  • OpenCV图像分割之分水岭算法与图像金字塔算法详解
    目录前言一、使用分水岭算法分割图像1、cv2.distanceTransform()函数2、cv2.connectedComponents()函数3、cv2.watershed()函...
    99+
    2024-04-02
  • OpenCV 图像分割实现Kmean聚类的示例代码
    目录1 Kmean图像分割2 流程3 实现1 Kmean图像分割 按照Kmean原理,对图像像素进行聚类。优点:此方法原理简单,效果显著。缺点:实践发现对于前景和背景颜色相近或者颜色...
    99+
    2024-04-02
  • Java实现黄金分割法的示例代码
    目录1、概述2、黄金分割法3、修改后的黄金分割算法4、编程实现修改后的黄金分割算法1、概述 黄金分割法是一种区间收缩方法。 所谓区间收缩方法,指的是将含有最优解的区间逐步缩小,直至区...
    99+
    2024-04-02
  • OpenCV(python)版实现文本分割之水平投影法
    对于如下一张图片,如何将文本区域分割成一行一行的了? 在文本分割领域中有一种很优秀的算法:投影法,包括水平投影法和垂直投影法。本文主要讲述水平投影法,水平投影法可以理解为一束光线从...
    99+
    2024-04-02
  • Python OpenCV基于HSV的颜色分割实现示例
    目录前言1、什么是HSV2、代码实战2.1 createTrackbar使用方法及步骤2.2 代码详解3、总结前言 一周没有更新博客了,这一周的时间内加强了对机器学习和图像处理的学习...
    99+
    2024-04-02
  • golang实现数组分割的示例代码
    需求:给定一个数组和一个正整数,要求把数组分割成多个正整数大小的数组,如果不够分,则最后一个数组分到剩余的所有元素。 示例1: 数组:[1, 2, 3, 4, 5, 6, 7,...
    99+
    2024-04-02
  • Mysql实现水平分库的示例代码
    目录前言:讲解:第一种方式的水平分库:mysql水平分库数据查询合并MySQL水平分库插入数据前言: 平时开发中,可能会遇见数据量越来越大的情况,一般数据量过千万级别,就必须考虑分库分表的情况了,来减少io 服务器压力,...
    99+
    2023-06-08
    Mysql 水平分库
  • python实现决策树分类算法代码示例
    目录前置信息1、决策树2、样本数据策树分类算法1、构建数据集2、数据集信息熵3、信息增益4、构造决策树5、实例化构造决策树6、测试样本分类后置信息:绘制决策树代码总结前置信息 1、决...
    99+
    2024-04-02
  • 使用sharding-jdbc实现水平分库+水平分表的示例代码
    前面的文章使用sharding-jdbc实现水平分表中详细记录了如何使用sharding-jdbc实现水平分表,即根据相应的策略,将一部分数据存入到表1中,一部分数据存入到表2中,...
    99+
    2024-04-02
  • golang实现数组分割的示例代码怎么写
    这篇文章将为大家详细讲解有关golang实现数组分割的示例代码怎么写,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。需求:给定一个数组和一个正整数,要求把数组分割成多个正整数大小的数组,如果不...
    99+
    2023-06-22
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作