6

我無法實現灰度圖像的正確分割:細分的灰度圖像

Image to be segmented

基本事實,即我想分割的樣子,是這樣的:

Ground truth

我最感興趣的是圈內的三個組件。因此,如您所見,我想將頂部圖像分爲三個部分:兩個半圓,以及它們之間的矩形。

我已經嘗試過擴張,侵蝕和重建的各種組合,以及各種聚類算法,包括k-means,isodata和高斯混合物 - 所有這些都取得了不同程度的成功。

任何建議,將不勝感激。

編輯:這是我已經能夠獲得最好的結果。這是使用主動輪廓來分割圓形ROI,然後應用ISODATA聚類得到:

Clusters

有兩個問題與此:

  • 白色滷代右下簇周圍,屬於左上角羣集
  • 圍繞屬於中心羣集的右上角和左下角羣集的灰色暈圈。
+0

它看起來像你有三峯直方圖。查看我在dsp.stackexchange.com上的答案 - > http://dsp.stackexchange.com/questions/3643/image-segmentation-issue-of-different-materials/3650#3650。無論如何,你的問題應該被移到該網站。 –

+0

我試過基於直方圖的分割。這種方法的問題在於,最右側羣集周圍的像素值與最左側羣集的像素最相似,導致最右側羣集周圍出現「暈圈」。 – Richard

+0

你有沒有試過bwboundaries,或者bwlabel?他們可能會爲你工作。但是如果光環效應太大,你可能得不到你想要的結果。儘管如此,通過一些操作和清理之前和之後,你可能會得到你想要的。它也可能有助於使用像[hough circles](http://www.mathworks.com/matlabcentral/fileexchange/26978-hough-transform-for-circles/content/html/circle_houghdemo.html)或其他方法[這一個](http://blogs.mathworks。com/pick/2008/05/23/detected-circles-in-an-image /),以便你知道你的圈子的界限。 – Bill

回答

7

這是首發... 使用circular Hough transform找到圓形部分。爲此,我最初threshold the image locally

im=rgb2gray(imread('Ly7C8.png')); 
imbw = thresholdLocally(im,[2 2]); % thresold localy with a 2x2 window 
% preparing to find the circle 
props = regionprops(imbw,'Area','PixelIdxList','MajorAxisLength','MinorAxisLength'); 
[~,indexOfMax] = max([props.Area]); 
approximateRadius = props(indexOfMax).MajorAxisLength/2; 
radius=round(approximateRadius);%-1:approximateRadius+1); 
%find the circle using Hough trans. 
h = circle_hough(edge(imbw), radius,'same'); 
[~,maxIndex] = max(h(:)); 
[i,j,k] = ind2sub(size(h), maxIndex); 
center.x = j;  center.y = i; 

figure;imagesc(im);imellipse(gca,[center.x-radius center.y-radius 2*radius 2*radius]); 
title('Finding the circle using Hough Trans.'); 

enter image description here

只選擇有什麼圈內:

[y,x] = meshgrid(1:size(im,2),1:size(im,1)); 
z = (x-j).^2+(y-i).^2; 
f = (z<=radius^2); 
im=im.*uint8(f); 

編輯:

找找通過查看啓動閾值圖像分割它的地方直方圖,找到它的第一個局部最大值,並從那裏迭代,直到找到2個單獨的段,使用bwlabel:

p=hist(im(im>0),1:255); 
    p=smooth(p,5); 
    [pks,locs] = findpeaks(p); 

    bw=bwlabel(im>locs(1)); 
    i=0; 
    while numel(unique(bw))<3 
    bw=bwlabel(im>locs(1)+i); 
    i=i+1; 
    end 


imagesc(bw); 

enter image description here

中間部分現在可以通過從圓取出兩個標記的部分來獲得,並且剩下將成爲中央部(+一些的暈)

bw2=(bw<1.*f); 

但一些中值濾波後,我們得到了更多的東西講理

bw2= medfilt2(medfilt2(bw2)); 

和我們一起獲得:

imagesc(bw+3*bw2); 

enter image description here

最後一部分是真正的「快速和骯髒的」,我敢肯定,隨着這些工具,你已經使用過,你會得到更好的結果...

+0

非常好,謝謝你花時間想出這個。然而,結果在很大程度上取決於閾值,在這種情況下是186.例如,值183會顯着扭曲結果。我意識到我沒有在我的問題中指出這一點,但這只是這個問題的一個典型例子。還有許多其他需要類似分割的圖像。因此,我希望能夠提出一種自動化的通用解決方案。也許有一些方法來「猜測」閾值參數。 – Richard

+0

有幾種方法可以做到這一點,請參閱我的編輯快速骯髒的方式來自動設置一個閾值,這是一個不同於我以前的... – bla

1

也可以使用watershed transformation獲得近似結果。這是反相圖像上的分水嶺 - >分水嶺(255-I)下面是一個例子的結果:

enter image description here

另一種簡單的方法是用一個圓盤結構元素進行原圖像上的形態學閉(人們可以執行多尺度關閉粒度測量),然後獲得整個圓。在這個提取之後,圓和組件更容易。

se = strel('disk',3); 
Iclo = imclose(I, se);% This closes open circular cells. 
Ithresh = Iclo>170;% one can locate this threshold automatically by histogram modes (if you know apriori your cell structure.) 
Icircle = bwareaopen(Ithresh, 50); %to remove small noise components in the bg 

enter image description here

Ithresh2 = I>185; % This again needs a simple histogram. 

enter image description here