【计算机视觉】分水岭搭建医学诊断

news/2025/10/30 18:10:14/文章来源:https://www.cnblogs.com/gccbuaa/p/19177853

目录

一、引言

二、分水岭算法

(一)模拟浸水过程

(二)模拟降水过程

(三)过度分割问题

(四)标记分水岭算法

三、分水岭医学诊断案例分析

1.距离变换的分水岭分割

2.梯度的分水岭分割

3.分水岭实现医学诊断

四、本文用到的图片

五、总结


一、引言

近年来,肺癌的发病率和病死率均迅速上升,目前已居所有癌症之首。随着肺癌病人数量的增加,医生对肺癌 CT 图像进行研判的工作量也增加了不少,在这种情况下,难免工作效率降低甚至会出现误诊。为了帮助医生减少重复性工作,对肺部 CT 图像进行计算机辅助检测的技术就被广泛应用于对肺癌的诊断和治疗过程中。

医学 CT 图像处理主要是研究医学图像中的器官和组织之间的关系,并进行病理性分析。因此,借助计算机及图像处理技术对 CT 图像中医生所关注的区域进行精确的分割和定位是医学图像处理的关键步骤,在临床诊断中对于协助医生进行病理研判具有重要意义。

分水岭分割是一种强有力的图像分割方法,可以有效地提取图像中我们所关注的区域。在灰度图像中使用分水岭方法可以将图像分割成不同的区域,每个区域都可能对应一个我们所关注的对象,对于这些图像的子区域可以进行进一步的处理。除此之外,使用分水岭算法还可以提取目标的轮廓等特征。

二、分水岭算法

分水岭算法是一种图像区域分割法,在分割的过程中,它会把跟近邻像素间的相似性作为重要的参考依据,从而将在空间位置上相近并且灰度值相近的像素点互相连接起来构成一个封闭的轮廓,封闭性是分水岭算法的一个重要特征。

其他图像分割方法,如阈值、边缘检测等都不会考虑像素在空间关系上的相似性和封闭性这一概念,彼此像素间互相独立,没有统一性。分水岭算法较其他分割方法更具有思想性,更符合人眼对图像的印象。

任意的灰度图像都可以被看作为地质学表面,高亮度的地方是山峰,低亮度的地方是山谷。如图所示。

(一)模拟浸水过程

给每个孤立的山谷(局部最小值)标注不同颜色的水(标签),当水涨起来,根据周围的山峰(梯度),不同的山谷也就是不同的颜色会开始合并,要避免这个问题,我们可以在水要漫过(合并)的地方建立障碍,直到所有山峰都被淹没,这就是模拟浸水过程。我们所创建的障碍就是分割结果,这就是分水岭的原理,但是这个方法会分割过度,因为有噪点或者其他图像上的错误。

(二)模拟降水过程

如果将图像视作地形图并建立地理模型,则当上空落下一滴雨珠时,雨珠降落到山体表面并顺山坡向下流,直到汇聚到相同的局部最低点。在地形图上,雨珠在山坡上经过的路线就是一个连通分支,通往局部最低点的所有连通分支就形成了一个聚水盆地,山坡就被称为分水岭,这就是模拟降水的过程。

(三)过度分割问题

分水岭变换的目标是求出梯度图像的 “分水岭线”,传统的差分梯度算法对近邻像素做差分运算,容易受到噪声和量化误差等因素的影响,往往会在灰度的均匀区域内部产生过多的局部梯度 “谷底”,这些在分水岭变换中对应 “集水盆地”。因此,传统的差分梯度算法最终将导致出现过分割(Over Segmentation)现象,即一个灰度均匀的区域可能被过度分成多个子区域,以致产生大量的虚假边缘,从而无法确认哪些是真正边缘,对算法的准确性造成了一定的不利影响,这就是过度分割。

(四)标记分水岭算法

直接应用分水岭算法的主要缺点是会产生过分割现象,即分割出大量的细小区域,而这些区域对于图像分析可以说是毫无意义的。图像噪声等因素往往会导致在图像中出现很多杂乱的低洼区域,而通过平滑滤波能减少局部最小点的数量,所以在分割前先对图像进行平滑是避免过分割的有效方法之一。此外,对分割后的图像按照某种准则进行相邻区域的合并也是一种过分割解决方法。

