天天看點

Matlab的BwLabel實作

連通區域分析中常需要找出一幅圖像中的連通區域,matlab自帶的Belabel函數即可,在此寫了一個功能相同的函數,友善以後将其移植到其他平台上,用的是Two pass算法

function [ outImg, labels ] = MyBwLabel( inputImg )
%MyBwLabel 自制的連通區域分析函數
%   [ outImg, labels ] = MyBwLabel( inputImg )
%   inputIg: 輸入的圖像,要求是二值化圖像,且最大值為1
%   outputImg: 輸出的圖像,不同的連通區域的;label不同
%   labels:連通區域的個數
%
%   example : a = false(400);
%             a(rand(400) > 0.5) = true;
%             [b , l] = MyBwLabel(a);
%             imshow(b , [])
    if ~islogical(inputImg)
        error( '========do not support the data type!!============' )
    end
    labels = 1;
    outImg = double( inputImg );
    markFlag = false( size(inputImg) );
    [height , width] = size( inputImg );

    %% first pass
    for ii = 1:height
        for jj = 1:width
            if inputImg(ii,jj) > 0  % 若是前景點,則進行統計處理
                neighbors = [];  % 記錄符合要求的鄰域中的前景點,三列依次是行、列、值
                if (ii-1 > 0)
                    if (jj-1 > 0 && inputImg(ii-1,jj-1) > 0)
                        neighbors = [neighbors ; ii-1 , jj-1 , outImg(ii-1,jj-1)];
                    end
                    if inputImg(ii-1,jj) > 0
                        neighbors = [neighbors ; ii-1 , jj , outImg(ii-1,jj)];
                    end
                elseif (jj-1) > 0 && inputImg(ii,jj-1) > 0
                    neighbors = [neighbors ; ii , jj-1 , outImg(ii,jj-1)];
                end

                if isempty(neighbors)
                    labels = labels + 1;
                    outImg(ii , jj) = labels;
                else
                    outImg(ii ,jj) = min(neighbors(:,3));
                end

            end
        end
    end

    %% second pass
    [r , c] = find( outImg ~= 0 );
    for ii = 1:length( r )
        if r(ii)-1 > 0
            up = r(ii)-1;
        else
            up = r(ii);
        end
        if r(ii)+1 <= height
            down = r(ii)+1;
        else
            down = r(ii);
        end
        if c(ii)-1 > 0
            left = c(ii)-1;
        else
            left = c(ii);
        end
        if c(ii)+1 <= width
            right = c(ii)+1;
        else
            right = c(ii);
        end

        tmpM = outImg(up:down , left:right);
        [r1 , c1] = find( tmpM ~= 0 );
        if ~isempty(r1)
            tmpM = tmpM(:);
            tmpM( tmpM == 0 ) = [];

            minV = min(tmpM);
            tmpM( tmpM == minV ) = [];
            for kk = 1:1:length(tmpM)
                outImg( outImg == tmpM(kk) ) = minV;
            end

        end
    end

    u = unique(outImg);
    for ii = 2:1:length(u)
        outImg(outImg == u(ii)) = ii-1;
    end
    labels = length( u ) - 1;
end
           

繼續閱讀