摘要 

● 基于动态阈值算法实现眼底图像视杯分割,通过灰度分布梯度分析自适应调整分割区间,结合形态学后处理消除血管干扰,在118张眼底图像上达成72.1%的优秀分割效果

● 创新设计降序梯度分析法,通过计算最大梯度变化点动态确定0.5%-2%有效分割区间,有效应对眼底图像亮度不均、边界模糊等挑战

● 开发完整处理流程:绿色通道提取→自适应阈值分割→孔洞填充→轮廓绘制,输出带分割标记的医学影像

1.项目简介

"视盘和视杯的比值是评价青光眼诊断中的重要指标之一,视盘和视杯的分割是青光眼诊断的关键步骤。"

"视盘呈现亮黄色,可分为两个明显的区域: 中间明亮区(视杯)和外围区(视神经网膜边缘)"

以上内容来自参考文献:Fang L L and Zhang L R.2022.The review of optic disc and optic cup segmentation applications in computer-aided glaucoma diagnosis. Journal of Image and Graphics,27(10):2952-2971(方玲玲,张丽榕.2022. 视盘和视杯分割在计算机辅助青光眼诊断中的应用综述. 中国图象图 形学报,27(10):2952-2971)[DOI:10. 11834/jig. 210313]

项目要求实现对眼底图中视杯的识别分割,并进行性能评价(分割效果好、一般、差的百分比)。眼底图数据为课程提供,共118张。(眼底图像库|百度网盘链接

图像的特点有 :(1)目标:亮黄色,内部有血管干扰;不同图像的目标亮度和色度可能存在在一定范围内的差异。(2)背景:背景不均匀,部分图像有亮色干扰。 (3)分界线:部分图像的目标和背景的分界线不太分明。

项目方案主要通过对灰度值降序排序,计算最大梯度变化点,动态调整有效范围找到最佳分割阈值点,实现对视杯的分割。

2.实现代码

import os
import cv2
import numpy as np
from  skimage import morphology

def cup_segmentation():
    input_folder = r'' # 输入待处理图像文件夹路径
    output_folder = r''# 输出处理后图像文件夹路径

    if not os.path.exists(output_folder):
        os.makedirs(output_folder)

    for img_name in os.listdir(input_folder):
        if not img_name.endswith('.jpg'):
            continue

        # 读取图像并提取绿色通道,绿色通道阈值分割效果更好
        img = cv2.imread(os.path.join(input_folder, img_name))
        green_channel = img[:, :, 1].copy()

        # 动态阈值计算
        threshold = find_threshold(green_channel)

        # 阈值分割
        binary_mask = green_channel >= threshold

        # 后处理优化
        binary_mask = morphology.remove_small_objects(binary_mask, min_size=50)
        binary_mask = morphology.remove_small_holes(binary_mask, area_threshold=100)
        binary_mask = binary_mask.astype(np.uint8) * 255

        # 寻找边缘轮廓
        contours, _ = cv2.findContours(binary_mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

        # 在原图上绘制绿色边缘
        result = img.copy()
        cv2.drawContours(result, contours, -1, (0, 255, 0), 1)  # BGR格式绿色,线宽1px

        # 保存结果
        output_path = os.path.join(output_folder, f'processed_{img_name}')
        cv2.imwrite(output_path, result)
        print(f'Processed: {img_name}')


def find_threshold(gray_img):
    # 分析全图灰度分布
    sorted_values = np.sort(gray_img.flatten())[::-1]  # 降序排列

    # 寻找最大梯度变化点
    gradients = np.diff(sorted_values)
    steep_point = np.argmax(gradients)

    # 计算有效百分比范围(0.5%-2%)
    total = len(sorted_values)
    min_percent = max(0.5, 100 * (steep_point / total) - 0.5)
    max_percent = min(2.0, 100 * (steep_point / total) + 0.5)
    final_percent = (min_percent + max_percent) / 2

    # 计算最终阈值
    threshold_idx = int(total * final_percent / 100)
    return sorted_values[threshold_idx]

if __name__ == '__main__':
    cup_segmentation()

3.性能评价

以本人的主观判断为基准,将分割结果按与基准的相似程度由高到低评为“分割效果好”、“分割效果一般”、“分割效果差”

分割效果好 分割效果一般 分割效果差
72.1% 18.6% 9.3%

部分结果图如下:

分割效果差
分割效果差
分割效果差

分割效果一般
分割效果一般
分割效果一般

分割效果好
分割效果好
分割效果好

因为非相关专业领域,此性能评价结果主观性较强,仅供参考。

Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