基于标记(Marker)的分水岭算法能够有效防止过分割现象的发生,该算法的标记包括内部标记(Internal Marker)和外部标记(External Marker)。其基本思想是通过引入标记来修正梯度图像,使得局部最小值仅出现在标记的位置,并设置阈值 h 来对像素值进行过滤,删除最小值深度小于阈值 h 的局部区域。

标记分水岭算法中的一个标记对应图像的一个连通成分,其内部标记与我们感兴趣的某个目标相关,外部标记与背景相关。对标记的选取一般包括预处理和定义选取准则两部分,其中选取准则可以是灰度值、连通性、大小、形状、纹理等特征。在选取内部标记之后,就能以其为基础对低洼进行分割,将分割区域对应的分水线作为外部标记,之后对每个分割出来的区域都利用其他分割技术(如二值化分割)将目标从背景中分离出来。

首先,假设将内部标记的选取准则定义为满足以下条件。

(1)区域周围由更高的 “海拔” 点组成。

(2)区域内的点可以组成一个连通分量。

(3)区域内连通分量的点具有相同或相近的灰度值。

然后,对平滑滤波后的图像应用分水岭算法,并将满足条件的内部标记为所允许的局部最小值,再将分水岭变换得到的分水线结果作为外部标记。

最后,内部标记对应每个感兴趣目标的内部,外部标记对应背景。根据这些标记结果将其分割成互不重叠的区域,每个区域都包含唯一的目标和背景。

因此,标记分水岭算法的显著特点和关键步骤就是获取标记的过程。

三、分水岭医学诊断案例分析

1.距离变换的分水岭分割

分水岭算法可以和距离变换结合,寻找 “汇水盆地” 和 “分水岭界限”,从而对图像进行分割。二值图像的距离变换就是每一个像素点到最近非零值像素点的距离,我们可以使用 scipy 包来计算距离变换。

基于距离变换的分水岭图像分割的Python代码:

import numpy as np
import matplotlib.pyplot as plt
from scipy import ndimage as ndi
from skimage import morphology, feature, segmentation
plt.rcParams['font.sans-serif'] = ['SimHei']  # 显示中文标签
# 创建两个带有重叠圆的图像
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)
# 现在用分水岭算法分离两个圆
distance = ndi.distance_transform_edt(image)  # 距离变换
# 获取峰值坐标
local_maxi_coords = feature.peak_local_max(distance,footprint=np.ones((3, 3)),labels=image
)
# 转换为布尔掩码
local_maxi = np.zeros_like(distance, dtype=bool)
local_maxi[tuple(local_maxi_coords.T)] = True
markers = ndi.label(local_maxi)[0]  # 初始标记点
# 从segmentation模块调用watershed
labels = segmentation.watershed(-distance, markers, mask=image)
# 可视化结果
fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(8, 8))
axes = axes.ravel()
ax0, ax1, ax2, ax3 = axes
ax0.imshow(image, cmap=plt.cm.gray, interpolation='nearest')
ax0.set_title("原始图像")
ax1.imshow(-distance, cmap=plt.cm.jet, interpolation='nearest')
ax1.set_title("距离变换")
ax2.imshow(markers, cmap=plt.cm.Spectral, interpolation='nearest')
ax2.set_title("标记")
ax3.imshow(labels, cmap=plt.cm.Spectral, interpolation='nearest')
ax3.set_title("分割")
for ax in axes:ax.axis('off')
fig.tight_layout()
plt.show()

2.梯度的分水岭分割

分水岭算法也可以和梯度相结合来实现图像分割。一般梯度图像在边缘处有较高的像素值,而在其他地方则有较低的像素值,理想情况下,分水岭恰好在边缘。因此,可以根据梯度来寻找分水岭。

基于梯度的分水岭图像分割的Python代码:

