2016-12-14 323 views
-1

我在matlab中的圖像分割中掙扎。我的目標是從ct掃描圖像中提取肝臟。 This is sample image肝臟的Matlab圖像分割

我爲這個樣本圖像提取肝臟,輸出是這樣的Output image for sample image。 我的實現代碼

function [] = Code4(image_file) 
image = imread(image_file);  
[height, width, planes] = size(image); 
rgb = reshape(image, height, width * planes); 
r = image(:, :, 1);    
g = image(:, :, 2);    
b = image(:, :, 3);    

% since r,g & b are of equeal values, we will be considering only r. 

mask=r>120 & r<140 ; % range of color component for liver 
labels = bwlabel(mask); 
id = labels(111, 200); 

% get the mask containing only the desired object 
liver = (labels == id); 
imagesc(liver); 
colorbar; 

end 

我的問題是,當我改變形象,肝段的RGB值可能會有所不同。 這裏是其他樣品圖像

Sample image 2

對於此圖像每種顏色成分的rgb值從160到190不等(r,g & b)。請幫我解決問題。

這裏是其他樣品圖像與rgb範圍從110到180 sample image 3

請幫忙。

+10

你不能段按值的CT圖像。它有噪音和CT值會改變。你需要使用一些更好的semiqueation技術,例如水平集 –

+0

@AnderBiguri你能否提供一些細節? –

+0

我會嘗試在圖像的第一個衍生物中找到輪廓,然後通過形態學操作將其放大以確保沒有間隙,然後用填充填充它填充 – Spektre

回答

5

如果不使用固定的閾值,您可以嘗試通過灰度級對圖像進行聚類。作爲一個預處理步驟,我會建議使用形態打開來使相鄰像素的灰度級差異變小,這樣在聚集圖像中噪點就會減少。

下面我使用3x3環形內核對圖像應用兩個連續的形態開口,然後將k-均值聚類應用於灰度級。從您的示例圖片和我在互聯網上找到的一些圖片中,我決定設置k = 4。如果您使用的是高分辨率圖像,請首先將它們縮小到400-600的尺寸。否則,形態操作可能沒有顯着的效果,並且k-均值將會很慢。

下面是一些打開和分割的圖像。當然,還有更多的在分離出肝區

  • 概括這對大型數據集
    • 方面做,但希望這至少是一個起點。

      我沒有matlab,使代碼在c++opencv,但轉換應該是簡單的,因爲它僅涉及形態學和集羣業務,它應該是有點類似this

      更新 您可能能夠通過來自分割圖像過濾出暗與最亮的區域,以縮小區域或利益。爲此,請使用k-means聚類中心,檢查極值(最大值和最小值),並從標記的圖像中移除相應的k值。然後,您可以在結果圖像的左側查找大型結構。最糟糕的情況是,當極端區域過濾出錯時,您可能會在左側出現一個洞。我更新了代碼和結果。

      1 2 4 5 6 7 8 9 10 1112 13 14 15

      OpenCV的C++代碼

      // load image as gray scale 
      Mat im = imread("5.jpg", 0); 
      // morphological opening 
      Mat kernel = getStructuringElement(MORPH_ELLIPSE, Size(3, 3)); 
      Mat morph; 
      morphologyEx(im, morph, CV_MOP_OPEN, kernel, Point(-1, -1), 2); 
      // clustering 
      int k = 4; 
      Mat segment, lbl; 
      vector<float> centers; 
      morph.convertTo(segment, CV_32F); 
      int imsize[] = {segment.rows, segment.cols}; 
      Mat color = segment.reshape(1, segment.rows*segment.cols); 
      kmeans(color, k, lbl, TermCriteria(CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 10, 1.0), k, KMEANS_PP_CENTERS, centers); 
      lbl = lbl.reshape(1, 2, imsize); 
      
      // find argmin and argmax to find extreme gray level regions 
      int minidx = min_element(centers.begin(), centers.end()) - centers.begin(); 
      int maxidx = max_element(centers.begin(), centers.end()) - centers.begin(); 
      // prepare a mask to filter extreme gray level regions 
      Mat mask = (lbl != minidx)^(lbl == maxidx); 
      
      // only for display purposes 
      Mat lbldisp; 
      lbl.convertTo(lbldisp, CV_8U, 255.0/(k-1)); 
      Mat lblColor; 
      applyColorMap(lbldisp, lblColor, COLORMAP_JET); 
      // region of interest 
      Mat roiColor = Mat::zeros(lblColor.size(), CV_8UC3); 
      lblColor.copyTo(roiColor, mask); 
      
      imshow("opened", morph); 
      imshow("segmented", lblColor); 
      imshow("roi", roiColor); 
      waitKey(); 
      
    +0

    我非常想知道任何降價的原因,所以我可以改進我的答案。 – dhanushka

    +1

    我沒有downvote並找到你的答案其實很有趣,但問題完全是堆棧溢出的主題。這不是一個編程問題,而是一個圖像處理研究項目。你的回答肯定指向了正確的方向,但對於題外話的回答一般都很差。 – dasdingonesin

    +2

    @dasdingonesin謝謝。我剛剛發現這個問題很有趣,並想到分享我所嘗試的內容。 :) – dhanushka