我試圖通過以下代碼使用Kmeans對肺部CT影像進行分割:
def process_mask(mask)。
convex_mask = np.copy(mask)
for i_layer in range(convex_mask.shape[0] )。)
mask1 = np.ascontiguousarray(mask[i_layer])
if np.sum(mask1)>0。
mask2 = convex_hull_image(mask1)
if np.sum(mask2)>2*np.sum(mask1)。
mask2 = mask1
else:
mask2 = mask1
convex_mask[i_layer] = mask2
struct = generate_binary_structure(3,1)
dilatedMask = binary_dilation(convex_mask,structure=struct,iterations=10)
return dilatedMask
def lumTrans(img)。
lungwin = np.array([-1200.,600.] )
newimg = (img-lungwin[0])/(lungwin[1]-lungwin[0] )
newimg[newimg<0]=0。
newimg[newimg>1]=1
newimg = (newimg*255).astype('uint8'/span>)
return newimg
def lungSeg(imgs_to_process,output,name)。
if os.path.existence(output '/' name '_clean.npy') : 回傳。
imgs_to_process = Image.open(imgs_to_process)
img_to_save = imgs_to_process.copy()
img_to_save = np.asarray(img_to_save).astype('uint8')
imgs_to_process = lumTrans(imgs_to_process)
imgs_to_process = np.expand_dims(imgs_to_process, axis=0)
x,y,z = imgs_to_process.shape
img_array = imgs_to_process.copy()
A1 = int(y/(512./100))
A2 = int(y/(512./400))
A3 = int(y/(512./475)
A4 = int(y/(512./40))
A5 = int(y/(512./470))
for i in range(len(imgs_to_process))。
img = imgs_to_process[i] 。
print(img.shape)
x,y = img.shape
#Standardize the pixel values(像素值標準化
allmean = np.mean(img)
allstd = np.std(img)
img = img-allmean
img = img/allstd
# 查找肺部附近的平均像素值。
# 對沖刷過的影像進行重新標準化處理。
middle = img[A1:A2,A1:A2]
Mean = np.mean(middle)
max = np.max(img)
min = np.min(img)
kmeans = KMeans(n_clusters=2).fit(np.reshape(middle,[np.prod(middle.shape),1] )
centers = sorted(kmeans.cluster_centers_.flatten() )
threshold = np.mean(center)
thresh_img = np.where(img<threshold,1.0,0.0) # threshold the image
eroded = morphology.erosion(thresh_img,np.ones([4,4] )
dilation = morphology.dilation(eroded,np.ones([10,10] )
label = 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]< A3 and B[3]-B[1]< A3 and B[0]>A4 and B[2]<A5。
Good_labels.append(prop.label)
mask = np.ndarray([x,y],dtype=np.int8)
mask[:] =0
for N in good_labels:
mask = mask np.where(labs==N,1,0)
mask = morphology.dilation(mask,np.ones([10,10] ) #最后一次擴張。
imgs_to_process[i] = mask
m1 = imgs_to_process
convex_mask = m1
dm1 = process_mask(m1)
擴張的Mask = dm1
面罩 = m1
extramask = dilatedMask ^ Mask
bone_thresh = 180
pad_value =0
img_array[np.isnan(img_array)]=-2000
sliceim = img_array
sliceim = sliceim*dilatedMask pad_value*(1-dilatedMask).astype('uint8')
bones = sliceim*extramask>bone_thresh
sliceim[bones] = pad_value
x,y,z = sliceim.shape
if not os.path.exists(output):
os.makedirs(output)
img_to_save[sliceim.squeeze()==0] =0
im = Image.fromarray(img_to_save)
im.save(output name ' .png', 'PNG')
問題是分割后的肺部仍然包含白色的邊框,就像這樣:
分割后的肺部仍然包含白色的邊框。
分割的肺(輸出):
未分割的肺(輸入):
完整的代碼可以在Google Colab Notebook中找到。代碼.
。而資料集的樣本是這里。
uj5u.com熱心網友回復:
>。對于這個問題,我不建議使用Kmeans顏色量化,因為這種技術通常是保留給有各種顏色的情況下,你想把它們分割成主導色塊。請看這個涉及分割看起來相似的顏色區域的上一個答案的典型用例。由于您的CT掃描影像是灰度的,所以Kmeans的性能并不理想。這里有一個潛在的解決方案,使用OpenCV進行簡單的影像處理:
。獲得二進制影像。加載輸入影像,轉換為灰度cv2.cvtColor(),Otsu的閾值cv2.threshold()以獲得二進制影像,并查找輪廓cv2.findContours()。
創建一個空白掩碼來提取所需的物件。我們可以使用np.zeros()來創建一個與輸入影像大小相同的空掩碼。
使用輪廓面積和長寬比過濾輪廓。我們通過確保輪廓在指定的面積閾值以及長寬比內來搜索肺部物件。我們使用cv2.contourArea()、cv2.arcLength()和cv2.actroxPolyDP()進行輪廓周長和輪廓形狀近似。如果我們已經找到了我們的肺部物件,我們利用cv2.drawContours來用白色填充我們的掩碼,以表示我們要提取的物件。
與原始影像的位數和掩碼。最后,我們將掩碼轉換為灰度,并用cv2.bitwise_and()來獲得我們的結果。
->大津的閾值
檢測到的要提取的物件以綠色突出顯示 -> 填充掩碼
Bitwise-and to get our result -> Optional result with white background instead
代碼
import cv2
import numpy as np
image = cv2.imread('1.png')
Highlight = image.copy()
原始 = image.copy()
# 將影像轉換成灰度,大津的閾值,并找到輪廓線。
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(grey, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU) [1]
Contours = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = contours[0] if len(contours) == 2 else Contours[1]
# 創建黑色掩碼以提取所需物件
mask = np.zeros(image.shape, dtype=np.uint8)
# 通過使用輪廓面積和長寬比進行過濾來搜索物件。
for c in輪廓線。
# Contour area 等高線的面積
area = cv2.contourArea(c)
# Contour perimeter等高線的周長True)
# Contour approximation 輪廓線的近似度
approx = cv2. approxPolyDP(c, 0.035 * peri, True)
(x, y, w, h) = cv2.boundingRect( approx)
aspect_ratio = w / float(h)
# 如果通過過濾器,則在蒙版上繪制填充的輪廓。
# These are arbitary values, may need to change depending on input image[/span].
if aspect_ratio <= 1.2 or area < 5000:
cv2.drawContours(highlight, [c], 0, (0,255, 0), -1)
cv2.drawContours(mask, [c], 0, (255,255, 255), -1)
# 將3通道掩碼轉換為灰度,然后用原影像進行位元化處理,以獲得結果。
mask = cv2.cvtColor(mask, cv2.COLOR_BGR2GRAY)
result = cv2.bitwise_and(original, original, mask=mask)
# Uncomment if you want background to be white instead of black[/span
# result[mask==0] = (255,255,255)
# 顯示
cv2.imshow('gray', gray)
cv2.imshow('thresh', thresh)
cv2.imshow('highlight', highlight)
cv2.imshow('mask', mask)
cv2.imshow('result', result)
# 保存影像# cv2.imwrite('grey.png', gray)。
# cv2.imwrite('thresh.png', thresh)
# cv2.imwrite('highlight.png', highlight)
# cv2.imwrite('mask.png', mask)
# cv2.imwrite('result.png', result)
cv2.waitKey(0)
uj5u.com熱心網友回復:
解決這個問題的一個更簡單的方法是使用形態學侵蝕。它只是比你將不得不在閾值中進行調整
。轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/320319.html
標籤:
Kubernetes的資源控制器Job和CronJob詳解與示例 ......
uj5u.com 2020-09-10 00:10:45 moreVMware下安裝CentOS 一、軟硬體準備 1 Centos鏡像準備 1.1 CentOS鏡像下載地址 下載地址 1.2 CentOS鏡像下載程序 點擊下載地址進入如下圖的網站,選擇需要下載的版本,這里選擇的是Centos8,點擊如圖所示。 決定選擇Centos8后,選擇想要的鏡像源進行下載,此 ......
uj5u.com 2020-09-10 00:12:10 more如何使用Grep 命令查找多個字串 大家好,我是良許! 今天向大家介紹一個非常有用的技巧,那就是使用 grep 命令查找多個字串。 簡單介紹一下,grep 命令可以理解為是一個功能強大的命令列工具,可以用它在一個或多個輸入檔案中搜索與正則運算式相匹配的文本,然后再將每個匹配的文本用標準輸出的格式 ......
uj5u.com 2020-09-10 00:12:28 moregit配置http代理 經常遇到克隆 github 慢的問題,這里記錄一下幾種配置 git 代理的方法,解決 clone github 過慢。 目錄 git配置代理 git單獨配置github代理 git配置全域代理 配置終端環境變數 git配置代理 主要使用 git config 命令 git單獨 ......
uj5u.com 2020-09-10 00:12:33 morenpm install 裝包時提示Error EACCES permission denied解決辦法 ......
uj5u.com 2020-09-10 00:12:53 moreCentos 7下安裝nginx,使用yum install nginx,提示沒有可用的軟體包。 18 (flaskApi) [root@67 flaskDemo]# yum -y install nginx 19 已加載插件:fastestmirror, langpacks 20 Loading ......
uj5u.com 2020-09-10 00:13:13 more在公網的服務器上經常遇到別人爆破你服務器的22埠,用來挖礦或者干其他嘿嘿嘿的事情~ 這種情況下正確的做法是: 修改默認ssh的22埠 使用設定密鑰登錄或者白名單ip登錄 建議服務器密碼為復雜密碼 創建普通用戶登錄服務器(root權限過大) 建立堡壘機,實作統一管理服務器 統計爆破IP [root ......
uj5u.com 2020-09-10 00:13:17 moreLinux系統中一些常見的快捷方式,可有效提高操作效率,在某些時刻也能避免操作失誤帶來的問題。 ......
uj5u.com 2020-09-10 00:13:31 more作業系統存在著大量的資料檔案資訊,相應檔案資訊會存在于系統相應目錄中,為了更好的管理資料資訊,會將系統進行一些目錄規劃,不同目錄存放不同的資源。 ......
uj5u.com 2020-09-10 00:13:35 more這里以Chrome為例。 1. 準備作業 wsl是可以使用Windows主機上安裝的exe程式,出于安全考慮,默認情況下改功能是無法使用。要使用的話,終端需要以管理員權限啟動。 我這里以Windows Terminal為例,介紹如何默認使用管理員權限打開終端,具體操作如下圖所示: 2. 操作 wsl ......
uj5u.com 2023-04-19 09:25:49 more問題:專案麒麟系統服務器的kdump服務無法啟動,沒有相關日志無法定位問題。 1、查看服務狀態是關閉的,重啟系統也無法啟動 systemctl status kdump 2、修改grub引數,修改“crashkernel”為“512M(有的機器數值太大太小都會導致報錯,建議從128M開始試,或者加個 ......
uj5u.com 2023-04-12 09:59:50 more問題:專案麒麟系統服務器的kdump服務無法啟動,沒有相關日志無法定位問題。 1、查看服務狀態是關閉的,重啟系統也無法啟動 systemctl status kdump 2、修改grub引數,修改“crashkernel”為“512M(有的機器數值太大太小都會導致報錯,建議從128M開始試,或者加個 ......
uj5u.com 2023-04-12 09:59:01 more1. 前文回顧 在之前的幾篇記憶體管理系列文章中,筆者帶大家從宏觀角度完整地梳理了一遍 Linux 記憶體分配的整個鏈路,本文的主題依然是記憶體分配,這一次我們會從微觀的角度來探秘一下 Linux 內核中用于零散小記憶體塊分配的記憶體池 —— slab 分配器。 在本小節中,筆者還是按照以往的風格先帶大家簡單 ......
uj5u.com 2023-04-05 16:44:11 more