2016-12-14 322 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