影象的腐蝕與膨脹
阿新 • • 發佈:2018-11-08
影象腐蝕與膨脹
結構元素
設有兩幅圖象B,X。若X是被處理的物件,而B是用來處理X的,則稱B為結構元素(structure element),又被形象地稱做刷子。結構元素通常都是一些比較小的圖象。
腐蝕
把結構元素B平移a後得到Ba,若Ba包含於X,我們記下這個a點,所有滿足上述條件的a點組成的集合稱做X被B腐蝕(Erosion)的結果。如下圖所示。
- 其中X是被處理的物件,B是結構元素。對於任意一個在陰影部分的點a,Ba 包含於X,所以X被B腐蝕的結果就是那個陰影部分。陰影部分在X的範圍之內,且比X小,就象X被剝掉了一層似的。
膨脹
膨脹(dilation)可以看做是腐蝕的對偶運算,其定義是:把結構元素B平移a後得到Ba,若Ba擊中X,我們記下這個a點。所有滿足上述條件的a點組成的集合稱做X被B膨脹的結果。如下圖所示。
其中X是被處理的物件,B是結構元素,不難知道,對於任意一個在陰影部分的點a,Ba擊中X,所以X被B膨脹的結果就是那個陰影部分。陰影部分包括X的所有範圍,就象X膨脹了一圈似的。
接下來請看如下圖:我們就能瞭解其具體工作原理了。
膨脹和腐蝕為相反的一對操作。dilate (膨脹) erode(腐蝕)都是形態學的濾波。
影象的膨脹:
#include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <iostream> using namespace std; using namespace cv; int main( ) { //載入原圖 Mat image = imread("C://1.jpg"); //建立視窗 namedWindow("【原圖】膨脹操作"); namedWindow("【效果圖】膨脹操作"); //顯示原圖 imshow("【原圖】膨脹操作", image); //進行膨脹操作 Mat element = getStructuringElement(MORPH_RECT, Size(15, 15)); Mat out; dilate(image, out, element); //顯示效果圖 imshow("【效果圖】膨脹操作", out); waitKey(0); return 0; }
影象的腐蝕:
程式碼如下:
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace cv;
int main( )
{
//載入原圖
Mat srcImage = imread("C://1.jpg");
//顯示原圖
imshow("【原圖】腐蝕操作", srcImage);
//進行腐蝕操作
Mat element = getStructuringElement(MORPH_RECT, Size(15, 15));
Mat dstImage;
erode(srcImage, dstImage, element);
//顯示效果圖
imshow("【效果圖】腐蝕操作", dstImage);
waitKey(0);
return 0;
}
影象的膨脹和腐蝕的綜合示例:可以改變滑動條視窗改變核心的大小,0代表腐蝕,1代表膨脹。
程式碼如下:
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
using namespace std;
using namespace cv;
//-----------------------------------【全域性變數宣告部分】--------------------------------------
// 描述:全域性變數宣告
//-----------------------------------------------------------------------------------------------
Mat g_srcImage, g_dstImage;//原始圖和效果圖
int g_nTrackbarNumer = 0;//0表示腐蝕erode, 1表示膨脹dilate
int g_nStructElementSize = 3; //結構元素(核心矩陣)的尺寸
//-----------------------------------【全域性函式宣告部分】--------------------------------------
// 描述:全域性函式宣告
//-----------------------------------------------------------------------------------------------
void Process();//膨脹和腐蝕的處理函式
void on_TrackbarNumChange(int, void *);//回撥函式
void on_ElementSizeChange(int, void *);//回撥函式
//-----------------------------------【main( )函式】--------------------------------------------
// 描述:控制檯應用程式的入口函式,我們的程式從這裡開始
//-----------------------------------------------------------------------------------------------
int main( )
{
//載入原圖
g_srcImage = imread("C://1.jpg");
if( !g_srcImage.data ) { printf("讀取srcImage錯誤~! \n"); return false; }
//顯示原始圖
namedWindow("【原始圖】");
imshow("【原始圖】", g_srcImage);
//進行初次腐蝕操作並顯示效果圖
namedWindow("【效果圖】");
//獲取自定義核
Mat element = getStructuringElement(MORPH_RECT, Size(2*g_nStructElementSize+1, 2*g_nStructElementSize+1),Point( g_nStructElementSize, g_nStructElementSize ));
erode(g_srcImage, g_dstImage, element);
imshow("【效果圖】", g_dstImage);
//建立軌跡條
createTrackbar("腐蝕/膨脹", "【效果圖】", &g_nTrackbarNumer, 1, on_TrackbarNumChange);
createTrackbar("核心尺寸", "【效果圖】", &g_nStructElementSize, 21, on_ElementSizeChange);
//輸出一些幫助資訊
cout<<endl<<"\t執行成功,請調整滾動條觀察影象效果~\n\n"
<<"\t按下“q”鍵時,程式退出。\n";
//輪詢獲取按鍵資訊,若下q鍵,程式退出
while(char(waitKey(1)) != 'q') {}
return 0;
}
//-----------------------------【Process( )函式】------------------------------------
// 描述:進行自定義的腐蝕和膨脹操作
//-----------------------------------------------------------------------------------------
void Process()
{
//獲取自定義核
Mat element = getStructuringElement(MORPH_RECT, Size(2*g_nStructElementSize+1, 2*g_nStructElementSize+1),Point( g_nStructElementSize, g_nStructElementSize ));
//進行腐蝕或膨脹操作
if(g_nTrackbarNumer == 0) {
erode(g_srcImage, g_dstImage, element);
}
else {
dilate(g_srcImage, g_dstImage, element);
}
//顯示效果圖
imshow("【效果圖】", g_dstImage);
}
//-----------------------------【on_TrackbarNumChange( )函式】------------------------------------
// 描述:腐蝕和膨脹之間切換開關的回撥函式
//-----------------------------------------------------------------------------------------------------
void on_TrackbarNumChange(int, void *)
{
//腐蝕和膨脹之間效果已經切換,回撥函式體內需呼叫一次Process函式,使改變後的效果立即生效並顯示出來
Process();
}
//-----------------------------【on_ElementSizeChange( )函式】-------------------------------------
// 描述:腐蝕和膨脹操作核心改變時的回撥函式
//-----------------------------------------------------------------------------------------------------
void on_ElementSizeChange(int, void *)
{
//核心尺寸已改變,回撥函式體內需呼叫一次Process函式,使改變後的效果立即生效並顯示出來
Process();
}
結果例項圖: