1. 程式人生 > >opencv學習筆記(十)-影象腐蝕與腐蝕

opencv學習筆記(十)-影象腐蝕與腐蝕

相關概念:

腐蝕:刪除物件邊界某些畫素。

結構元素

設有兩幅圖象B,X。若X是被處理的物件,而B是用來處理X的,則稱B為結構元素(structure element),又被形象地稱做刷子。結構元素通常都是一些比較小的圖象。

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

腐蝕過程介紹:

對二值圖腐蝕過程:

在圖6.10中,左邊是被處理的圖象X(二值圖象,我們針對的是黑點),中間是結構元素B,那個標有origin的點是中心點,即當前處理元素的位置。腐蝕的方法是,拿B的中心點和X上的點一個一個地對比,如果B上的所有點(指的是所有黑點)都在X的範圍內(即X圖上處理元素所在的位置以及它上,左兩個點都是黑色),則該點保留,否則將該點去掉(變為白點);右邊是腐蝕後的結果。可以看出,它仍在原來X的範圍內,且比X包含的點要少,就像X被腐蝕掉了一層。
這裡寫圖片描述

對灰度影象的腐蝕:

如下圖,左邊是要處理影象,中間是結構元素,右邊是與對應每個畫素的灰度值。

處理過程就是:與上面的B一樣,中間是要處理的元素所在的位置,三個1所在的位置對應三個灰度值,然後將中間這個1對應的灰度值改成這三個最小的,如源影象第一個灰度值1,它上左都沒有灰度值,所以最小就是它本身,所以輸出也是1,再比如處理灰度值為22那個點的時候,上面是7左邊是44,所以22應改為7。

這裡寫圖片描述

腐蝕的作用

1,邊緣檢測。
2,噪聲濾除。
3,形態骨架提取。

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

腐蝕例程:

1:從灰度值層面介紹腐蝕


#include "cv.h"
#include "highgui.h"
#include "cxcore.h"

