python形态学分割图像

python形态学图像分割(分水岭算法),怎么提取我照片中分割好的病灶的掩膜

img

import numpy as np
import cv2
from matplotlib import pyplot as plt
# 1.加载图像
img = cv2.imread('IMD017.jpg')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# 2.阈值分割-将图像分为黑白两部分(大津阈值法)
ret, thresh = cv2.threshold(gray,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)
#3.对图像进行开运算(先腐蚀,再膨胀)
kernel = np.ones((3,3),np.uint8)
opening = cv2.morphologyEx(thresh,cv2.MORPH_OPEN,kernel, iterations = 2)
#4.对开运算得到的结果膨胀,得到大部分都是背景的区域
sure_bg = cv2.dilate(opening,kernel,iterations=3)
#5.获取前景图像
dist_transform = cv2.distanceTransform(opening,1,5)
ret, sure_fg = cv2.threshold(dist_transform,0.1*dist_transform.max(),255,0)#参数改小了,出现不确定区域
# 6.背景与前景,得到既有前景又有背景的重合区域
sure_fg = np.uint8(sure_fg)
unknown = cv2.subtract(sure_bg,sure_fg)#减去前景
#7.连通区域处理
ret,markers=cv2.connectedComponents(sure_fg,connectivity=8)# 标记变量
markers=markers+1
markers[unknown==255]=0
# 8.分水岭算法
markers=cv2.watershed(img,markers)
img[markers==-1]=[0,0,255]
# 可视化
cv2.imshow('p',img)
cv2.waitKey(0)

在你代码后面加这几行:

# 提取标签为2的区域作为病灶的掩膜
mask = np.zeros_like(markers)
mask[markers == 2] = 255

# 可视化病灶掩膜
cv2.imshow('Lesion Mask', mask)
cv2.waitKey(0)
cv2.destroyAllWindows()


该回答通过自己思路及引用到GPTᴼᴾᴱᴺᴬᴵ搜索,得到内容具体如下:
在分水岭算法进行图像分割后,可以通过提取标记矩阵(markers)中的特定值,来得到指定区域的掩膜。具体步骤如下:

  1. 根据分水岭算法的结果,将标记矩阵中指定的值提取出来,作为病灶区域的标记值(例如,本例中的-1)。

  2. 创建一个大小与原始图像相同的全黑图像(即掩膜),并将标记矩阵中指定的值在掩膜中对应的像素位置设为255(白色),其余位置设为0(黑色)。

  3. 可以通过掩膜与原始图像进行按位与操作,提取出病灶区域的像素值。

以下是修改后的代码,用于提取病灶区域的掩膜:

import numpy as np
import cv2
from matplotlib import pyplot as plt

# 1.加载图像
img = cv2.imread('IMD017.jpg')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

# 2.阈值分割-将图像分为黑白两部分(大津阈值法)
ret, thresh = cv2.threshold(gray,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)

# 3.对图像进行开运算(先腐蚀,再膨胀)
kernel = np.ones((3,3),np.uint8)
opening = cv2.morphologyEx(thresh,cv2.MORPH_OPEN,kernel, iterations = 2)

# 4.对开运算得到的结果膨胀,得到大部分都是背景的区域
sure_bg = cv2.dilate(opening,kernel,iterations=3)

# 5.获取前景图像
dist_transform = cv2.distanceTransform(opening,1,5)
ret, sure_fg = cv2.threshold(dist_transform,0.1*dist_transform.max(),255,0)#参数改小了,出现不确定区域

# 6.背景与前景,得到既有前景又有背景的重合区域
sure_fg = np.uint8(sure_fg)
unknown = cv2.subtract(sure_bg,sure_fg)#减去前景

# 7.连通区域处理
ret,markers=cv2.connectedComponents(sure_fg,connectivity=8)# 标记变量
markers=markers+1
markers[unknown==255]=0

# 8.分水岭算法
markers=cv2.watershed(img,markers)
img[markers==-1]=[0,0,255]

# 9.提取病灶区域的掩膜
mask = np.zeros_like(gray)
mask[markers == -1] = 255

# 10.可视化
cv2.imshow('p',mask)
cv2.waitKey(0)

在上述代码中,第9步新增了代码,用于创建并填充掩膜。最后,通过cv2.imshow()函数可以查看提取出的病灶区域掩膜。


如果以上回答对您有所帮助,点击一下采纳该答案~谢谢

  • 你可以参考下这个问题的回答, 看看是否对你有帮助, 链接: https://ask.csdn.net/questions/7661575
  • 我还给你找了一篇非常好的博客,你可以看看是否有帮助,链接:python手撕分水岭算法
  • 除此之外, 这篇博客: 【数字图像处理5.2】区域生长算法、分裂合并算法和分水岭分割法 python中的 实验前言与目的 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • 这些算法都属于【基于形态学的图像分割】这一范畴,我们最终做的一切,都是为了图像分割(比如分成黑白两块,相对提取物体主题,为物体描轮廓…)

    编写程序完成以下算法,并进行比较,得出结论。

    1. 区域生长算法
    2. 区域分裂合并算法
    3. 分水岭分割算法
  • 您还可以看一下 赵俊老师的程序员的数学通关课课程中的 常见数据分析统计:如何使用Python实现常见统计量的计算小节, 巩固相关知识点
  • 以下回答由chatgpt基于相关博客总结生成:

    可以通过以下步骤提取出分割后的病灶掩膜:

    1. 在分水岭算法中,执行完毕算法后,得到的markers矩阵中不为-1的像素为分割后的对象区域,即病灶区域。

    2. 可以使用numpy的where函数将markers矩阵中非-1的像素对应的位置计入掩膜,即可得到病灶的掩膜。代码如下:

    mask = np.zeros_like(markers, dtype=np.uint8)
    mask[markers != -1] = 255
    

    完整代码如下:

    import cv2
    import numpy as np
    
    # Load image
    img = cv2.imread('image.jpg')
    
    # Convert to grayscale
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    
    # Threshold and morphology to prepare for watershed
    thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)[1]
    kernel = np.ones((3,3), np.uint8)
    opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=2)
    
    # Find sure background and sure foreground
    sure_bg = cv2.dilate(opening,kernel,iterations=3)
    dist_transform = cv2.distanceTransform(opening, 1, 5)
    ret, sure_fg = cv2.threshold(dist_transform, 0.7*dist_transform.max(), 255, 0)
    
    # Find unknown regions and mark objects
    sure_fg = np.uint8(sure_fg)
    unknown = cv2.subtract(sure_bg, sure_fg)
    ret, markers = cv2.connectedComponents(sure_fg)
    markers = markers+1
    markers[unknown==255] = 0
    
    # Perform watershed
    markers = cv2.watershed(img, markers)
    img[markers == -1] = [255,0,0]
    
    # Extract lesion mask
    mask = np.zeros_like(markers, dtype=np.uint8)
    mask[markers != -1] = 255
    
    # Show result
    cv2.imshow('Image', img)
    cv2.imshow('Mask', mask)
    cv2.waitKey(0)
    cv2.destroyAllWindows()