实战:使用yolov3完成肺结节检测(Luna16数据集)
yolov3是一个比较常用的端到端的目标检测深度学习模型,这里加以应用,实现肺结节检测。由于Luna16数据集是三维的,需要对其进行切片操作,转换成yolov3可以处理的二维图片。
1. yolov3代码及原理
* 代码
* 原理
2. Luna16数据集
* 数据集介绍
* 转换成voc数据集格式
3. 检测效果预览
更新:2019.9.10
对数据集进行肺实质分割。
更新:2019.9.14
使用分割后的数据进行训练
更新:2019.9.23
修改anchor size后重新训练
更新:2019.12.5
发现一个注释的错误:
a = image_array.transpose(1,2,0)[:,:,20] #transpose是将(z,x,y)的三维矩阵转为(x,y,z)的矩阵
应该是transpose是将(z,y,x)的三维矩阵转为(y,x,z)的矩阵
更新:2019.12.11
发现应该坐标换算错误:
#如果图像进行旋转了,那么坐标也要旋转
if isflip :
x_max = 512 - x_min#修改前是 x_min = 512 - x_min 以下类似
y_max = 512 - y_min
x_min = 512 - x_max
y_min = 512 - y_max
x = 512 - x
y = 512 - y
补充 2020.11.19
博主临近毕业,可能有消息无法及时回复,见谅,有问题请留言。
有很多csdner向我要数据集和代码,关于代码核心部分已经在博客中讲解(已上传csdn,存在些许bug),如果要提高自己能力,建议看懂,自己上手。如果是想要快速上手,测试相关数据集,我已经上传百度云VOC数据集,密码:zc0p。
赠人玫瑰,手留余香,如果我的博文/数据集/代码对你有所帮助,麻烦点个赞~~
补充:关于为什么分享数据集size不是512*512的,这里我对原始CT是进行了归一化的,即1mm*1mm*1mm,所以尺寸不一样。
1. yolov3代码及原理
1.1代码
基于c的:
https://github.com/AlexeyAB/darknet
基于pytorch的:
https://github.com/eriklindernoren/PyTorch-YOLOv3
1.2原理
可查看:
Pytorch | yolov3原理及代码详解(一)
Pytorch | yolov3原理及代码详解(一)_NotFound1911的博客-CSDN博客_pytorch和yolo的关系
Pytorch | yolov3原理及代码详解(二)
Pytorch | yolov3原理及代码详解(二)_NotFound1911的博客-CSDN博客_yolov3pytorch代码详解
Pytorch | yolov3原理及代码详解(三)
Pytorch | yolov3原理及代码详解(三)_NotFound1911的博客-CSDN博客_yolov3pytorch代码详解
Pytorch | yolov3原理及代码详解(四)
Pytorch | yolov3原理及代码详解(四)_NotFound1911的博客-CSDN博客
2.Luna16数据集
2.1 Luna16数据集介绍
LUNA16数据集介绍_pursuit_zhangyu的博客-CSDN博客_luna16
Luna16数据集_一一|一一一亅的博客-CSDN博客_luna16数据集
上面说的很全,这里只进行补充:
2.1.1.图像的翻转
.mhd文件中有CT图像的属性,其中有一条是:
TransformMatrix = 1 0 0 0 1 0 0 0 1
- TransformMatric:图像矩阵是否翻转的标志。(在现实中CT扫描的时候有的人是正卧,有的人是仰卧的,所以会导致图像会出现翻转的情况。)
- TransformMatrix = 1 0 0 0 1 0 0 0 1是正卧的,这里举一个反卧的例子:TransformMatrix = -1 0 0 0 -1 0 0 0 1。当图像反卧的时候我们把图像的x,y坐标进行倒序调整,使其正卧。如下面代码所示(加载CT图像):
def load_itk_image(filename):
with open(filename) as f:
contents = f.readlines()
line = [k for k in contents if k.startswith('TransformMatrix')][0]
offset = [k for k in contents if k.startswith('Offset')][0]
EleSpacing = [k for k in contents if k.startswith('ElementSpacing')][0]
# 把值进行分割
offArr = np.array(offset.split(' = ')[1].split(' ')).astype('float')
eleArr = np.array(EleSpacing.split(' = ')[1].split(' ')).astype('float')
CT = CTImage(offArr[0],offArr[1],offArr[2],eleArr[0],eleArr[1],eleArr[2])
transform = np.array(line.split(' = ')[1].split(' ')).astype('float')
transform