int main()
{
    //建立源影象
    IplImage* src = cvCreateImage(cvSize(11, 10), 8, 1);

    //建立影象  用來儲存輸出後的影象
    IplImage* dat = cvCreateImage(cvSize(11,10), 8, 1);

    //影象清零
    cvSetZero(dat);
    cvSetZero(src);

    //將源影象賦初值
int x, y; //(1,6)-->(1,9) //(2,6)-->(2,9) //(3,6)-->(3,9) for (y = 1; y < 4; y++) { for (x = 6; x < 10; x++) { cvSetReal2D(src, y, x, 255); } } //(4,4)-->(4,7) //(5,4)-->(4,7) for (y = 4; y < 6; y++) { for (x = 4; x < 8; x++) { cvSetReal2D(src, y, x, 255); } } //(6,1)-->(6,7) for (x = 1; x < 8; x++) { cvSetReal2D(src, 6, x, 255); } //(7,1)-->(7,4) //(8,1)-->(8,4) for (y = 7; y < 9; y++) { for (x = 1; x < 5; x++) { cvSetReal2D(src, y, x, 255); } } //輸出源影象 printf("src is :\n"); for (y = 0; y < src->height; y++) { for (x = 0; x < src->width; x++) { float value = cvGetReal2D(src, y, x); printf("%5d", (int)(value)); } printf("\n"); } //建立結構元素變數,並且對其取值 IplConvKernel* element = 0; //結構元素的取值情況 int value[16] = { 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0 }; //宣告結構元素的列數 行數 錨點座標 int clos = 4, rows = 4, anchor_x = 2, anchor_y = 2; element = cvCreateStructuringElementEx(clos, rows, anchor_x, anchor_y, CV_SHAPE_CUSTOM, value); //使用自定義結構元素 對影象進行腐蝕 cvErode(src, dat, element, 1); //輸出腐蝕後的結果 printf("dat is: \n"); for (y = 0; y < dat->height; y++) { for (x = 0; x < dat->width; x++) { float value = cvGetReal2D(dat, y, x); printf("%5d", (int)value); } printf("\n"); } }

效果:
腐蝕前:

這裡寫圖片描述

腐蝕後:

這裡寫圖片描述

2,從影象層面介紹腐蝕:

#include <opencv2/highgui/highgui.hpp> 
#include <opencv2/imgproc/imgproc.hpp>

using namespace cv;

int main()
{
    Mat srcImage = imread("楪析.jpg");
    imshow("【原圖】腐蝕操作", srcImage);

    Mat element = getStructuringElement(MORPH_RECT, Size(5, 5));

    Mat dstImage;

    erode(srcImage, dstImage, element);

    imshow("【效果圖】腐蝕操作", dstImage);

    waitKey(0);
    return 0;
}

腐蝕前:
這裡寫圖片描述

腐蝕後:
這裡寫圖片描述

影象膨脹

影象的膨脹就是影象腐蝕的相反操作,例如: 對灰度圖的處理過程就是:與上面的B一樣,中間是要處理的元素所在的位置,三個1所在的位置對應三個灰度值,然後將中間這個1對應的灰度值改成這三個最的,如第一個灰度值1,它上左都沒有灰度值,所以最大就是它本身,所以輸出也是1,再比如處理灰度值為22那個點的時候,上面是7左邊是44,所以22應改為44。

例程:

#include "cv.h"
#include "highgui.h"
#include "cxcore.h"

void main11()
{
    /*建立兩個單通道影象*/
    IplImage    *src, *dst;

    src = cvCreateImage(cvSize(10, 10), 8, 1);
    dst = cvCreateImage(cvGetSize(src), 8, 1);

    /*影象的取值*/
    unsigned char data[100] = {
        1,  2,  5,  1,  78, 68, 7,  3,  5,  6,
        5,  66, 7,  6,  3,  44, 22, 44, 0,  2,
        9,  77, 3,  5,  6,  2,  4,  57, 9,  4,
        54, 27, 59, 23, 58, 13, 36, 31, 38, 57,
        35, 26, 24, 24, 31, 54, 22, 48, 48, 49,
        27, 14, 26, 33, 68, 87, 57, 61, 19, 72,
        46, 58, 46, 64, 54, 43, 97, 92, 20, 53,
        84, 35, 35, 75, 12, 57, 37, 57, 4,  48,
        57, 14, 67, 97, 56, 33, 37, 46, 58, 59,
        36, 57, 89, 65, 47, 75, 11, 27, 41, 54
    };

    for (int y = 0; y < src->height; y++)
    {
        unsigned char* imageData = (unsigned char *)(src->imageData + y*src->widthStep);
        for (int x = 0; x < src->width; x++)
        {
            imageData[x] = data[y*src->width + x];
        }
    }

    printf("src is \n");
    for (int y = 0; y < src->height; y++)
    {
        for (int x = 0; x < src->width; x++)
        {
            float value = cvGetReal2D(src, x, y);
            printf("%3d  ", (int)(value));
        }
        printf("\n");
    }
    /*宣告結構元素變數*/
    IplConvKernel* element = 0;
    int values[16] = {
                        0,0,0,0,
                        0,0,1,0,
                        0,1,1,0,
                        0,0,0,0
                     };

    /*結構體元素引數*/
    int clos = 4, rows = 4, anchor_x = 2, anchor_y = 2;

    /*建立結構元素*/
    element = cvCreateStructuringElementEx(clos, rows, anchor_x, anchor_y, CV_SHAPE_CUSTOM, values);
    /*膨脹後的結果*/
    cvDilate(src, dst, element, 1);


    printf("dst is \n");
    for (int y = 0; y < src->height; y++)
    {
        for (int x = 0; x < src->width; x++)
        {
            float value = cvGetReal2D(dst, x, y);
            printf("%3d  ", (int)(value));
        }
        printf("\n");
    }
    /*釋放影象記憶體*/
    src = NULL;
    dst = NULL;
    system("pause");
}

效果如圖:
這裡寫圖片描述