使用Yolov7进行LUNA16的肺结节检测

2024-03-22 21:59

本文主要是介绍使用Yolov7进行LUNA16的肺结节检测,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1、图像预处理

1.1 从mhd文件中获取CT图像,保存3张切片


def normalizePlanes(npzarray):maxHU = 400minHU = -1000npzarray = (npzarray - minHU)/(maxHU - minHU)npzarray[npzarray>1] = 1npzarray[npzarray<0] = 0npzarray *= 255return (npzarray.astype(int))def make_mask(center,diam,z,width,height,spacing,origin):''''''mask = np.zeros([height,width])  #匹配图像#定义结节所在的体素范围v_center = (center-origin)/spacingv_diam = int(diam/spacing[0]+5)v_xmin = np.max([0,int(v_center[0]-v_diam)-5])v_xmax = np.min([width-1,int(v_center[0]+v_diam)+5])v_ymin = np.max([0,int(v_center[1]-v_diam)-5])v_ymax = np.min([height-1,int(v_center[1]+v_diam)+5])v_xrange = range(v_xmin,v_xmax+1)v_yrange = range(v_ymin,v_ymax+1)x_data = [x*spacing[0]+origin[0] for x in range(width)]y_data = [x*spacing[1]+origin[1] for x in range(height)]#结节周围全都填充1for v_x in v_xrange:for v_y in v_yrange:p_x = spacing[0]*v_x + origin[0]p_y = spacing[1]*v_y + origin[1]if np.linalg.norm(center-np.array([p_x,p_y,z]))<=diam:mask[int((p_y-origin[1])/spacing[1]),int((p_x-origin[0])/spacing[0])] = 1.0return (mask)luna_path = "E:/LUNA16/src/subset0/"
output_path = "E:/VSCode/lung/npy"
file_list = glob("E:\LUNA16\src\subset0/" + "*.mhd")# 获取数据中的每一行
def get_filename(case):global file_listfor f in file_list:if case in f:return (f)# 节点的位置
df_node = pd.read_csv('E:\LUNA16\src/annotations.csv')
df_node["file"] = df_node["seriesuid"].apply(get_filename)
# df_node: 文件的路径  example:E:\LUNA16\src\subset0\1.3.6.1.4.1.14519.5.2.1……
df_node = df_node.dropna()# 循环遍历图像文件
#fcount = 0
for fcount, img_file in enumerate(tqdm(file_list)):print("Getting mask for image file %s" % img_file.replace(luna_path, ""))mini_df = df_node[df_node["file"] == img_file]  # 得到所有结节if(len(mini_df) > 0):    #跳过没有结节的文件#读取数据itk_img = sitk.ReadImage(img_file)img_array = sitk.GetArrayFromImage(itk_img)   #(z,y,x)num_z,height,width = img_array.shape    #heightXwidth constitute the transverse plane  origin = np.array(itk_img.GetOrigin())  #世界坐标系下的x,y,z(mm)spacing = np.array(itk_img.GetSpacing()) #世界坐标中的体素间隔(mm)#遍历所有节点for node_idx,cur_row in mini_df.iterrows():node_x = cur_row["coordX"]node_y = cur_row["coordY"]node_z = cur_row["coordZ"]diam = cur_row["diameter_mm"]#保留三个切片imgs = np.ndarray([3,height,width],dtype=np.float32)masks = np.ndarray([3,height,width],dtype=np.uint8)center = np.array([node_x,node_y,node_z])  #结点中心v_center = np.rint((center-origin)/spacing) #体素坐标系的结点中心(x,y,z)for i,i_z in enumerate(np.arange(int(v_center[2])-1,int(v_center[2])+2).clip(0,num_z-1)):   #clip防止超出zmask = make_mask(center,diam,i_z*spacing[2]+origin[2],width,height,spacing,origin)masks[i] = mask#imgs[i] = img_array[i_z]imgs[i] = normalizePlanes(img_array[i_z])np.save(os.path.join(output_path,"images_%04d_%04d.npy" % (fcount, node_idx)),imgs)np.save(os.path.join(output_path,"masks_%04d_%04d.npy" % (fcount, node_idx)),masks)

1.2  获取肺实质

for img_file in file_list:imgs_to_process = np.load(img_file).astype(np.float64) print("on image",img_file)for i in range(len(imgs_to_process)):img = imgs_to_process[i]#标准化mean = np.mean(img)   #均值std = np.std(img)    #标准差img = (img-mean)/std#寻找肺部附近的平均像素,以重新调整过度曝光的图像middle = img[100:400,100:400]#使用Kmeans算法将前景(放射性不透明组织)和背景(放射性透明组织,即肺部)分离。#仅在图像中心进行此操作,以尽可能避免图像的非组织部分。kmeans = KMeans(n_clusters=2,n_init=10).fit(np.reshape(middle,[np.prod(middle.shape),1]))#np.prod 计算给定数组中所有元素的乘积#np.reshape 低维变高维  .flatten() 高维变1维centers = sorted(kmeans.cluster_centers_.flatten())threshold = np.mean(centers)thresh_img = np.where(img<threshold,1.0,0.0)  #阈值化图像,二值化处理#腐蚀和膨胀eroded = morphology.erosion(thresh_img,np.ones([4,4]))dilation = morphology.dilation(eroded,np.ones([10,10]))labels = measure.label(dilation)#对二值图像进行标记,标记连通区域label_vals = np.unique(labels)  #获取标记值的唯一值,即标记的数量regions = measure.regionprops(labels) #标记区域good_labels = []for prop in regions:B = prop.bbox   #边界框if B[2]-B[0]<475 and B[3]-B[1]<475 and B[0]>40 and B[2]<472:good_labels.append(prop.label)#np.ndarray 创建多维数组mask = np.ndarray([512,512],dtype=np.int8)mask[:] = 0  #肺部maskfor N in good_labels:mask = mask + np.where(labels==N,1,0)mask = morphology.dilation(mask,np.ones([10,10]))imgs_to_process[i] = masknp.save(img_file.replace("images","lungmask"),imgs_to_process)

