脑血管医学图像颅内分割尝试——分水岭算法
code 1.2 不分割颅内直接分割code 2.0 实验版code 3.0 批量处理版code 3.1 加入孔洞填充总结
本篇博客原目的同https://blog.csdn.net/qq_40690815/article/details/105377094,但早期代码不够规范,整理时间较晚。 参考博客https://segmentfault.com/a/1190000015690356
code 1.2 不分割颅内直接分割
import cv2
as cv
import numpy
as np
from matplotlib
import pyplot
as plt
import string
import pylab
def pltImgShow(image
):
plt
.title
('pltImgShow')
plt
.imshow
(image
)
plt
.show
()
img1
= "DE #PP DE_CarotidAngio 1.0 Q30f 3 A_80kV.0061.tif"
img2
= "DE #PP DE_CarotidAngio 1.0 Q30f 3 A_80kV.0073.tif"
img3
= "DE #PP DE_CarotidAngio 1.0 Q30f 3 A_80kV.0085.tif"
img4
= "DE #PP DE_CarotidAngio 1.0 Q30f 3 A_80kV.0097.tif"
img5
= "DE #PP DE_CarotidAngio 1.0 Q30f 3 A_80kV.0109.tif"
img6
= "DE #PP DE_CarotidAngio 1.0 Q30f 3 A_80kV.0121.tif"
img7
= "DE #PP DE_CarotidAngio 1.0 Q30f 3 A_80kV.0133.tif"
img8
= "DE #PP DE_CarotidAngio 1.0 Q30f 3 A_80kV.0145.tif"
img9
= "DE #PP DE_CarotidAngio 1.0 Q30f 3 A_80kV.0157.tif"
img10
= "DE #PP DE_CarotidAngio 1.0 Q30f 3 A_80kV.0169.tif"
img
= cv
.imread
('D:/auxiliaryPlane/project/Python/medImgSegment/imgData/'+img5
)
plt
.subplot
(2,3,1)
plt
.title
('original')
plt
.imshow
(img
)
img_gray
= cv
.cvtColor
(img
,cv
.COLOR_RGB2GRAY
)
plt
.subplot
(2,3,2)
plt
.title
('img_gray')
plt
.imshow
(img_gray
)
ret
, thresh
= cv
.threshold
(img_gray
,254,255,cv
.THRESH_BINARY
)
plt
.subplot
(2,3,3)
plt
.title
('thresh')
plt
.imshow
(thresh
)
kernel
= np
.ones
((5,5),np
.uint8
)
opening
= cv
.morphologyEx
(thresh
,cv
.MORPH_OPEN
,kernel
, iterations
= 3)
dist_transform
= cv
.distanceTransform
(opening
,cv
.DIST_L2
,5)
ret
, sure_fg
= cv
.threshold
(dist_transform
,0.7*dist_transform
.max(),255,cv
.THRESH_BINARY
)
sure_fg
= np
.uint8
(sure_fg
)
print(opening
.shape
)
plt
.subplot
(2,3,4)
plt
.title
('opening')
plt
.imshow
(opening
)
sure_bg
= cv
.dilate
(opening
,kernel
,iterations
=3)
sure_bg
= cv
.bitwise_not
(sure_bg
,sure_bg
)
plt
.subplot
(2,3,5)
plt
.title
('sure_bg')
plt
.imshow
(sure_bg
)
nlabels
, labels
, stats
, centroids
= cv
.connectedComponentsWithStats
(sure_bg
)
markers
= labels
print(markers
.shape
)
markers
= markers
+1
img_gray
[markers
!= 3] = 255
plt
.subplot
(2,3,6), plt
.title
('markers'), plt
.imshow
(markers
)
plt
.show
()
markers
= cv
.watershed
(img
, markers
)
img
[markers
== -1] = [255,0,0]
plt
.subplot
(1,2,1); plt
.title
('img'); plt
.imshow
(img
)
plt
.subplot
(1,2,2); plt
.title
('markers'); plt
.imshow
(markers
)
plt
.show
()
code 2.0 实验版
import cv2
as cv
import numpy
as np
from matplotlib
import pyplot
as plt
import string
import pylab
def pltImgShow(image
):
plt
.title
('pltImgShow')
plt
.imshow
(image
)
plt
.show
()
img1
= "DE #PP DE_CarotidAngio 1.0 Q30f 3 A_80kV.0061.tif"
img2
= "DE #PP DE_CarotidAngio 1.0 Q30f 3 A_80kV.0073.tif"
img3
= "DE #PP DE_CarotidAngio 1.0 Q30f 3 A_80kV.0085.tif"
img4
= "DE #PP DE_CarotidAngio 1.0 Q30f 3 A_80kV.0097.tif"
img5
= "DE #PP DE_CarotidAngio 1.0 Q30f 3 A_80kV.0109.tif"
img6
= "DE #PP DE_CarotidAngio 1.0 Q30f 3 A_80kV.0121.tif"
img7
= "DE #PP DE_CarotidAngio 1.0 Q30f 3 A_80kV.0133.tif"
img8
= "DE #PP DE_CarotidAngio 1.0 Q30f 3 A_80kV.0145.tif"
img9
= "DE #PP DE_CarotidAngio 1.0 Q30f 3 A_80kV.0157.tif"
img9
= "DE #PP DE_CarotidAngio 1.0 Q30f 3 A_80kV.0169.tif"
img
= cv
.imread
('D:/auxiliaryPlane/project/Python/medImgSegment/imgData/'+img1
)
plt
.subplot
(2,3,1)
plt
.title
('original')
plt
.imshow
(img
)
img_gray
= cv
.cvtColor
(img
,cv
.COLOR_RGB2GRAY
)
plt
.subplot
(2,3,2)
plt
.title
('img_gray')
plt
.imshow
(img_gray
)
ret
, thresh
= cv
.threshold
(img_gray
,254,255,cv
.THRESH_BINARY
)
plt
.subplot
(2,3,3)
plt
.title
('thresh')
plt
.imshow
(thresh
)
kernel
= np
.ones
((5,5),np
.uint8
)
opening
= cv
.morphologyEx
(thresh
,cv
.MORPH_OPEN
,kernel
, iterations
= 3)
opening
= cv
.morphologyEx
(opening
,cv
.MORPH_CLOSE
,kernel
, iterations
= 3)
print(opening
.shape
)
plt
.subplot
(2,3,4)
plt
.title
('opening')
plt
.imshow
(opening
)
sure_bg
= cv
.dilate
(opening
,kernel
,iterations
=3)
sure_bg
= cv
.bitwise_not
(sure_bg
,sure_bg
)
plt
.subplot
(2,3,5)
plt
.title
('sure_bg')
plt
.imshow
(sure_bg
)
nlabels
, labels
, stats
, centroids
= cv
.connectedComponentsWithStats
(sure_bg
)
markers
= labels
print(markers
.shape
)
markers
= markers
+1
img_gray
[markers
!= 3] = 255
plt
.subplot
(2,3,6)
plt
.title
('img_gray')
plt
.imshow
(img_gray
)
plt
.show
()
ret
, thresh
= cv
.threshold
(img_gray
,0,255,cv
.THRESH_BINARY_INV
+cv
.THRESH_OTSU
)
print(thresh
.shape
)
plt
.subplot
(2,3,1)
plt
.title
('gray')
plt
.imshow
(thresh
,'gray')
kernel
= np
.ones
((3,3),np
.uint8
)
opening
= cv
.morphologyEx
(thresh
, cv
.MORPH_OPEN
, kernel
, iterations
= 1)
plt
.subplot
(2,3,2)
plt
.title
('morphologyEx,(3,3),2')
plt
.imshow
(opening
)
sure_bg
= cv
.dilate
(opening
,kernel
,iterations
=3)
dist_transform
= cv
.distanceTransform
(opening
,cv
.DIST_L2
,5)
ret
, sure_fg
= cv
.threshold
(dist_transform
,0.7*dist_transform
.max(),255,cv
.THRESH_BINARY
)
print(sure_fg
.dtype
)
sure_fg
= np
.uint8
(sure_fg
)
print(sure_fg
.dtype
)
unknown
= cv
.subtract
(sure_bg
,sure_fg
)
plt
.subplot
(2,3,3)
plt
.title
('dist_transform')
plt
.imshow
(dist_transform
)
ret
, markers
= cv
.connectedComponents
(sure_fg
)
print(markers
.shape
)
markers
= markers
+1
markers
[unknown
==255]=0
plt
.subplot
(2,3,4)
plt
.title
('final sure_fg')
plt
.imshow
(markers
)
markers
= cv
.watershed
(img
,markers
)
img
[markers
== -1] = [255,0,0]
plt
.subplot
(2,3,5); plt
.title
('img'); plt
.imshow
(img
)
plt
.subplot
(2,3,6); plt
.title
('markers'); plt
.imshow
(markers
)
plt
.show
()
code 3.0 批量处理版
import glob
import os
import cv2
from pylab
import*
import numpy
as np
from matplotlib
import pyplot
as plt
from PIL
import Image
from itertools
import chain
def fillHole(im_in
):
im_floodfill
= im_in
.copy
()
h
, w
= im_in
.shape
[:2]
mask
= np
.zeros
((h
+2, w
+2), np
.uint8
)
cv2
.floodFill
(im_floodfill
, mask
, (0,0), 255)
im_floodfill_inv
= cv2
.bitwise_not
(im_floodfill
)
im_out
= im_in
| im_floodfill_inv
return im_out
def inHead_seg(img
):
copyImg
= img
.copy
()
h
, w
= img
.shape
[:2]
mask
= np
.zeros
([h
+2, w
+2],np
.uint8
)
cv2
.floodFill
(copyImg
, mask
, (int(h
/2), int(w
/2)), (5, 5, 5), (55, 55, 55), (55, 55 ,55), cv2
.FLOODFILL_FIXED_RANGE
)
img_gray
= cv2
.cvtColor
(img
,cv2
.COLOR_RGB2GRAY
)
ret
, thresh
= cv2
.threshold
(img_gray
,254,255,cv2
.THRESH_BINARY
)
thresh
[:,:] = 0
copyImg_gray
= cv2
.cvtColor
(copyImg
,cv2
.COLOR_RGB2GRAY
)
thresh
[ copyImg_gray
==5 ] = 255
kernel
= np
.ones
((5,5),np
.uint8
)
thresh
= fillHole
(thresh
)
opening
= cv2
.morphologyEx
(thresh
,cv2
.MORPH_OPEN
,kernel
, iterations
= 3)
sure_bg
= cv2
.dilate
(opening
,kernel
,iterations
=5)
nlabels
, labels
, stats
, centroids
= cv2
.connectedComponentsWithStats
(sure_bg
)
markers
= labels
markers
= markers
+1
return img
,markers
,labels
def maxAreaFind(markers
):
markers
= list(chain
(*markers
))
mCnt
= np
.bincount
(markers
)
resFind
= np
.argmax
(mCnt
)
print (mCnt
,resFind
)
markers2
= list(filter(lambda x
: x
!= resFind
, markers
))
mCnt2
= np
.bincount
(markers2
)
if(any(mCnt2
) == False):
return resFind
resFind
= np
.argmax
(mCnt2
)
return resFind
WSI_MASK_PATH
= "D:/MINE_FILE/dataSet/CTA/CTA1"
paths
= glob
.glob
(os
.path
.join
(WSI_MASK_PATH
, '*.tif'))
paths
.sort
()
for ipath
in paths
:
img
= cv2
.imread
(ipath
)
img_gray
= cv2
.cvtColor
(img
,cv2
.COLOR_RGB2GRAY
)
img
,markers
,labels
= inHead_seg
(img
)
resFind
= maxAreaFind
(markers
)
labels
= labels
+ 1
img
[labels
== resFind
] = img
[labels
== resFind
]*0.6+(0,0,70)
img_gray
[labels
!= resFind
] = 0
img
= Image
.fromarray
(img
, mode
='RGB')
pre_savename
= 'medImgSegment/Documents/testTemp/'
line
= "inHead_t2"+ipath
[-8:-4]+".png"
print (pre_savename
,line
)
img
.save
(os
.path
.join
(pre_savename
,line
),'PNG')
效果实际上不是很理想
code 3.1 加入孔洞填充
from itertools
import chain
import cv2
import numpy
as np
from matplotlib
import pyplot
as plt
def fillHole(im_in
):
im_floodfill
= im_in
.copy
()
h
, w
= im_in
.shape
[:2]
mask
= np
.zeros
((h
+2, w
+2), np
.uint8
)
cv2
.floodFill
(im_floodfill
, mask
, (0,0), 255)
im_floodfill_inv
= cv2
.bitwise_not
(im_floodfill
)
im_out
= im_in
| im_floodfill_inv
return im_out
img1
= "DE #PP DE_CarotidAngio 1.0 Q30f 3 A_80kV.0055.tif"
img2
= "DE #PP DE_CarotidAngio 1.0 Q30f 3 A_80kV.0068.tif"
img3
= "DE #PP DE_CarotidAngio 1.0 Q30f 3 A_80kV.0070.tif"
img4
= "DE #PP DE_CarotidAngio 1.0 Q30f 3 A_80kV.0071.tif"
img5
= "DE #PP DE_CarotidAngio 1.0 Q30f 3 A_80kV.0072.tif"
img6
= "DE #PP DE_CarotidAngio 1.0 Q30f 3 A_80kV.0091.tif"
img7
= "DE #PP DE_CarotidAngio 1.0 Q30f 3 A_80kV.0092.tif"
img8
= "DE #PP DE_CarotidAngio 1.0 Q30f 3 A_80kV.0095.tif"
img9
= "DE #PP DE_CarotidAngio 1.0 Q30f 3 A_80kV.0112.tif"
img10
= "DE #PP DE_CarotidAngio 1.0 Q30f 3 A_80kV.0114.tif"
img11
= "DE #PP DE_CarotidAngio 1.0 Q30f 3 A_80kV.0115.tif"
img
= cv2
.imread
( 'D:/auxiliaryPlane/project/Python/medImgSegment/imgData/test1Error/'+img5
)
img
= cv2
.imread
( 'D:/MINE_FILE/dataSet/CTA/CTA1/DE #PP DE_CarotidAngio 1.0 Q30f 3 A_80kV.0103.tif')
copyImg
= img
.copy
()
h
, w
= img
.shape
[:2]
mask
= np
.zeros
([h
+2, w
+2],np
.uint8
)
print (img
[int(h
/2), int(w
/2)])
cv2
.floodFill
(copyImg
, mask
, (int(h
/2), int(w
/2)), (5, 5, 5), (55, 55, 55), (55, 55 ,55), cv2
.FLOODFILL_FIXED_RANGE
)
plt
.subplot
(2,3,1); plt
.title
('original'); plt
.imshow
(img
)
img_gray
= cv2
.cvtColor
(img
,cv2
.COLOR_RGB2GRAY
)
plt
.subplot
(2,3,2); plt
.title
('img_gray'); plt
.imshow
(img_gray
)
ret
, thresh
= cv2
.threshold
(img_gray
,254,255,cv2
.THRESH_BINARY
)
thresh
[:,:] = 0
copyImg_gray
= cv2
.cvtColor
(copyImg
,cv2
.COLOR_RGB2GRAY
)
thresh
[ copyImg_gray
==5 ] = 255
plt
.subplot
(2,3,3); plt
.title
('thresh'); plt
.imshow
(thresh
)
kernel
= np
.ones
((5,5),np
.uint8
)
thresh
= fillHole
(thresh
)
opening
= cv2
.morphologyEx
(thresh
,cv2
.MORPH_OPEN
,kernel
, iterations
= 3)
print (opening
.shape
)
plt
.subplot
(2,3,4); plt
.title
('opening'); plt
.imshow
(opening
)
sure_bg
= cv2
.dilate
(opening
,kernel
,iterations
=5)
plt
.subplot
(2,3,5); plt
.title
('sure_bg'); plt
.imshow
(sure_bg
)
nlabels
, labels
, stats
, centroids
= cv2
.connectedComponentsWithStats
(sure_bg
)
markers
= labels
print(markers
.shape
)
markers
= markers
+ 1
markers
= list(chain
(*markers
))
mCnt
= np
.bincount
(markers
)
resFind
= np
.argmax
(mCnt
)
print (mCnt
,resFind
)
markers2
= list(filter(lambda x
: x
!= resFind
, markers
))
mCnt2
= np
.bincount
(markers2
)
resFind
= np
.argmax
(mCnt2
)
print ('resFind: ',resFind
)
labels
= labels
+ 1
img_gray
[labels
!= resFind
] = 0
print ('img_shape: ',img
.shape
)
img
[labels
== resFind
] = img
[labels
== resFind
]*0.6+(0,0,70)
img
[img_gray
== 255] = (255,0,0)
plt
.subplot
(2,3,6); plt
.title
('img'); plt
.imshow
(img
)
plt
.show
()
总结
分水岭算法不适用于颅内血管分割这个数量多,面积不一,分布不均匀的实际医学图像,因此后来转变思路尝试用分水岭算法来分割颅内区域,但本实验展示的图像实际上是比较标准的一张,脑CT图从上到下扫描会出现很多种情况,在分水岭的腐蚀与膨胀函数中不一定适用于所有情况。