import matplotlib.pyplot as plt
from scipy import ndimage as ndi
from skimage import morphology, color, data, filters
from skimage import segmentation
# 直接使用灰度图像(data.camera()返回的就是灰度图)
image = data.camera()  # 形状为(512, 512)的灰度图
plt.rcParams['font.sans-serif'] = ['SimHei']  # 显示中文标签
# 过滤噪声
denoised = filters.rank.median(image, morphology.disk(2))
# 将梯度值低于10的作为开始标记点
markers = filters.rank.gradient(denoised, morphology.disk(5)) < 10
markers = ndi.label(markers)[0]
# 计算梯度
gradient = filters.rank.gradient(denoised, morphology.disk(2))
# 基于梯度的分水岭算法
labels = segmentation.watershed(gradient, markers, mask=image)
# 可视化结果
fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(6, 6))
axes = axes.ravel()
ax0, ax1, ax2, ax3 = axes
ax0.imshow(image, cmap=plt.cm.gray, interpolation='nearest')
ax0.set_title("原始图像")
ax1.imshow(gradient, cmap=plt.cm.Spectral, interpolation='nearest')
ax1.set_title("梯度")
ax2.imshow(markers, cmap=plt.cm.Spectral, interpolation='nearest')
ax2.set_title("标记")
ax3.imshow(labels, cmap=plt.cm.Spectral, interpolation='nearest')
ax3.set_title("分割")
for ax in axes:ax.axis('off')
fig.tight_layout()
plt.show()

3.分水岭实现医学诊断

分水岭算法的主要目标在于找到图像的连通区域并进行分割。在实际处理过程中,如果直接以梯度图像作为输入,则容易受到噪声的干扰,产生多个分割区域;如果对原始图像进行平滑滤波处理后再进行梯度计算,则容易将某些原本独立的相邻区域合成一个区域。当然,这里的区域主要还是指图像内容变化不大或灰度值相近的连通区域。

 利用分水岭对肺癌细胞进行分割诊断处理的Python代码:

import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
def watershed_demo(img):"""分水岭分割核心函数:返回所有中间处理结果(用于matplotlib显示)"""# 1. 去噪声(彩色图像专用滤波)blurred = cv.pyrMeanShiftFiltering(img, 10, 100)# 2. 灰度化 + 二值化(OTSU自动阈值)gray = cv.cvtColor(blurred, cv.COLOR_BGR2GRAY)ret, thresh = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)# 3. 开运算去黑点噪声(先腐蚀再膨胀)kernel = cv.getStructuringElement(cv.MORPH_RECT, (3, 3))opening = cv.morphologyEx(thresh, cv.MORPH_OPEN, kernel, iterations=2)# 4. 膨胀确定背景区域(扩大背景范围)sure_bg = cv.dilate(opening, kernel, iterations=3)# 5. 距离变换(突出前景核心)dist = cv.distanceTransform(opening, cv.DIST_L2, 3)dist_output = cv.normalize(dist, 0, 1.0, cv.NORM_MINMAX)  # 归一化到0-1# 6. 阈值化确定前景区域ret, surface = cv.threshold(dist, dist.max() * 0.6, 255, cv.THRESH_BINARY)surface_fg = np.uint8(surface)  # 转换为uint8类型# 7. 计算未知区域(背景与前景的过渡区)unknown = cv.subtract(sure_bg, surface_fg)# 8. 连通区域标记 + 分水岭分割ret, markers = cv.connectedComponents(surface_fg)markers = markers + 1  # 背景标签从0改为1(避免与未知区域冲突)markers[unknown == 255] = 0  # 未知区域标记为0markers = cv.watershed(img, markers)  # 执行分水岭result_img = img.copy()  # 复制原图,避免修改原数据result_img[markers == -1] = [255, 0, 0]  # 分割边界标记为红色(BGR)# 9. 颜色空间转换(BGR→RGB,供matplotlib显示)blurred_rgb = cv.cvtColor(blurred, cv.COLOR_BGR2RGB)result_img_rgb = cv.cvtColor(result_img, cv.COLOR_BGR2RGB)# 返回所有需显示的结果(按显示顺序排列)return [("原始图像", cv.cvtColor(img, cv.COLOR_BGR2RGB)),  # 原始图(BGR→RGB)("二值化图像", thresh),  # 灰度图("开运算去噪", opening),  # 灰度图("确定背景区域", sure_bg),  # 灰度图("距离变换(归一化)", dist_output),  # 浮点数灰度图("前景标记", surface),  # 灰度图("前景二值图", surface_fg),  # 灰度图("分水岭分割结果", result_img_rgb)  # 彩色结果图(RGB)]
# -------------------------- 主逻辑:图像读取 + matplotlib显示 --------------------------
if __name__ == "__main__":# 1. 读取图像img_path = "37.jpg"img = cv.imread(img_path)# 2. 执行分水岭分割,获取所有显示结果display_results = watershed_demo(img)# 3. matplotlib 子图布局(2行4列,容纳8个结果图)plt.figure(figsize=(16, 8))  # 窗口大小:宽16英寸,高8英寸plt.rcParams['font.sans-serif'] = ['SimHei']  # 显示中文标题plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示异常# 4. 逐个绘制子图for idx, (title, img_data) in enumerate(display_results, 1):plt.subplot(2, 4, idx)  # 2行4列,第idx个子图if len(img_data.shape) == 3:  # 彩色图像(RGB格式)plt.imshow(img_data)else:  # 灰度图像(二值图/距离变换图等)# 距离变换图用jet色表更直观,其他灰度图用gray色表cmap = 'jet' if "距离变换" in title else 'gray'plt.imshow(img_data, cmap=cmap)plt.title(title, fontsize=12)  # 添加子图标题plt.axis('off')  # 关闭坐标轴,聚焦图像# 5. 调整子图间距,避免标题/图像重叠plt.tight_layout()# 6. 显示所有子图(阻塞窗口,按关闭键退出)plt.show()

