1. 程式人生 > >opencv--膨脹和腐化

opencv--膨脹和腐化

形態學

形態學(morphology)常應用在生物學中,研究動植物的形態和結構;

影象形態學即數學形態學(Mathematical morphology)是一門建立在格倫和拓撲學基礎上的影象分析學科,是數學形態學影象處理的基本理論;

常見影象形態學運算:腐蝕、膨脹、開運算、閉運算、骨架抽取、極線腐蝕、擊中擊不中變換、Top-hat變換、顆粒分析、流域變換、形態學梯度等;

最基本的形態學操作是:膨脹(dilation)和腐蝕(erosion);

  • 膨脹操作會擴大(粗化)影象中物體的輪廓,可以用來彌補(填充)物體間的孔洞,強化離散點,代價是導致物體的面積比原來的面積要大。
  • 腐蝕操作會收縮(細化)影象中物體的輪廓,可以用來斷開(分離)物體間的連線,消除離散點,代價是導致物體的面積比原來的面積要小。
    在這裡插入圖片描述

膨脹和腐蝕

腐蝕和膨脹是對白色部分(高亮部分)而言的,不是黑色部分。膨脹就是影象中的高亮部分進行膨脹,“領域擴張”,效果圖擁有比原圖更大的高亮區域。腐蝕就是原圖中的高亮部分被腐蝕,“領域被蠶食”,效果圖擁有比原圖更小的高亮區域。

這些形態學操作都涉及到一個關鍵的因子——結構元。結構元基本的形態是矩形、十字形或橢圓形(圓形)。

結構元素就相當於我們在濾波中所涉及到的模板,也就是說它是一個給定畫素的矩陣,這個矩陣可以是任意形狀的,但是一般情況下都是正方形,圓形或者菱形的但是在結構元素中有一箇中心點(也叫做anchor point)。和模板中心一樣,處理後的結果賦值給和這個中心點對齊的畫素點。處理的過程也是基本相同。
結構元素和卷積模板的區別在於,

膨脹是以集合運算為基礎的,卷積是以算數運算為基礎的。

膨脹原理:

膨脹:求區域性最大值;
①定義一個卷積核B,
核可以是任何的形狀和大小,且擁有一個單獨定義出來的參考點-錨點(anchorpoint);
通常和為帶參考點的正方形或者圓盤,可將核稱為模板或掩膜;
②將核B與影象A進行卷積,計算核B覆蓋區域的畫素點最大值;

  1. 用結構元素,掃描影象的每一個畫素
  2. 用結構元素與其覆蓋的二值影象做“與”操作
  3. 如果都為0,結果影象的該畫素為0。否則為1

③將這個最大值賦值給參考點指定的畫素;
因此,影象中的高亮區域逐漸增長。
在這裡插入圖片描述

腐蝕

腐蝕:區域性最小值(與膨脹相反);
①定義一個卷積核B,
核可以是任何的形狀和大小,且擁有一個單獨定義出來的參考點-錨點(anchorpoint);
通常和為帶參考點的正方形或者圓盤,可將核稱為模板或掩膜;
②將核B與影象A進行卷積,計算核B覆蓋區域的畫素點最小值;

  1. 用結構元素,掃描影象的每一個畫素
  2. 用結構元素與其覆蓋的二值影象做“與”操作
  3. 如果都為1,結果影象的該畫素為1。否則為0

③將這個最小值賦值給參考點指定的畫素;
因此,影象中的高亮區域逐漸減小。
在這裡插入圖片描述

膨脹和腐蝕的主要用途:

  • 消除噪聲;
  • 分割出獨立的影象元素,在影象中連線相鄰的元素;
  • 尋找影象中明顯的極大值或極小值區;
  • 求出影象的梯度;

【注】:
腐蝕和膨脹是對畫素值大的部分而言的,即高亮白部分而不是黑色部分;
膨脹是影象中的高亮部分進行膨脹,領域擴張,效果圖擁有比原圖更大的高亮區域;
腐蝕是影象中的高亮部分被腐蝕掉,領域縮減,效果圖擁有比原圖更小的高亮區域;

opencv中API

在這裡插入圖片描述

  • 卷積核
    關於核,一般配合==getStructuringElement()==使用;
    1. 功能:返回指定形狀和尺寸的結構元素;
    2. 格式:
      getStructuringElement(int shape, Size ksize, Point anchor=Point(-1,-1));
    3. 引數:
      shape:表核的形狀,矩形MORPH_RECT;交叉形MORPH_CROSS;橢圓形MORPH_ELLIPSE;
      ksize:核尺寸大小;
      anchor:錨點的位置,錨點隻影響形態學運算結果的偏移
  • 膨脹:
CV_EXPORTS_W void dilate( InputArray src,    //輸入
                          OutputArray dst,   //輸出 
                          InputArray kernel, //卷積核
                          Point anchor = Point(-1,-1), //錨位置(-1,-1)為中心
                          int iterations = 1,//迭代次數
                          int borderType = BORDER_CONSTANT,//影象邊界畫素模式
                          const Scalar& borderValue = morphologyDefaultBorderValue() //邊界值
                         );

  • 腐蝕:
CV_EXPORTS_W void erode(
				InputArray src,    //輸入
				OutputArray dst,   //輸出
				InputArray kernel, //核大小
				Point anchor=Point(-1,-1),// 錨位置,(-1,-1)為中心
				int iterations=1,  //迭代次數
				int borderType=BORDER_CONSTANT, //影象邊界畫素模式
				const Scalar& borderValue=morphologyDefaultBorderValue()//邊界值
				);

在這裡插入圖片描述

舉例

Mat src,dst1, dst2;
int step_size = 3;
int max_size = 21;

void my_dilate(int ,void*) {
	int s = step_size * 2 + 1;
	Mat structingElement = getStructuringElement(MORPH_ELLIPSE, Size(s, s), Point(-1, -1));
	dilate(src, dst1, structingElement);
	imshow("dilate", dst1);
	return;
}

void my_erode(int, void*) {
	int s = step_size * 2 + 1;
	Mat kernel = getStructuringElement(MORPH_ELLIPSE, Size(s, s));
	erode(src, dst2, kernel);
	imshow("erode", dst2);
	return;
}
int main() {
    src = imread("D:\\cat.jpg");
	if (src.empty()) {
		cerr << "open error" << endl;
		return -1;
	}
	imshow("cat", src);
	my_dilate(0, 0);
	my_erode(0, 0);
	createTrackbar("erode_size", "erode", &step_size, max_size, my_erode);
	createTrackbar("膨脹:", "dilate", &step_size, max_size,my_dilate);
	waitKey(0);
}

在這裡插入圖片描述

詳細:https://blog.csdn.net/qq_37059483/article/details/77878829