%%%% ロボットビジョン(5T) sample06_labeling.m  2016/5/8

clear;
Iin = imread('image05.jpg');
I = double(Iin);

% 画像の2値化--------------------------------------------------
threshold = 200;  % 2値化のしきい値
[n,m] = size(I);
Ibin = zeros(n,m); % nxmのゼロ行列（2値化画像の格納先）
for j = 1 : n
    for i = 1 : m
        if I(j,i) > threshold;  % しきい値処理
            Ibin(j,i) = 1;
        end;
    end;
end;

% ラベリング
% 1巡目---------------------------------------------------------
Ilabel = zeros(n,m);
lcount = 0; 
lbuf = zeros(1,4);

for j = 2 : n-1
    for i = 2 : m-1
        if Ibin(j,i) == 1
            % 走査済み４近傍のラベルを取得
            lbuf = [Ilabel(j-1,i-1), Ilabel(j-1,i), Ilabel(j-1,i+1), Ilabel(j,i-1)];
            % 走査済み４近傍の中で，0でないラベルを取得
            clear nzbuf; q=0;
            for p = 1 : 4
                if lbuf(p) ~= 0  % ~= は，not equal
                    q = q + 1;
                    nzbuf(q) = lbuf(p);
                end;
            end;
            
            % 1巡目のラベルを付ける
            if sum(lbuf) == 0 % 近傍にラベルなければ，新しいラベルを付ける
                lcount = lcount + 1;
                Ilabel(j,i) = lcount;
                llut(lcount,1) = lcount;
                llut(lcount,2) = lcount;         
            else
                Ilabel(j,i) = min(nzbuf); % 近傍にラベルあれば，0でないラベルの中で最小のラベルを付ける
                for p = 1 : size(nzbuf,2)
                    if(llut(nzbuf(p),2) > min(nzbuf)) % これまでで最少のラベルに統一するため
                        llut(nzbuf(p),2) = min(nzbuf);
                    end;
                end;                
            end;
        end;
 %       if(j==22 && i==109)
 %           break;
 %       end;
    end;
 %    if(j==22 && i==109)
 %           break;
 %       end;
end;



% 2巡目---------------------------------------------------------
% LUTの整理
lcount = 0; 
for k = 1 : size(llut,1)
    if llut(k,1) == llut(k,2)
        lcount = lcount + 1;
        llut_rev(lcount,1) = llut(k,2);
        llut_rev(lcount,2) = lcount; 
    end;
end;
% 整理したLUTを用いて，ラベルを付け直す
for j = 2 : n-1
    for i = 2 : m-1 
        if Ilabel(j,i) ~= 0
            ldist = Ilabel(j,i); 
            while llut(ldist,1) ~= llut(ldist,2) %整理前のLUT(llut)で同一ラベルを解決
                Ilabel(j,i) = llut(ldist,2);
                ldist = llut(ldist,2);
            end;
            for p = 1 : size(llut_rev,1) %整理後のLUT(llut_rev)でラベルを整理
                if llut_rev(p,1) == Ilabel(j,i)
                    Ilabel(j,i) = llut_rev(p,2);
                end;
            end;
        end;        
    end;
end;



figure(1);
subplot(1,3,1); %画像を1x3並べて表示
imagesc(I); colormap(gray);
subplot(1,3,2);
imagesc(Ibin); colormap(gray);
subplot(1,3,3);
imagesc(Ilabel); colormap(gray);



%%%% EOF