用于肝脏的Matlab图像分割

swa*_*dhi -1 matlab image image-processing image-segmentation

我正在努力在matlab中分割图像.我的目标是从ct扫描图像中提取肝脏.这是样本图像.

我为这个样本图像提取了肝脏,输出就像这样 样本图像的输出图像.我的实现代码是

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
Run Code Online (Sandbox Code Playgroud)

我的问题是当我改变图像时,肝脏切片的rgb值可能会有所不同.这是其他样本图像

样本图片2.

对于该图像,对于每种颜色成分(r,g和b),rgb值从160变化到190.请帮我解决问题.

这是rgb范围从110到180的其他样本图像 样本图片3.

请帮忙.

dha*_*hka 5

如果不使用固定阈值,您可以尝试按灰度级对图像进行聚类.作为预处理步骤,我建议使用形态学开口来使相邻像素的灰度级差异变小,这样您在聚类图像中的噪声就会减少.

下面我使用3x3圆形内核将两个连续的形态学开口应用于图像,然后将k均值聚类应用于灰度级.从您的样本图像和我在互联网上找到的一些图像,我决定设置k = 4.如果您使用的是高分辨率图像,请首先将它们下采样到尺寸~400-600.否则,形态学操作可能没有显着影响,并且k均值将是缓慢的.

下面是一些打开和分割的图像.当然还有更多要做的事情

  • 分离出肝脏区域
  • 将其推广到大型数据集

但希望这至少是一个起点.

我没有matlab,所以代码在c++opencv,但转换应该很简单,因为它只涉及形态和聚类操作,它应该有点类似于.

更新 您可以通过从分割图像中滤除最暗和最亮的区域来缩小区域或兴趣范围.为此,使用k-means聚类中心,检查极值(最大值和最小值)并从标记图像中删除相应的k值.然后,您可以在结果图像的左侧查找大型结构.最坏的情况是,当极端区域过滤出错时,您可能会在左侧出现一个洞.我已经更新了代码和结果.

1 2 4 五 6 7 8 9 10 11 12 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();
Run Code Online (Sandbox Code Playgroud)

  • 我没有投反对票,并发现你的答案实际上很有趣,但这个问题完全与 Stack Overflow 的主题无关。这不是一个编程问题,而是一个图像处理研究项目。您的回答肯定指向正确的方向,但对偏离主题的问题的回答通常不受欢迎。 (2认同)
  • @dasdingonesin谢谢.我刚发现这个问题很有意思,想到分享我尝试过的东西.:) (2认同)