背景
スカイツリーの写真を使って画像のセグメンテーションを行い,建物部分だけを抜き出します.
使用環境: MATLAB R2016b
使用したツールボックス: Image Processing Toolbox, Statistics and Machine Learning Toolbox
画像の表示
imread で画像を読み込みます.サイズが大きいので,imresize で0.2倍にしています.
img = 'skytree.jpg';
J = imread(img);
I = imresize(J, 0.2);
figure
imshow(I)
スーパーピクセルを用いた画像の分割
画像を,画素単位ではなく輝度や色が似ている領域単位に処理するスーパーピクセルに変換します.Lab* 色空間に変換した場合は,superpixels 関数のプロパティ IsInputLab を true に設定します.ここではスーパーピクセルの数を 1000 に設定しています。
Ilab = rgb2lab(I);
[Ls, N] = superpixels(Ilab, 1000, 'IsInputLab', true);
Bmask = boundarymask(Ls); % セグメンテーションの領域境界を検出
I1 = imoverlay(I, Bmask,'c'); % スーパーピクセルを画像に重ね書き
figure;
imshow(I1);
スーパーピクセルごとの平均値を算出
N 個のそれぞれのスーパーピクセルに対して,L*, a*, b* の平均値を計算し,imshowpair で,元画像とスーパーピクセルごとに平均を取った画像を表示します.
pixIdxList = label2idx(Ls); % 各ラベル領域の行列インデックスを取得
sz = numel(Ls); % 画素数
superLab = zeros(N,3);
for i = 1:N
superLab(i,1) = mean(Ilab(pixIdxList{i} )); % L* mean
superLab(i,2) = mean(Ilab(pixIdxList{i}+ sz)); % a* mean
superLab(i,3) = mean(Ilab(pixIdxList{i}+ 2*sz)); % b* mean
end
I2 = label2rgb(Ls, lab2rgb(superLab));
figure;
imshowpair(I, imoverlay(I2, boundarymask(Ls),'w'), 'montage');
K-meansで色の類似度を用いたクラスタリング
今回はクラス数を2に設定します.クラスタリングは kmeans を使用します.
numColors = 2;
[idx, cLab] = kmeans(superLab, numColors);
Lc = zeros(size(Ls));
for i = 1:N
Lc(pixIdxList{i}) = idx(i);
end
I3 = label2rgb(Lc, lab2rgb(cLab));
I3b = imoverlay(I3, boundarymask(Lc), 'm');
figure;
imshow(I3b);
建物の部分のみを抽出
ほら建物だけ取れた.
宮殿みたいになってしまいました.
maskA = (Lc == 1);
maskA_filled = imfill(maskA, 'holes'); % マスクの穴を埋める
Iout = imoverlay(I, maskA_filled, 'w');
figure;
imshowpair(I, Iout);