圖像二值形態學——腐蝕和膨脹的C語言實現


數學形態學是法國和德國科學家在研究岩石結構時建立的一門科學。形態學的用途主要是獲取物體拓撲和結構信息,通過物體和結構元素相互作用的某些運算,得到物體更本質的形態。在圖像處理中的應用主要是:利用形態學的基本運算,對圖像進行觀察和處理,從而達到改善圖像質量的目的;描述和定義圖像的各種幾何參數和特征,如面積、周長、連通度、顆粒度、骨架和方向性等。

關於形態學的具體描述和數學形式化的定義可以從文章底部的參考資料中獲得。

最近的實驗中需要對二值圖像進行減噪處理,圖像形態學中的腐蝕和膨脹能很好的解決此問題。如果在腐蝕和膨脹操作前,對灰度圖像做一次濾波,減噪效果將更明顯。

腐蝕的具體操作是:用一個結構元素(一般是3×3的大小)掃描圖像中的每一個像素,用結構元素中的每一個像素與其覆蓋的像素做“與”操作,如果都為1,則該像素為1,否則為0。

膨脹的具體操作是:用一個結構元素(一般是3×3的大小)掃描圖像中的每一個像素,用結構元素中的每一個像素與其覆蓋的像素做“與”操作,如果都為0,則該像素為0,否則為1。

腐蝕的作用是消除物體邊界點,使目標縮小,可以消除小於結構元素的噪聲點;膨脹的作用是將與物體接觸的所有背景點合並到物體中,使目標增大,可添補目標中的空洞。

開運算是先腐蝕后膨脹的過程,可以消除圖像上細小的噪聲,並平滑物體邊界。

閉運算時先膨脹后腐蝕的過程,可以填充物體內細小的空洞,並平滑物體邊界。

以下是一段在OpenCV中實現的C語言程序,分別是圖像腐蝕和膨脹函數,輸入的參數依次為:當前二值圖像數據指針、圖像寬度、圖像高度。通過這兩個函數的組合使用(開閉運算),可以對圖像進行有效減噪。

//腐蝕運算
void erosion(uchar* data, int width, int height)
{
    int i, j, index, sum, flag; 
    sum = height * width * sizeof(uchar);
    uchar *tmpdata = (uchar*)malloc(sum);
    memcpy((char*)tmpdata, (char*)data, sum);
    for(i = 1;i < height - 1;i++)
    {
        for(j = 1;j < width - 1;j++)
        {
            flag = 1;
            for(int m = i - 1;m < i + 2;m++)
            {
                for(int n = j - 1; n < j + 2;n++)
                {
                    //自身及領域中若有一個為0
                    //則將該點設為0
                    if(tmpdata[i * width + j] == 0
                        || tmpdata[m * width + n] == 0)
                    {
                        flag = 0;
                        break;
                    }
                }
                if(flag == 0)
                {
                    break;
                }
            }
            if(flag == 0)
            {
                data[i * width + j] = 0;
            }
            else
            {
                data[i * width + j] = 255;
            }
        }
    }
    free(tmpdata);
}

//膨脹運算
void dilation(uchar* data, int width, int height)
{
    int i, j, index, sum, flag;
    sum = height * width * sizeof(uchar);
    uchar *tmpdata = (uchar*)malloc(sum);
    memcpy((char*)tmpdata, (char*)data, sum);
    for(i = 1;i < height - 1;i++)
    {
        for(j = 1;j < width - 1;j++)
        {
            flag = 1;
            for(int m = i - 1;m < i + 2;m++)
            {
                for(int n = j - 1; n < j + 2;n++)
                {
                    //自身及領域中若有一個為255
                    //則將該點設為255
                    if(tmpdata[i * width + j] == 255
                        || tmpdata[m * width + n] == 255)
                    {
                        flag = 0;
                        break;
                    }
                }
                if(flag == 0)
                {
                    break;
                }
            }
            if(flag == 0)
            {
                data[i * width + j] = 255;
            }
            else
            {
                data[i * width + j] = 0;
            }
        }
    }
    free(tmpdata);
}

注意到腐蝕和膨脹是一個對偶運算,故以上兩個函數可以精簡成一個函數,並且這樣的對偶特性在硬件上也是便於實現的。

Resources & Reference:
1、http://www.docin.com/p-8583366.html

--End--

作者: Steven Wang | 可以轉載, 轉載時務必以超鏈接形式標明文章原始出處和作者信息及 版權聲明


免責聲明!

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



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