OpenCV 形態學
形態學處理
形態學處理之前需要將圖像進行二值化處理, 然后我們需要設定一個卷積核, 最后將像素上每個點都完成卷積計算.
形態學很多高級處理的基礎, 有很多作用: 消除毛刺、填充空隙、檢測邊緣,檢查拐角(使用十字形卷積核)
腐蝕 Erode
腐蝕作用和膨脹相反, 用來腐蝕減小白色區域, 常用來消除一些白色毛刺等細小區域, 也會腐蝕掉邊緣部分.
卷積計算方法: 卷積核為一個全1的小矩陣, 計算過程為, 圖像一個像素和卷積核對齊后, 如果卷積覆蓋區域中圖像有含0的像素, 則該像素取值為0, 即白色, 如果全部都為1, 則該像素值為1.
代碼示例:
public void erodeTest()
{
string file = @"D:\my_workspace\opencv\images\毛刺.jpg";
var img = Cv2.ImRead(file, ImreadModes.Grayscale);
var elements = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(3, 3));
var newImg1 = img.Clone();
newImg1 = newImg1.Erode(elements, null, iterations: 1);
Cv2.ImShow("img", img);
Cv2.ImShow("腐蝕1次", newImg1);
Cv2.WaitKey();
Cv2.DestroyAllWindows();
}
效果:

膨脹 Dilate
膨脹用來擴張白色區域, 減少黑色區域, 常用來消除區域中的黑色空隙, 也會擴大白色邊緣部分.
卷積計算方法: 卷積核為一個全1的小矩陣, 計算過程為, 圖像一個像素和卷積核對齊后, 如果卷積覆蓋區域中圖像有含1的像素, 則該像素取值為1, 即白色, 如果全部都為0, 則該像素值為0.
/// <summary>
/// 膨脹測試
/// 結論: 3次遞歸, 仍有少量空隙, 這時可增加遞歸次數, 或者增大卷積核size
/// </summary>
public void dilateTest()
{
string file = @"D:\my_workspace\opencv\images\孔隙.jpg";
var img = Cv2.ImRead(file, ImreadModes.Grayscale);
var elements = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(3, 3));
var newImg3 = img.Clone();
newImg3 = newImg3.Dilate(elements, null, iterations: 3); //3次遞歸, 仍有少量空隙, 這時可增加遞歸次數, 或者增大卷積核size
var newImg6 = img.Clone();
newImg6 = newImg6.Dilate(elements, null, iterations: 6); //6次遞歸, 空隙清除干凈
Cv2.ImShow("img", img);
Cv2.ImShow("膨脹3次", newImg3);
Cv2.ImShow("膨脹6次", newImg6);
Cv2.WaitKey();
Cv2.DestroyAllWindows();
}
效果:
經過膨脹后, 空隙被消除了, 但可以看到矩形也變大了.

開運算
開運算是先腐蝕后膨脹, 閉運算是先膨脹后腐蝕, 腐蝕和膨脹其實并不是逆運算, 所以開閉運算最終效果是不一樣的.
我們使用開運算的主要目的是利用腐蝕的正向效果, 即消除毛刺和虛假聯通部分, 同時使用膨脹來抵消腐蝕的副作用.
代碼示例:
/// <summary>
/// 開運算, 先腐蝕后膨脹
/// </summary>
public void openTest()
{
string file = @"D:\my_workspace\opencv\images\毛刺.jpg";
var img = Cv2.ImRead(file, ImreadModes.Grayscale);
var elements = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(3, 3));
var newImg1 = img.Clone();
Cv2.MorphologyEx(newImg1, newImg1, MorphTypes.Open, elements, anchor: null, iterations: 1);
Cv2.ImShow("img", img);
Cv2.ImShow("開運算", newImg1);
Cv2.WaitKey();
Cv2.DestroyAllWindows();
}
效果:

