opencv--膨脹和腐化
形態學
形態學(morphology)常應用在生物學中,研究動植物的形態和結構;
影象形態學即數學形態學(Mathematical morphology)是一門建立在格倫和拓撲學基礎上的影象分析學科,是數學形態學影象處理的基本理論;
常見影象形態學運算:腐蝕、膨脹、開運算、閉運算、骨架抽取、極線腐蝕、擊中擊不中變換、Top-hat變換、顆粒分析、流域變換、形態學梯度等;
最基本的形態學操作是:膨脹(dilation)和腐蝕(erosion);
- 膨脹操作會擴大(粗化)影象中物體的輪廓,可以用來彌補(填充)物體間的孔洞,強化離散點,代價是導致物體的面積比原來的面積要大。
- 腐蝕操作會收縮(細化)影象中物體的輪廓,可以用來斷開(分離)物體間的連線,消除離散點,代價是導致物體的面積比原來的面積要小。
膨脹和腐蝕
腐蝕和膨脹是對白色部分(高亮部分)而言的,不是黑色部分。膨脹就是影象中的高亮部分進行膨脹,“領域擴張”,效果圖擁有比原圖更大的高亮區域。腐蝕就是原圖中的高亮部分被腐蝕,“領域被蠶食”,效果圖擁有比原圖更小的高亮區域。
這些形態學操作都涉及到一個關鍵的因子——結構元。結構元基本的形態是矩形、十字形或橢圓形(圓形)。
結構元素就相當於我們在濾波中所涉及到的模板,也就是說它是一個給定畫素的矩陣,這個矩陣可以是任意形狀的,但是一般情況下都是正方形,圓形或者菱形的但是在結構元素中有一箇中心點(也叫做anchor point)。和模板中心一樣,處理後的結果賦值給和這個中心點對齊的畫素點。處理的過程也是基本相同。
結構元素和卷積模板的區別在於,
膨脹是以集合運算為基礎的,卷積是以算數運算為基礎的。
膨脹原理:
膨脹:求區域性最大值;
①定義一個卷積核B,
核可以是任何的形狀和大小,且擁有一個單獨定義出來的參考點-錨點(anchorpoint);
通常和為帶參考點的正方形或者圓盤,可將核稱為模板或掩膜;
②將核B與影象A進行卷積,計算核B覆蓋區域的畫素點最大值;
- 用結構元素,掃描影象的每一個畫素
- 用結構元素與其覆蓋的二值影象做“與”操作
- 如果都為0,結果影象的該畫素為0。否則為1
③將這個最大值賦值給參考點指定的畫素;
因此,影象中的高亮區域逐漸增長。
腐蝕
腐蝕:區域性最小值(與膨脹相反);
①定義一個卷積核B,
核可以是任何的形狀和大小,且擁有一個單獨定義出來的參考點-錨點(anchorpoint);
通常和為帶參考點的正方形或者圓盤,可將核稱為模板或掩膜;
②將核B與影象A進行卷積,計算核B覆蓋區域的畫素點最小值;
- 用結構元素,掃描影象的每一個畫素
- 用結構元素與其覆蓋的二值影象做“與”操作
- 如果都為1,結果影象的該畫素為1。否則為0
③將這個最小值賦值給參考點指定的畫素;
因此,影象中的高亮區域逐漸減小。
膨脹和腐蝕的主要用途:
- 消除噪聲;
- 分割出獨立的影象元素,在影象中連線相鄰的元素;
- 尋找影象中明顯的極大值或極小值區;
- 求出影象的梯度;
【注】:
腐蝕和膨脹是對畫素值大的部分而言的,即高亮白部分而不是黑色部分;
膨脹是影象中的高亮部分進行膨脹,領域擴張,效果圖擁有比原圖更大的高亮區域;
腐蝕是影象中的高亮部分被腐蝕掉,領域縮減,效果圖擁有比原圖更小的高亮區域;
opencv中API
- 卷積核
關於核,一般配合==getStructuringElement()==使用;- 功能:返回指定形狀和尺寸的結構元素;
- 格式:
getStructuringElement(int shape, Size ksize, Point anchor=Point(-1,-1));
- 引數:
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