膨脹和腐蝕
如實對膨脹和腐蝕不了解需要先看一下這篇文章,了解圖像處理 腐蝕 膨脹 細化
膨脹和腐蝕這兩種操作是形態學處理的基礎,許多形態學算法都是以這兩種運算為基礎的.
① 膨脹
是以得到B的相對與它自身原點的映像并且由z對映像進行移位為基礎的.A被B膨脹是所有位移z的集合,這樣,和A至少有一個元素是重疊的.我們可以把上式改寫為:
結構元素B可以看作一個卷積模板,區別在于膨脹是以集合運算為基礎的,卷積是以算術運算為基礎的,但兩者的處理過程是相似的.
⑴ 用結構元素B,掃描圖像A的每一個像素
⑵ 用結構元素與其覆蓋的二值圖像做“與”操作
⑶ 如果都為0,結果圖像的該像素為0.否則為1
② 腐蝕
對Z中的集合A和B,B對A進行腐蝕的整個過程如下:
⑴ 用結構元素B,掃描圖像A的每一個像素
⑵ 用結構元素與其覆蓋的二值圖像做“與”操作
⑶ 如果都為1,結果圖像的該像素為1.否則為0
腐蝕處理的結果是使原來的二值圖像減小一圈.
⑷ 擊中(匹配)或擊不中變換
他們的運用廣泛:
消除噪聲
分割(isolate)獨立的圖像元素,以及連接(join)相鄰的元素。
OpenCV中函數介紹(erode and dilate)腐蝕與膨脹
erode
erode(InputArray src,// 原圖像
? ? ? ? ? ?OutputArray dst,// 輸出圖像// 腐蝕操作的內核。 如果不指定,默認為一個簡單的 3x3 矩陣。// 否則,我們就要明確指定它的形狀,可以使用函數 getStructuringElement:
? ? ? ? ? ?InputArray kernel,? ? ??
? ? ? ? ? Point anchor = Point(-1,-1),
? ? ? ? ? ?int iterations =1,
? ? ? ? ? ?int borderType = BORDER_CONSTANT,
? ? ? ? ? ? const Scalar& borderValue = morphologyDefaultBorderValue()
)
dilate(參數用途同上)
dilate(InputArray src,? ? ??
? ? ? ? ? ?OutputArray dst,? ? ??
? ? ? ? ? ?InputArray kernel,? ? ??
? ? ? ? ? ?Point anchor = Point(-1,-1),? ? ??
? ? ? ? ? ? int iterations =1,? ? ??
? ? ? ? ? ? int borderType = BORDER_CONSTANT,? ? ??
? ? ? ? ? ? ?const Scalar& borderValue = morphologyDefaultBorderValue()?
? ? ? ? ? ? ? )
getStructuringElemen
// 這里 shap 是內核形狀,ksize 是內核大小,anchor是錨點位置
? Mat getStructuringElement(
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? int shape,? ? ? ? ? ? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Size ksize,? ? ? ? ? ? ? ? ? ? ? ? ??
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?Point anchor= Point(-1,-1)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? )
shap 有三種形狀
矩形:MORPH_RECT
交叉形:MORPH_CROSS
橢圓形:MORPH_ELLIPSE
代碼實現
腐蝕
- (void)eroding
{
int erosion_type;
/// dilation_elem 全局變量 int 型,用來控制選擇的內核形狀
if(dilation_elem == 0) {
erosion_type = MORPH_RECT;? ? // 矩形
} else if(dilation_elem == 1) {
erosion_type = MORPH_CROSS;? ? // 十字
} else {
erosion_type = MORPH_ELLIPSE;? // 圓形
}
/// 指定內核 erosion_size 全局變量 我這里用的是 Slider.value 來控制 erosion_size 的
Mat element = getStructuringElement(erosion_type, cv::Size(2*erosion_size+1,2*erosion_size+1),cv::Point(erosion_size,erosion_size));
// 腐蝕操作
erode(src, dst, element);
self.secondImageView.image = MatToUIImage(dst);
}
效果圖(其中一種)
膨脹
- (void)diating
{
int erosion_type;
/// dilation_elem 全局變量 int 型,用來控制選擇的內核形狀
if(dilation_elem == 0) {
erosion_type = MORPH_RECT;? ? // 矩形
} else if(dilation_elem == 1) {
erosion_type = MORPH_CROSS;? ? // 十字
} else {
erosion_type = MORPH_ELLIPSE;? // 圓形
}
/// 指定內核 erosion_size 全局變量 我這里用的是 Slider.value 來控制 erosion_size 的
Mat element = getStructuringElement(erosion_type, cv::Size(2*erosion_size+1,2*erosion_size+1),cv::Point(erosion_size,erosion_size));
// 膨脹操作
dilate(src, dst, element);
self.secondImageView.image = MatToUIImage(dst);
}
效果(其中的一種)
參考資料