图像分割(Image Segmentation)
圖像分割(Image Segmentation)
作者:王先榮
前言
??? 圖像分割指的是將數字圖像細分為多個圖像子區域的過程,在OpenCv中實現了三種跟圖像分割相關的算法,它們分別是:分水嶺分割算法、金字塔分割算法以及均值漂移分割算法。它們的使用過程都很簡單,下面的文章權且用于記錄,并使該系列保持完整吧。
分水嶺分割算法
??? 分水嶺分割算法需要您或者先前算法提供標記,該標記用于指定哪些大致區域是目標,哪些大致區域是背景等等;分水嶺分割算法的分割效果嚴重依賴于提供的標記。OpenCv中的函數cvWatershed實現了該算法,函數定義如下:
其中:image為8為三通道的彩色圖像;
????? markers是單通道整型圖像,它用不同的正整數來標記不同的區域,下面的代碼演示了如果響應鼠標事件,并生成標記圖像。
private void pbSource_MouseMove(object sender, MouseEventArgs e)
{
//如果按下了左鍵
if (e.Button == MouseButtons.Left)
{
if (previousMouseLocation.X >= 0 && previousMouseLocation.Y >= 0)
{
Point p1 = new Point((int)(previousMouseLocation.X * xScale), (int)(previousMouseLocation.Y * yScale));
Point p2 = new Point((int)(e.Location.X * xScale), (int)(e.Location.Y * yScale));
LineSegment2D ls = new LineSegment2D(p1, p2);
int thickness = (int)(LineWidth * xScale);
imageSourceClone.Draw(ls, new Bgr(255d, 255d, 255d), thickness);
pbSource.Image = imageSourceClone.Bitmap;
imageMarkers.Draw(ls, new Gray(drawCount), thickness);
}
previousMouseLocation = e.Location;
}
}
//當松開鼠標左鍵時,將繪圖的前一位置設置為(-1,-1)
private void pbSource_MouseUp(object sender, MouseEventArgs e)
{
previousMouseLocation = new Point(-1, -1);
drawCount++;
}
?
?
??????? 您可以用類似下面的方式來使用分水嶺算法:
使用分水嶺分割算法?
?
金字塔分割算法
??? 金字塔分割算法由cvPrySegmentation所實現,該函數的使用很簡單;需要注意的是圖像的尺寸以及金字塔的層數,圖像的寬度和高度必須能被2整除,能夠被2整除的次數決定了金字塔的最大層數。下面的代碼演示了如果校驗金字塔層數:
?
?
使用金字塔分割的示例代碼如下:
使用金字塔分割算法?
?
均值漂移分割算法
??? 均值漂移分割算法由cvPryMeanShiftFiltering所實現,均值漂移分割的金字塔層數只能介于[1,7]之間,您可以用類似下面的代碼來使用它:
?
?
??? 函數cvPryMeanShiftFiltering在EmguCv中沒有實現,我們可以用下面的方式來使用:
調用均值漂移分割?
?
分割效果及性能對比
??? 上述三種分割算法的效果如何呢?下面我們以它們的默認參數,對一幅2272x1704大小的圖像進行分割。得到的結果如下所示:
圖1 分水嶺分割算法(左圖白色的線條用于標記區域)
圖2 金字塔分割算法
圖3 均值漂移分割算法
??? 從上面我們可以看出:
??? (1)分水嶺分割算法的分割效果效果最好,均值漂移分割算法次之,而金字塔分割算法的效果最差;
??? (2)均值漂移分割算法效率最高,分水嶺分割算法接近于均值漂移算法,金字塔分割算法需要很長的時間。
??? 值得注意的是分水嶺算法對標記很敏感,需要仔細而認真的繪制。
?
??? 本文的完整代碼如下:
本文完整代碼?
?
感謝您耐心看完本文,希望對您有所幫助。
總結
以上是生活随笔為你收集整理的图像分割(Image Segmentation)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 基于特征点匹配的自适应目标跟踪算法
- 下一篇: 深度卷积网络CNN与图像语义分割