エッジ検出とモルフォロジーを使用した細胞の検出
この例では、エッジ検出と基本的なモルフォロジーを使用して細胞を検出する方法を示します。オブジェクトは、背景と十分なコントラストがある場合、イメージ内で簡単に検出されます。
手順 1: イメージの読み取り
cell.tif
イメージを読み取ります。これは前立腺癌細胞のイメージです。このイメージには 2 つの細胞がありますが、1 つの細胞だけ全体が表示されています。目標は、完全に表示されている細胞を検出、すなわちセグメント化することです。
I = imread('cell.tif'); imshow(I) title('Original Image'); text(size(I,2),size(I,1)+15, ... 'Image courtesy of Alan Partin', ... 'FontSize',7,'HorizontalAlignment','right'); text(size(I,2),size(I,1)+25, .... 'Johns Hopkins University', ... 'FontSize',7,'HorizontalAlignment','right');
手順 2: 細胞全体の検出
セグメント化するオブジェクトは、コントラストが背景のイメージと大きく異なります。コントラストの変化は、イメージ勾配を計算する演算子によって検出できます。セグメント化された細胞を含んでいるバイナリ マスクを作成するには、イメージ勾配を計算し、しきい値を適用します。
edge
とソーベル演算子を使用してしきい値を計算します。しきい値を調整し再度 edge
を使用して、セグメント化された細胞を含んでいるバイナリ マスクを取得します。
[~,threshold] = edge(I,'sobel'); fudgeFactor = 0.5; BWs = edge(I,'sobel',threshold * fudgeFactor);
結果のバイナリ勾配マスクを表示します。
imshow(BWs)
title('Binary Gradient Mask')
手順 3: イメージの膨張
バイナリの勾配マスクでは、イメージに高いコントラストの線が示されます。これらの線は、対象オブジェクトの輪郭を正確には表しません。元のイメージと比べて、勾配マスクのオブジェクトの周囲の線にはギャップがあります。これらの線のギャップは、線形構造化要素を使用してソーベル イメージを膨張させると見えなくなります。関数 strel
を使用して、2 つの垂直な線形構造化要素を作成します。
se90 = strel('line',3,90); se0 = strel('line',3,0);
縦方向の構造化要素を使用し、次に横方向の構造化要素を使用して、バイナリ勾配マスクを膨張します。関数 imdilate
はイメージを膨張します。
BWsdil = imdilate(BWs,[se90 se0]);
imshow(BWsdil)
title('Dilated Gradient Mask')
手順 4: 内部ギャップの塗りつぶし
膨張した勾配マスクでは細胞の輪郭がよく見えますが、細胞の内部にはまだ穴があります。これらの穴を塗りつぶすために、関数 imfill
を使用します。
BWdfill = imfill(BWsdil,'holes'); imshow(BWdfill) title('Binary Image with Filled Holes')
手順 5: 境界に接触するオブジェクトの削除
対象細胞は適切にセグメント化されましたが、検出されたのはこのオブジェクトのみではありません。イメージの境界に接触するオブジェクトは、関数 imclearborder
を使用して削除できます。斜め方向の接触部分を削除するには、関数 imclearborder
の連結性を 4
に設定します。
BWnobord = imclearborder(BWdfill,4);
imshow(BWnobord)
title('Cleared Border Image')
手順 6: オブジェクトの平滑化
最後に、セグメント化されたオブジェクトが自然に見えるように、ダイヤモンド構造化要素でイメージを 2 回収縮してオブジェクトを平滑にします。関数 strel
を使用してダイヤモンド構造化要素を作成します。
seD = strel('diamond',1); BWfinal = imerode(BWnobord,seD); BWfinal = imerode(BWfinal,seD); imshow(BWfinal) title('Segmented Image');
手順 7: セグメンテーションの可視化
関数 labeloverlay
を使用して、マスクを元のイメージの上に重ねて表示することができます。
imshow(labeloverlay(I,BWfinal))
title('Mask Over Original Image')
セグメント化したオブジェクトを表示する別の方法は、セグメント化された細胞の周りに輪郭を描くことです。関数 bwperim
を使用して輪郭を描きます。
BWoutline = bwperim(BWfinal);
Segout = I;
Segout(BWoutline) = 255;
imshow(Segout)
title('Outlined Original Image')
参考
imfill
| imclearborder
| edge
| imdilate
| imerode
| bwperim
| strel