实验表明,采用标记分水岭算法对肺部图像进行分割具有良好的效果,能在一定程度上突出病变区域,起到辅助医学诊断的目的,具有一定的使用价值。

四、本文用到的图片

五、总结

本文探讨了分水岭算法在医学CT图像分割中的应用,重点解决肺癌诊断中的图像处理问题。针对传统分水岭算法存在的过分割问题,提出了标记分水岭算法,通过引入内部标记和外部标记来修正梯度图像。研究展示了距离变换和梯度两种分水岭分割方法的具体实现,并通过Python代码验证了其在医学图像处理中的有效性。实验结果表明,标记分水岭算法能有效分割肺部CT图像中的病变区域,为医生诊断提供辅助支持。该方法在降低误诊率、提高诊断效率方面具有临床价值。

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

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

相关文章

mysql和java获取经纬度的距离的两种方式

mysql和java获取经纬度的距离的两种方式mysql和java获取经纬度的距离的两种方式 T713802819052   取车距离:40333   还车距离:15303 根据订单号vlookup关联一下,单位是 米 1.java与mysql的计算公式是一一对…

SQL索引及调优

SQL索引及调优一:索引的含义及用法 ● 索引index:一种特殊的查找结构,它存储了表中特定列的值,并对这些值进行排序,同时保存了指向原表行数据的物理地址指针。 ● 先查索引,通过索引查表,提高查询效率。 ● 优点…

Sequence2Sequence - -一叶知秋

Sequence2SequenceSequence-to-Sequence(简称 Seq2Seq) 是一种用于序列到序列(Sequence → Sequence)映射任务的深度学习模型结构。 它最早由 Google 在 2014 年提出,用于 机器翻译(Machine Translation),后来…

Python列表 _ 创一个购物清单

Python列表 _ 创一个购物清单shopping_list = []shopping_list.append("键盘")shopping_list.append("键帽")print(shopping_list)print(shopping_list[0])print(len(shopping_list))price = [1,2…

如何在Golang项目中集成Prometheus进行监控?

本文将带大家学习如何在 Golang 项目中集成 Prometheus 进行监控,包括安装客户端库、定义和注册指标、暴露指标端点、更新指标值、配置标签和注册表,以及生产环境的建议配置。 添加 Prometheus 客户端库依赖 在 Go 项…

第177天:信息收集篇自动项目本机导出外部打点域内通讯PillagerBloodHound

工具信息收集 内网中 个人用机的角色 账号密码存储 1,浏览器自动存储 2,自己创建文件记录 3,某些工具自动存储 今天的这些工具就是可以对以上这些进行信息进行提取,如果是web服务器或者数据库服务器,用这些工具收…

如何在Linux中,为Flatpak版本的Edge浏览器导入证书

当使用 Flatpak 版本的 Edge 浏览器时,可能会遇到缺少证书管理功能的问题。本文提供了两种解决方案:1)通过 edge://certificate-manager/localcerts 内部链接图形化导入证书;2)将证书文件复制到系统信任目录 /etc…

