Matlab肺结节分割(肺结节提取)源程序,也有GUI人机界面版本。 使用传统图像分割方法,非深度学习方法。 使用LIDC-IDRI数据集。 工作如下: 1、读取图像。 读取原始dicom格式的CT图像,并显示,绘制灰度直方图; 2、图像增强。 对图像进行图像增强,包括Gamma矫正、直方图均衡化、中值滤波、边缘锐化; 3、肺质分割。 基于阈值分割,从原CT图像中分割出肺质; 4、肺结节分割。 肺质分割后,进行特征提取,计算灰度特征、形态学特征来分割出肺结节; 5、可视化标注文件。 读取医生的xml标注文件,可视化出医生的标注结果; 6、计算IOU、DICE、PRE三个参数评价分割效果好坏。 7、做成GUI人机界面。 两个版本的程序中,红框内为主函数,可以直接运行,其他文件均为函数或数据。
最近在研究肺结节分割相关的课题,今天就来给大家分享一下使用Matlab实现基于传统图像分割方法(非深度学习),利用LIDC - IDRI数据集完成肺结节分割的全过程,并且还打造了GUI人机界面版本哦,方便又实用。
1. 读取图像
首先要读取原始dicom格式的CT图像。在Matlab里,我们可以使用dicomread函数轻松搞定。代码如下:
% 读取dicom图像 img = dicomread('your_dicom_file.dcm'); % 显示图像 imshow(img, []); % 绘制灰度直方图 imhist(img);代码分析:第一行,dicomread函数接收dicom文件路径作为参数,读取图像数据并赋值给img变量。第二行,imshow函数负责显示图像,[]在这里的作用是让Matlab自动根据图像数据调整显示的灰度范围。第三行,imhist函数绘制图像的灰度直方图,帮助我们直观了解图像灰度分布情况。
2. 图像增强
Gamma矫正
Gamma矫正可以调整图像的亮度和对比度,代码如下:
gamma = 0.5; % 设置gamma值 img_gamma = imadjust(img, [], [], gamma);代码分析:先定义了gamma值,这里设为0.5,代表矫正的强度。imadjust函数对原图像img进行调整,[]表示使用默认的输入和输出范围,最后一个参数gamma就是我们设置的矫正系数。
直方图均衡化
img_equalized = histeq(img);代码分析:histeq函数直接对图像img进行直方图均衡化处理,将图像的灰度级均匀分布,从而增强图像对比度。
中值滤波
img_median = medfilt2(img, [3 3]);代码分析:medfilt2函数用于二维中值滤波,[3 3]是指定的滤波窗口大小,也就是3x3的窗口,它能有效去除图像中的椒盐噪声。
边缘锐化
h = fspecial('unsharp'); img_sharp = imfilter(img, h);代码分析:fspecial函数创建一个“unsharp”类型的滤波器,这个滤波器用于边缘锐化。然后imfilter函数将这个滤波器应用到原图像img上,得到锐化后的图像img_sharp。
3. 肺质分割
基于阈值分割来从原CT图像中分割出肺质。
% 手动设置一个合适的阈值,这里只是示例,实际可能需调整 threshold = 100; bw = img > threshold;代码分析:先设定一个阈值threshold,这里设为100,但实际应用中要根据图像特点调整。然后通过比较运算img > threshold,将大于阈值的像素设为1(白色),小于等于的设为0(黑色),得到二值图像bw,完成初步的肺质分割。
4. 肺结节分割
在肺质分割后,进行特征提取,通过计算灰度特征、形态学特征来分割出肺结节。
% 灰度特征计算示例,比如计算平均灰度 mean_gray = mean2(img(bw)); % 形态学特征提取,以面积为例 [labeled, num] = bwlabel(bw, 8); stats = regionprops(labeled, 'Area');代码分析:第一行,mean2函数计算肺质区域(img(bw))的平均灰度值。第二行,bwlabel函数对二值图像bw进行标记,8表示使用8连通区域标记,返回标记后的图像labeled和区域数量num。第三行,regionprops函数计算标记区域的属性,这里选择计算“Area”面积属性,便于后续通过面积等形态学特征筛选出肺结节。
5. 可视化标注文件
读取医生的xml标注文件,可视化出医生的标注结果。
% 假设这里有个函数parse_xml来解析xml文件获取标注信息 [annotations] = parse_xml('your_xml_file.xml'); % 这里简单假设annotations包含标注位置等信息,在图像上绘制标注 for i = 1:size(annotations, 1) % 根据标注信息获取坐标等,这里假设获取到x,y坐标和半径r x = annotations(i, 1); y = annotations(i, 2); r = annotations(i, 3); rectangle('Position', [x - r, y - r, 2 * r, 2 * r], 'EdgeColor','r'); end代码分析:先调用假设的parse_xml函数解析xml文件获取标注信息存到annotations里。然后通过循环遍历每个标注,从annotations里获取坐标和半径等信息,使用rectangle函数在图像上绘制红色矩形来表示标注位置。
6. 计算IOU、DICE、PRE三个参数评价分割效果好坏
% 假设这里有分割结果图像bw_seg和真实标注二值图像bw_true % 计算交集 intersection = sum(bw_seg & bw_true, 'all'); % 计算并集 union_set = sum(bw_seg | bw_true, 'all'); % 计算IOU iou = intersection / union_set; % 计算DICE dice = 2 * intersection / (sum(bw_seg, 'all') + sum(bw_true, 'all')); % 计算PRE(这里假设bw_seg为预测结果,bw_true为真实结果,计算准确率) tp = sum(bw_seg & bw_true, 'all'); fp = sum(bw_seg & ~bw_true, 'all'); pre = tp / (tp + fp);代码分析:首先通过逻辑与运算计算分割结果和真实标注的交集,逻辑或运算计算并集,从而得出IOU。接着通过交集以及分割结果和真实标注中前景像素总和计算DICE。最后,通过真阳性(tp)和假阳性(fp)计算准确率(PRE)。
7. 做成GUI人机界面
这部分主要利用Matlab的GUIDE工具来创建交互式界面。在GUIDE里,可以方便地拖拽各种组件,比如按钮、文本框、图像显示区域等。然后为每个组件编写回调函数,实现相应功能。例如,为“读取图像”按钮编写回调函数,在点击按钮时执行读取图像的代码。虽然这里不详细展开GUIDE的使用,但思路就是通过它将前面实现的各个功能整合到一个友好的界面里。
在整个项目的两个版本程序中,红框内为主函数,可以直接运行,其他文件均为函数或数据,分工明确,便于管理和维护。希望这篇博文能给同样在研究肺结节分割的小伙伴们一些启发和帮助呀!