圖像腐蝕和膨脹

目標:

         在這個教程中你將學會:

         應用兩個最常用的形態學操作:膨脹和腐蝕。爲了這個目的,你將使用下面的OpenCV函數:
         erode()

         Dilate()

形態學操作:

         簡要的說:就是一系列基於形狀的處理圖像的操作。形態學操作對輸入圖像應用一個結構元素並且產生輸出圖像。

         最基本的形態學操作是:膨脹和腐蝕。他們有很廣泛的應用,例如:

         取出噪音;

         分離單個的元素並且把分開的元素在一幅圖像中聯通;

         找出一幅圖像的碰撞或者孔洞。

我們將使用下面這幅圖像來簡要地解釋一下膨脹和腐蝕:

                                                           

腐蝕:

         這個操作是以B爲覈對圖像A進行卷積處理,這個核可以有任意的形狀和尺寸,通常是一個方形或圓形。

         核B有一個錨點,通常是核的中心;

         當核B對圖像進行掃描的時候,我們計算被B所掩蓋的像素的最大值,並且在錨點用最大值取代圖像的像素值。正如你所推斷,這種最大化操作導致圖像中亮的區域增多(因此也叫作腐蝕)。以上述圖像爲例,對其應用腐蝕操作我們可以得到:

                                                             

背景(亮)腐蝕字母的黑色區域。

膨脹:

         這個操作時腐蝕的姊妹操作。這個操作所做的就是去計算被核所掩蓋的像素的最小值。

         當核B在掃描圖像的時候,我們計算被核所掩蓋的圖像像素的最小值,並且在錨點用這個最小值去替換該像素值。

         和腐蝕的例子相似,我們可以將膨脹操作應用到上述的圖像中。你可以在下面的結果中看到圖像的亮區域(背景),變得更窄了,然而字母的黑色區域變得更大了。

                                                             

代碼:

#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "highgui.h"
#include <stdlib.h>
#include <stdio.h>

using namespace cv;

/// Global variables
Mat src, erosion_dst, dilation_dst;

int erosion_elem = 0;
int erosion_size = 0;
int dilation_elem = 0;
int dilation_size = 0;
int const max_elem = 2;
int const max_kernel_size = 21;

/** Function Headers */
void Erosion(int, void*);
void Dilation(int, void*);

/** @function main */
int main(int argc, char** argv)
{
	/// Load an image
	src = imread("F:/Photo/OpenCV_Photo/lena.jpg");

	if (!src.data)
	{
		return -1;
	}

	/// Create windows
	namedWindow("Erosion Demo", CV_WINDOW_AUTOSIZE);
	namedWindow("Dilation Demo", CV_WINDOW_AUTOSIZE);
	cvMoveWindow("Dilation Demo", src.cols, 0);

	/// Create Erosion Trackbar
	createTrackbar("Element:\n 0: Rect \n 1: Cross \n 2: Ellipse", "Erosion Demo",
		&erosion_elem, max_elem,
		Erosion);

	createTrackbar("Kernel size:\n 2n +1", "Erosion Demo",
		&erosion_size, max_kernel_size,
		Erosion);

	/// Create Dilation Trackbar
	createTrackbar("Element:\n 0: Rect \n 1: Cross \n 2: Ellipse", "Dilation Demo",
		&dilation_elem, max_elem,
		Dilation);

	createTrackbar("Kernel size:\n 2n +1", "Dilation Demo",
		&dilation_size, max_kernel_size,
		Dilation);

	/// Default start
	Erosion(0, 0);
	Dilation(0, 0);

	waitKey(0);
	return 0;
}

/**  @function Erosion  */
void Erosion(int, void*)
{
	int erosion_type;
	if (erosion_elem == 0){ erosion_type = MORPH_RECT; }
	else if (erosion_elem == 1){ erosion_type = MORPH_CROSS; }
	else if (erosion_elem == 2) { erosion_type = MORPH_ELLIPSE; }

	Mat element = getStructuringElement(erosion_type,
		Size(2 * erosion_size + 1, 2 * erosion_size + 1),
		Point(erosion_size, erosion_size));

	/// Apply the erosion operation
	erode(src, erosion_dst, element);
	imshow("Erosion Demo", erosion_dst);
}

/** @function Dilation */
void Dilation(int, void*)
{
	int dilation_type;
	if (dilation_elem == 0){ dilation_type = MORPH_RECT; }
	else if (dilation_elem == 1){ dilation_type = MORPH_CROSS; }
	else if (dilation_elem == 2) { dilation_type = MORPH_ELLIPSE; }

	Mat element = getStructuringElement(dilation_type,
		Size(2 * dilation_size + 1, 2 * dilation_size + 1),
		Point(dilation_size, dilation_size));
	/// Apply the dilation operation
	dilate(src, dilation_dst, element);
	imshow("Dilation Demo", dilation_dst);
}

解釋:

1、  大多數的代碼以應該都知道了,下面讓我們來檢查這個程序的大概結構:

首先載入一幅圖像

創建兩個窗口;

         爲每一個操作創建一個滑動條;

         每次你移動滑動條,用戶函數就會響應,然後更新窗口中顯示的圖像;

         下面讓我們來分析這兩個函數:

2、  膨脹:
erode( src, erosion_dst, element );

從上面我們可以看到,膨脹操作erode函數結構三個參數。其中element是我們要進行膨脹操作的核。如果我們沒有指定,那麼默認的核是一個3X3的矩陣,我們也可以自己指定核。爲了我們自己來定義核,我們使用了下面的函數:OpenCV提供了一個函數getStructuringElement,可以獲取常用的結構元素的形狀:矩形(包括線形)、橢圓(包括圓形)及十字形:MORPH_RECT, MORPH_ELLIPSE, MORPH_CROSS

Matelement = getStructuringElement( erosion_type,

                                     Size(2*erosion_size + 1, 2*erosion_size+1 ),

                                     Point( erosion_size,erosion_size ) );

然後我們只需要指定我們核的大小以及錨點。如果沒有指定,那麼它就假設在覈的中心。

         有了上述這些,我們已經可以去對我們的圖像做膨脹操作了。

注意:還有另外一個參數允許你一次性做多次膨脹操作,在這個簡單的例子中,就不介紹了,請查看相關資料獲得更多詳細的介紹。

3、  腐蝕:

腐蝕操作從上面的代碼中可以看出,它的實現過程和膨脹的過程非常相似。這裏就不多做介紹了。



發佈了50 篇原創文章 · 獲贊 86 · 訪問量 20萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章