2025年防火HPL板厂家权威推荐榜单:耐刮防火板/耐高温防火板 /阻燃高压装饰板源头厂家精选

在建筑装饰与工业应用领域,防火HPL板(热固性树脂浸渍纸高压层积板)作为关键的表面装饰耐火材料,其性能直接关系到工程安全与使用寿命。据行业数据显示,2025年全球防火板市场规模预计将以9.74%的年复合增长率持续扩…

Java 集合 “Map(1)”面试清单(含超通俗生活案例与深度理解) - 教程

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

2025 年铸铁井盖生产厂家最新推荐榜,技术实力与市场口碑深度解析防沉降球墨/防沉降/电力/双层铸铁井盖公司推荐

引言 在城市基础设施建设持续推进的背景下,铸铁井盖的质量与性能对市政安全、道路通行效率至关重要。为助力采购方精准筛选优质供应商,中国市政工程协会联合建筑材料测试中心于 2024 年第四季度开展了铸铁井盖行业专…

smss!SmpStartCsr函数分析之SmpLoadSubSystemsForMuSession3389远程桌面新进程csrss.exe的由来 - 指南

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

220kv数字化变电站保护解决方案综述[期刊理解]

220kv数字化变电站保护解决方案综述[期刊理解] 本文围绕双母接线型 220kV 数字化变电站,系统阐述了继电保护的实施方案、配置逻辑、故障处理机制及配合关系,核心重点可从以下五大维度梳理:重点内容:核心背景与数字…

2025年10月VI设计公司权威推荐排行榜:排名依据包括项目交付质量、客户满意度、创新能力和市场影响力

摘要 VI设计行业近年来随着品牌竞争加剧而快速发展,企业越来越重视视觉识别系统以提升市场竞争力。2025年,行业趋势聚焦于数字化整合和极简主义设计,帮助企业实现品牌焕新。本文基于权威数据和用户口碑,提供一份VI…

2025年0糖苏打水厂家权威推荐榜单:带帽苏打水/茉莉苏打水 /蜜桃苏打水源头厂家精选

随着健康饮食观念的普及,0糖苏打水市场呈现快速增长态势。行业数据显示,2025年中国无糖饮料市场规模预计突破800亿元,其中0糖苏打水品类年均增长率达25%以上。在这一市场背景下,生产企业的技术实力与品质管控能力成…

Bilidown Setup 1.2.7下载

软件已停更,目前能用,且用且珍惜 Bilidown Setup 1.2.7下载

rpm因依赖安装失败的一次检查记录

rpm安装rpm -i --test XaoS-3.0-1.i386.rpm 出现错误:error: failed dependencies:libslang.so.0 is needed by XaoS-3.0-1libpng.so.0 is needed by XaoS-3.0-1libaa.so.1 is needed by XaoS-3.0-但是,libslang.so.…

0296-Nand-机器语言

环境Time 2023-07-07前言 说明 参考:https://www.nand2tetris.org/ 目标 接上一节,通过模拟的 CPU 实现 mult 和 fill 程序。 mult // r2 = 0 @2 M=0// loop r1 > 0 (LOOP) @1 D=M @END D;JLE// r1 = r1 - 1 D=D-…

0295-Nand-时序逻辑

环境Time 2023-07-07前言 说明 参考:https://www.nand2tetris.org/ 参考:《编码:隐匿在计算机背后的语言》 目标 接上一节,实现 Bit、Register、RAM8、RAM64、RAM512、RAM4K、RAM16K、PC。 Bit /*** 1-bit registe…

[apt update docker 密钥问题]

问题输出 Get:26 http://mirrors.aliyun.com/ubuntu focal-backports/restricted amd64 DEP-11 Metadata [212 B] Get:27 http://mirrors.aliyun.com/ubuntu focal-backports/universe amd64 DEP-11 Metadata [30.5 kB…

0300-Nand-表示代码

环境Time 2023-07-09 Java 17前言 说明 参考:https://craftinginterpreters.com/contents.html https://github.com/GuoYaxiang/craftinginterpreters_zh https://space.bilibili.com/44550904目标 使用 Java 语言脚本…