手寫01矩陣連通域分析


連通域分析其實是一個路徑搜索問題,搜索方式就看聯通的規則(4聯通:上下左右算是聯通,8聯通:上下左右還有四個對角)

01矩陣背景是0,黑色的,有色區域是1,白色的,從圖像的左上角(最外圍的邊要去掉)進行遍歷,將找到的第一個值為1的像素點作為起點,對他進行連通域搜尋,將搜尋到的整個連通域內的像素點標為2(為了避免與本來的顏色1沖突)

繼續搜索像素值為1的點(之前聯通域分析過的已經將像素值改為大於1的值,所以像素值為1的就是還沒有分析過的),直到整個圖像遍歷完成

 

遍歷方法:

找到起點后初始化一個棧,存放連通域的點坐標(pair),將起點的橫縱坐標壓入棧中,連通域的標記值自增(第一個連通域的標記值為2,從2開始,第二個連通域的標記值為3,以此類推)

當棧不為空時,從棧頂取點,讀出他的橫縱坐標,在Label圖中,根據橫縱坐標對連通域進行對應標記值的賦值,然后將該點出棧,同時按照聯通規則,根據坐標找到它的相鄰像素點,看相鄰像素點的值是否為1,如果是1,則是連通域,將這個點入棧(判斷時記得要加上邊界條件,防止點下標溢出,我的代碼偷懶了沒有加,正常要加上 0<=Row<BinaryImg.rows&&0<=Col<BinaryImg.cols)

 

代碼

void SeedFilling(const Mat &BinaryImg, Mat &LabelImg)
{
    if (BinaryImg.empty || BinaryImg.type() != CV_8UC1)
        return;

    BinaryImg.convertTo(LabelImg, CV_32SC1);

    int Label = 1;// 從2開始,防止和二值圖像的像素值重合

    int Row = BinaryImg.rows - 1;
    int Col = BinaryImg.cols - 1;

    for (int i = 1; i < Row; ++i)
    {
        int* data = LabelImg.ptr<int>(i);

        for (int j = 1; j < Col - 1; ++j)
        {
            if (data[j] == 1)
            {
                stack<pair<int, int>> NeighborPixel;
                NeighborPixel.push(pair<int, int>(i, j));

                ++Label;// 新標簽

                while (!NeighborPixel.empty)// 棧不為空
                {
                    pair<int, int> CurPixel = NeighborPixel.top();
                    int CurRow = CurPixel.first;
                    int CurCol = CurPixel.second;
                    LabelImg.at<int>(CurRow, CurCol) = Label;
                    NeighborPixel.pop();// 出棧

                    if (LabelImg.at<int>(CurRow, CurCol - 1) == 1)
                        NeighborPixel.push(pair<int, int>(CurRow, CurCol - 1));

                    if (LabelImg.at<int>(CurRow, CurCol + 1) == 1)
                        NeighborPixel.push(pair<int, int>(CurRow, CurCol + 1));

                    if (LabelImg.at<int>(CurRow - 1, CurCol) == 1)
                        NeighborPixel.push(pair<int, int>(CurRow - 1, CurCol));

                    if (LabelImg.at<int>(CurRow + 1, CurCol) == 1)
                        NeighborPixel.push(pair<int, int>(CurRow + 1, CurCol));
                }
            }
        }

        return;
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM