opencv 4 圖像處理(2 形態學濾波:腐蝕與膨脹,開運算、閉運算、形態學梯度、頂帽、黑帽)

##腐蝕與膨脹 ###膨脹(求局部最大值)(dilate函數) ios

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

//-----------------------------------【命名空間聲明部分】---------------------------------------
//	描述:包含程序所使用的命名空間
//-----------------------------------------------------------------------------------------------  
using namespace std;
using namespace cv;

//-----------------------------------【main( )函數】--------------------------------------------
//	描述:控制檯應用程序的入口函數,咱們的程序從這裏開始
//-----------------------------------------------------------------------------------------------
int main()
{

	//載入原圖  
	Mat image = imread("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;
}

###腐蝕(求局部最小值)(erode) 函數

#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace cv;

//-----------------------------------【main( )函數】--------------------------------------------
//	描述:控制檯應用程序的入口函數,咱們的程序從這裏開始
//-----------------------------------------------------------------------------------------------
int main()
{
	//載入原圖  
	Mat srcImage = imread("1.jpg");
	//顯示原圖
	imshow("【原圖】腐蝕操做", srcImage);
	//進行腐蝕操做 
	Mat element = getStructuringElement(MORPH_RECT, Size(15, 15));
	Mat dstImage;
	erode(srcImage, dstImage, element);
	//顯示效果圖 
	imshow("【效果圖】腐蝕操做", dstImage);
	waitKey(0);

	return 0;
}

###腐蝕與膨脹滑動條實例字體

#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 *);//回調函數
void ShowHelpText();

//-----------------------------------【main( )函數】--------------------------------------------
//		描述:控制檯應用程序的入口函數,咱們的程序從這裏開始
//-----------------------------------------------------------------------------------------------
int main()
{
	//改變console字體顏色
	system("color 2F");

	//載入原圖
	g_srcImage = imread("1.jpg");
	if (!g_srcImage.data) { printf("讀取srcImage錯誤~! \n"); return false; }

	ShowHelpText();

	//顯示原始圖
	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();
}


//-----------------------------------【ShowHelpText( )函數】-----------------------------
//		 描述:輸出一些幫助信息
//----------------------------------------------------------------------------------------------
void ShowHelpText()
{
	//輸出歡迎信息和OpenCV版本
	
	printf("\n\n\t\t\t   當前使用的OpenCV版本爲:" CV_VERSION);
	printf("\n\n  ----------------------------------------------------------------------------\n");
}

##開運算、閉運算、形態學梯度、頂帽、黑帽(morphologyEx函數) ui

###開運算(先腐蝕後膨脹) spa

###閉運算(先膨脹後腐蝕) 3d

###形態學梯度(膨脹圖與腐蝕圖之差) code

###頂帽(原圖像與開運算之差) blog

###黑帽(閉運算與原圖像之差) ###核心API函數(morphologyEx函數) ###範例ip

#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace cv;


//-----------------------------------【main( )函數】------------------------------------------
//		描述:控制檯應用程序的入口函數,咱們的程序從這裏開始
//-----------------------------------------------------------------------------------------------
int main( )
{
	//載入原始圖   
	Mat image = imread("1.jpg");  //工程目錄下應該有一張名爲1.jpg的素材圖
	//建立窗口   
	namedWindow("【原始圖】形態學梯度");  
	namedWindow("【效果圖】形態學梯度");  
	//顯示原始圖  
	imshow("【原始圖】形態學梯度", image);  
	//定義核
	Mat element = getStructuringElement(MORPH_RECT, Size(15, 15));  
	//進行形態學操做
	morphologyEx(image, image, MORPH_GRADIENT, element);
	//顯示效果圖  
	imshow("【效果圖】形態學梯度", image);  

	waitKey(0);  

	return 0;  
}

###綜合實例element

#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace std;
using namespace cv;


//-----------------------------------【全局變量聲明部分】-----------------------------------
//		描述:全局變量聲明
//-----------------------------------------------------------------------------------------------
Mat g_srcImage, g_dstImage;//原始圖和效果圖
int g_nElementShape = MORPH_RECT;//元素結構的形狀

//變量接收的TrackBar位置參數
int g_nMaxIterationNum = 10;
int g_nOpenCloseNum = 0;
int g_nErodeDilateNum = 0;
int g_nTopBlackHatNum = 0;



//-----------------------------------【全局函數聲明部分】--------------------------------------
//		描述:全局函數聲明
//-----------------------------------------------------------------------------------------------
static void on_OpenClose(int, void*);//回調函數
static void on_ErodeDilate(int, void*);//回調函數
static void on_TopBlackHat(int, void*);//回調函數
static void ShowHelpText();


//-----------------------------------【main( )函數】--------------------------------------------
//		描述:控制檯應用程序的入口函數,咱們的程序從這裏開始
//-----------------------------------------------------------------------------------------------
int main()
{
	//改變console字體顏色
	system("color 2F");

	ShowHelpText();

	//載入原圖
	g_srcImage = imread("1.jpg");
	if (!g_srcImage.data) { printf("Oh,no,讀取srcImage錯誤~! \n"); return false; }

	//顯示原始圖
	namedWindow("【原始圖】");
	imshow("【原始圖】", g_srcImage);

	//建立三個窗口
	namedWindow("【開運算/閉運算】", 1);
	namedWindow("【腐蝕/膨脹】", 1);
	namedWindow("【頂帽/黑帽】", 1);

	//參數賦值
	g_nOpenCloseNum = 9;
	g_nErodeDilateNum = 9;
	g_nTopBlackHatNum = 2;

	//分別爲三個窗口建立滾動條
	createTrackbar("迭代值", "【開運算/閉運算】", &g_nOpenCloseNum, g_nMaxIterationNum * 2 + 1, on_OpenClose);
	createTrackbar("迭代值", "【腐蝕/膨脹】", &g_nErodeDilateNum, g_nMaxIterationNum * 2 + 1, on_ErodeDilate);
	createTrackbar("迭代值", "【頂帽/黑帽】", &g_nTopBlackHatNum, g_nMaxIterationNum * 2 + 1, on_TopBlackHat);

	//輪詢獲取按鍵信息
	while (1)
	{
		int c;

		//執行回調函數
		on_OpenClose(g_nOpenCloseNum, 0);
		on_ErodeDilate(g_nErodeDilateNum, 0);
		on_TopBlackHat(g_nTopBlackHatNum, 0);

		//獲取按鍵
		c = waitKey(0);

		//按下鍵盤按鍵Q或者ESC,程序退出
		if ((char)c == 'q' || (char)c == 27)
			break;
		//按下鍵盤按鍵1,使用橢圓(Elliptic)結構元素結構元素MORPH_ELLIPSE
		if ((char)c == 49)//鍵盤按鍵1的ASII碼爲49
			g_nElementShape = MORPH_ELLIPSE;
		//按下鍵盤按鍵2,使用矩形(Rectangle)結構元素MORPH_RECT
		else if ((char)c == 50)//鍵盤按鍵2的ASII碼爲50
			g_nElementShape = MORPH_RECT;
		//按下鍵盤按鍵3,使用十字形(Cross-shaped)結構元素MORPH_CROSS
		else if ((char)c == 51)//鍵盤按鍵3的ASII碼爲51
			g_nElementShape = MORPH_CROSS;
		//按下鍵盤按鍵space,在矩形、橢圓、十字形結構元素中循環
		else if ((char)c == ' ')
			g_nElementShape = (g_nElementShape + 1) % 3;
	}

	return 0;
}


//-----------------------------------【on_OpenClose( )函數】----------------------------------
//		描述:【開運算/閉運算】窗口的回調函數
//-----------------------------------------------------------------------------------------------
static void on_OpenClose(int, void*)
{
	//偏移量的定義
	int offset = g_nOpenCloseNum - g_nMaxIterationNum;//偏移量
	int Absolute_offset = offset > 0 ? offset : -offset;//偏移量絕對值
	//自定義核
	Mat element = getStructuringElement(g_nElementShape, Size(Absolute_offset * 2 + 1, Absolute_offset * 2 + 1), Point(Absolute_offset, Absolute_offset));
	//進行操做
	if (offset < 0)
		//此句代碼的OpenCV2版爲:
		//morphologyEx(g_srcImage, g_dstImage, CV_MOP_OPEN, element);
		//此句代碼的OpenCV3版爲:
		morphologyEx(g_srcImage, g_dstImage, MORPH_OPEN, element);
	else
		//此句代碼的OpenCV2版爲:
		//morphologyEx(g_srcImage, g_dstImage, CV_MOP_CLOSE, element);
		//此句代碼的OpenCV3版爲:
		morphologyEx(g_srcImage, g_dstImage, MORPH_CLOSE, element);



	//顯示圖像
	imshow("【開運算/閉運算】", g_dstImage);
}


//-----------------------------------【on_ErodeDilate( )函數】----------------------------------
//		描述:【腐蝕/膨脹】窗口的回調函數
//-----------------------------------------------------------------------------------------------
static void on_ErodeDilate(int, void*)
{
	//偏移量的定義
	int offset = g_nErodeDilateNum - g_nMaxIterationNum;	//偏移量
	int Absolute_offset = offset > 0 ? offset : -offset;//偏移量絕對值
	//自定義核
	Mat element = getStructuringElement(g_nElementShape, Size(Absolute_offset * 2 + 1, Absolute_offset * 2 + 1), Point(Absolute_offset, Absolute_offset));
	//進行操做
	if (offset < 0)
		erode(g_srcImage, g_dstImage, element);
	else
		dilate(g_srcImage, g_dstImage, element);
	//顯示圖像
	imshow("【腐蝕/膨脹】", g_dstImage);
}


//-----------------------------------【on_TopBlackHat( )函數】--------------------------------
//		描述:【頂帽運算/黑帽運算】窗口的回調函數
//----------------------------------------------------------------------------------------------
static void on_TopBlackHat(int, void*)
{
	//偏移量的定義
	int offset = g_nTopBlackHatNum - g_nMaxIterationNum;//偏移量
	int Absolute_offset = offset > 0 ? offset : -offset;//偏移量絕對值
	//自定義核
	Mat element = getStructuringElement(g_nElementShape, Size(Absolute_offset * 2 + 1, Absolute_offset * 2 + 1), Point(Absolute_offset, Absolute_offset));
	//進行操做
	if (offset < 0)
		morphologyEx(g_srcImage, g_dstImage, MORPH_TOPHAT, element);
	else
		morphologyEx(g_srcImage, g_dstImage, MORPH_BLACKHAT, element);
	//顯示圖像
	imshow("【頂帽/黑帽】", g_dstImage);
}

//-----------------------------------【ShowHelpText( )函數】----------------------------------
//		描述:輸出一些幫助信息
//----------------------------------------------------------------------------------------------
static void ShowHelpText()
{
	//輸出歡迎信息和OpenCV版本
	
	printf("\n\n\t\t\t   當前使用的OpenCV版本爲:" CV_VERSION);
	printf("\n\n  ----------------------------------------------------------------------------\n");

	//輸出一些幫助信息
	printf("\n\t請調整滾動條觀察圖像效果\n\n");
	printf("\n\t按鍵操做說明: \n\n"
		"\t\t鍵盤按鍵【ESC】或者【Q】- 退出程序\n"
		"\t\t鍵盤按鍵【1】- 使用橢圓(Elliptic)結構元素\n"
		"\t\t鍵盤按鍵【2】- 使用矩形(Rectangle )結構元素\n"
		"\t\t鍵盤按鍵【3】- 使用十字型(Cross-shaped)結構元素\n"
		"\t\t鍵盤按鍵【空格SPACE】- 在矩形、橢圓、十字形結構元素中循環\n");
}
相關文章
相關標籤/搜索