1. 程式人生 > >影象的腐蝕與膨脹

影象的腐蝕與膨脹

影象腐蝕與膨脹

  • 結構元素

  • 設有兩幅圖象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();
}

結果例項圖:
在這裡插入圖片描述

在這裡插入圖片描述