1.3  获取xml和jpg文件

        通过遍历只含结节图像nodule_annos.xls,该文件在另一篇文章中生成。点此跳转

       这里也可以通过遍历官方文件annotations.csv获得

        获取结节图像的结节信息生成xml文件,生成xml文件的方法参考了这位博主的方法,可以去学习,生成不了也可以去下载该博主共享的数据集,点此跳转

        获取名称匹配lungmask图像获得jpg图像

count = 0
for i in range(len(img_list)):origin_img = np.load(img_list[i])lung_mask = np.load(lungmask_list[i])for j in range(len(origin_img)):img = origin_img[j]lung_img = lung_mask[j]segment = img * lung_imgsegment = Image.fromarray(segment)segment = segment.convert('RGB')segment.save("E:\VSCode\lung/" + '{:04d}.jpg'.format(count+1))count = count + 1

2、模型

YOLOV7

 3、训练

2023.4.14更

 

当然后续继续训练也是有很大的提升的,模型没有完全收敛

2023.5.15 更


有小伙伴私信问我说xml中的filename和图片名称对不上,具体的原因是因为我删掉了一部分肺实质分割不太好的分割图,所以导致最后出现不匹配的原因。
不过labelimg查看结节位置都是对的,训练起来也没有太大的影响

这里用无删减的数据集训练了一下

训练结果

检测结果

这篇关于使用Yolov7进行LUNA16的肺结节检测的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/836286

相关文章

中文分词jieba库的使用与实景应用(一)

知识星球:https://articles.zsxq.com/id_fxvgc803qmr2.html 目录 一.定义: 精确模式(默认模式): 全模式: 搜索引擎模式: paddle 模式(基于深度学习的分词模式): 二 自定义词典 三.文本解析   调整词出现的频率 四. 关键词提取 A. 基于TF-IDF算法的关键词提取 B. 基于TextRank算法的关键词提取

使用SecondaryNameNode恢复NameNode的数据

1)需求: NameNode进程挂了并且存储的数据也丢失了,如何恢复NameNode 此种方式恢复的数据可能存在小部分数据的丢失。 2)故障模拟 (1)kill -9 NameNode进程 [lytfly@hadoop102 current]$ kill -9 19886 (2)删除NameNode存储的数据(/opt/module/hadoop-3.1.4/data/tmp/dfs/na

Hadoop数据压缩使用介绍

一、压缩原则 (1)运算密集型的Job,少用压缩 (2)IO密集型的Job,多用压缩 二、压缩算法比较 三、压缩位置选择 四、压缩参数配置 1)为了支持多种压缩/解压缩算法,Hadoop引入了编码/解码器 2)要在Hadoop中启用压缩,可以配置如下参数

Makefile简明使用教程

文章目录 规则makefile文件的基本语法:加在命令前的特殊符号:.PHONY伪目标: Makefilev1 直观写法v2 加上中间过程v3 伪目标v4 变量 make 选项-f-n-C Make 是一种流行的构建工具,常用于将源代码转换成可执行文件或者其他形式的输出文件(如库文件、文档等)。Make 可以自动化地执行编译、链接等一系列操作。 规则 makefile文件

使用opencv优化图片(画面变清晰)

文章目录 需求影响照片清晰度的因素 实现降噪测试代码 锐化空间锐化Unsharp Masking频率域锐化对比测试 对比度增强常用算法对比测试 需求 对图像进行优化,使其看起来更清晰,同时保持尺寸不变,通常涉及到图像处理技术如锐化、降噪、对比度增强等 影响照片清晰度的因素 影响照片清晰度的因素有很多,主要可以从以下几个方面来分析 1. 拍摄设备 相机传感器:相机传

综合安防管理平台LntonAIServer视频监控汇聚抖动检测算法优势

LntonAIServer视频质量诊断功能中的抖动检测是一个专门针对视频稳定性进行分析的功能。抖动通常是指视频帧之间的不必要运动,这种运动可能是由于摄像机的移动、传输中的错误或编解码问题导致的。抖动检测对于确保视频内容的平滑性和观看体验至关重要。 优势 1. 提高图像质量 - 清晰度提升:减少抖动,提高图像的清晰度和细节表现力,使得监控画面更加真实可信。 - 细节增强:在低光条件下,抖

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

pdfmake生成pdf的使用

实际项目中有时会有根据填写的表单数据或者其他格式的数据,将数据自动填充到pdf文件中根据固定模板生成pdf文件的需求 文章目录 利用pdfmake生成pdf文件1.下载安装pdfmake第三方包2.封装生成pdf文件的共用配置3.生成pdf文件的文件模板内容4.调用方法生成pdf 利用pdfmake生成pdf文件 1.下载安装pdfmake第三方包 npm i pdfma

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

业务中14个需要进行A/B测试的时刻[信息图]

在本指南中,我们将全面了解有关 A/B测试 的所有内容。 我们将介绍不同类型的A/B测试,如何有效地规划和启动测试,如何评估测试是否成功,您应该关注哪些指标,多年来我们发现的常见错误等等。 什么是A/B测试? A/B测试(有时称为“分割测试”)是一种实验类型,其中您创建两种或多种内容变体——如登录页面、电子邮件或广告——并将它们显示给不同的受众群体,以查看哪一种效果最好。 本质上,A/B测