如何去除二值化眼底血管骨架图像的外围伪影?
眼底图像视盘定位中的外围伪影去除问题
我尝试通过提取血管并标记中心像素来定位眼底图像的视盘,现有代码如下:
# Read the image and resize it to 800x800 pixels to reduce the computation time and memory usage img = load_image(file) blur = cv2.bilateralFilter(img, 9, 75, 75) median = cv2.medianBlur(blur, 5) # Extract the vessels from the image using the sato filter and normalize the image vessels = sato(median, sigmas=range(1, 10, 2), black_ridges=False) vessels = (vessels - np.min(vessels)) / (np.max(vessels) - np.min(vessels)) vessels = vessels * 255 vessels = vessels.astype(np.uint8) _, binary = cv2.threshold(vessels, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) skeleton = morphology.skeletonize(binary) g, nodes = graph.pixel_graph(skeleton, connectivity=2) px, distances = graph.central_pixel(g, nodes=nodes, shape=skeleton.shape, partition_size=100)
目前存在的问题:原始图像经处理后,骨架化图像的外围出现大量伪影(对应标注的蓝色区域),完全干扰了血管中心像素的计算,需要去除该区域的伪影。
解决思路与修改后的代码
核心思路是先提取眼底的有效圆形区域,屏蔽外围伪影区域,再进行后续的血管提取操作。具体步骤如下:
- 生成眼底区域掩码:通过灰度化、阈值分割和形态学操作,定位眼底的有效范围
- 应用掩码:将预处理后的图像与掩码结合,仅保留有效区域内的内容
修改后的代码:
import cv2 import numpy as np from skimage.filters import sato from skimage.morphology import skeletonize from skimage.graph import pixel_graph, central_pixel # Read the image and resize it to 800x800 pixels img = load_image(file) img_resized = cv2.resize(img, (800, 800)) # -------------------------- 新增:提取眼底有效区域掩码 -------------------------- # 转灰度图 gray = cv2.cvtColor(img_resized, cv2.COLOR_BGR2GRAY) # 大津法分割,得到初始掩码 _, mask = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU) # 形态学闭操作填充内部小孔 kernel_close = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (20, 20)) mask_closed = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel_close) # 形态学开操作去除外围小噪点 kernel_open = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (10, 10)) mask_clean = cv2.morphologyEx(mask_closed, cv2.MORPH_OPEN, kernel_open) # 确保掩码是单通道布尔类型 mask_clean = mask_clean.astype(bool) # ----------------------------------------------------------------------------- # 预处理图像(仅保留有效区域) blur = cv2.bilateralFilter(img_resized, 9, 75, 75) # 将外围伪影区域置为背景(黑色) blur_masked = blur.copy() blur_masked[~mask_clean] = 0 median = cv2.medianBlur(blur_masked, 5) # 提取血管并处理 vessels = sato(median, sigmas=range(1, 10, 2), black_ridges=False) vessels = (vessels - np.min(vessels)) / (np.max(vessels) - np.min(vessels)) vessels = vessels * 255 vessels = vessels.astype(np.uint8) # 应用掩码,去除外围伪影的血管检测结果 vessels[~mask_clean] = 0 _, binary = cv2.threshold(vessels, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) skeleton = skeletonize(binary) g, nodes = pixel_graph(skeleton, connectivity=2) px, distances = central_pixel(g, nodes=nodes, shape=skeleton.shape, partition_size=100)
关键说明
- 掩码生成环节采用形态学椭圆核,适配眼底图像的圆形特征,能有效区分眼底有效区域和外围伪影
- 在预处理和血管提取后都应用掩码,确保伪影区域不会参与后续的骨架化和中心像素计算
内容的提问来源于stack exchange,提问作者hascet33
相关产品推荐
相关产品推荐