閉運算
閉運算是先膨脹后腐蝕, 開運算是先腐蝕后膨脹, 腐蝕和膨脹其實并不是逆運算, 所以開閉運算最終效果是不一樣的.
我們使用閉運算的主要目的是利用膨脹的正向效果, 同時使用腐蝕來抵消膨脹的副作用.
代碼:
/// <summary>
/// 閉運算, 先膨脹后腐蝕
/// </summary>
public void closeTest()
{
string file = @"D:\my_workspace\opencv\images\孔隙.jpg";
var img = Cv2.ImRead(file, ImreadModes.Grayscale);
var elements = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(3, 3));
var newImg1 = img.Clone();
Cv2.MorphologyEx(newImg1, newImg1, MorphTypes.Close, elements, anchor: null, iterations: 4);
Cv2.ImShow("img", img);
Cv2.ImShow("閉運算", newImg1);
Cv2.WaitKey();
Cv2.DestroyAllWindows();
}
效果:

梯度 Gradient
梯度相當于膨脹后的圖像減去腐蝕后的圖像, 可以用來刻畫出輪廓部分.
代碼示例:
/// <summary>
/// 梯度: 膨脹-腐蝕
/// </summary>
public void gradientTest()
{
string file = @"D:\my_workspace\opencv\images\circle.png";
var img = Cv2.ImRead(file, ImreadModes.Grayscale);
var newImg3 = img.Clone();
var elements3 = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(3, 3));
Cv2.MorphologyEx(newImg3, newImg3, MorphTypes.Gradient, elements3, anchor: null, iterations: 1);
var newImg5 = img.Clone();
var elements5 = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(5, 5));
Cv2.MorphologyEx(newImg5, newImg5, MorphTypes.Gradient, elements5, anchor: null, iterations: 1);
Cv2.ImShow("img", img);
Cv2.ImShow("梯度3", newImg3);
Cv2.ImShow("梯度5", newImg5);
Cv2.WaitKey();
Cv2.DestroyAllWindows();
}
效果:

禮帽和頂帽 Top Hat
禮帽也叫做頂帽 Top Hat: 原始圖像-開運算, 能將一些細小的毛刺凸顯出來
黑帽 Black Hat: 閉操作-原始圖像, 能將一些黑色的空隙凸顯出來.
代碼示例:
/// <summary>
/// 禮帽(頂帽), 原始圖像-開操作
/// </summary>
public void topHatTest()
{
string file = @"D:\my_workspace\opencv\images\毛刺.jpg";
var img = Cv2.ImRead(file, ImreadModes.Grayscale);
var elements = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(3, 3));
var newImg1 = img.Clone();
Cv2.MorphologyEx(newImg1, newImg1, MorphTypes.TopHat, elements, anchor: null, iterations: 1);
Cv2.ImShow("img", img);
Cv2.ImShow("禮帽(頂帽)", newImg1);
Cv2.WaitKey();
Cv2.DestroyAllWindows();
}
效果:

黑帽 Black Hat
黑帽 Black Hat: 閉操作-原始圖像, 能將一些黑色的空隙凸顯出來.
禮帽也叫做頂帽 Top Hat: 原始圖像-開運算, 能將一些細小的毛刺凸顯出來
代碼示例:
/// <summary>
/// 黑帽運算, 閉操作-原始圖像
/// </summary>
public void blackHatTest()
{
string file = @"D:\my_workspace\opencv\images\孔隙.jpg";
var img = Cv2.ImRead(file, ImreadModes.Grayscale);
var elements = Cv2.GetStructuringElement(MorphShapes.Rect, new OpenCvSharp.Size(3, 3));
var newImg1 = img.Clone();
Cv2.MorphologyEx(newImg1, newImg1, MorphTypes.BlackHat, elements, anchor: null, iterations: 4);
Cv2.ImShow("img", img);
Cv2.ImShow("黑帽運算", newImg1);
Cv2.WaitKey();
Cv2.DestroyAllWindows();
}
效果演示:

參考
https://zhuanlan.zhihu.com/p/273475106
https://blog.csdn.net/Vermont_/article/details/108424547

浙公網安備 33010602011771號