图像分割 Image Segmentation

本文介绍了OpenCV中的三种图像分割算法:分水岭分割、金字塔分割和均值漂移分割。分水岭算法效果最佳但依赖于标记,金字塔算法效率最低,均值漂移算法效率高但效果次于分水岭。示例代码和对比分析帮助理解各算法特点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

               

http://www.cnblogs.com/xrwang/archive/2010/02/28/ImageSegmentation.html?login=1

作者:王先荣
前言
    图像分割指的是将数字图像细分为多个图像子区域的过程,在OpenCv中实现了三种跟图像分割相关的算法,它们分别是:分水岭分割算法、金字塔分割算法以及均值漂移分割算法。它们的使用过程都很简单,下面的文章权且用于记录,并使该系列保持完整吧。
分水岭分割算法
    分水岭分割算法需要您或者先前算法提供标记,该标记用于指定哪些大致区域是目标,哪些大致区域是背景等等;分水岭分割算法的分割效果严重依赖于提供的标记。OpenCv中的函数cvWatershed实现了该算法,函数定义如下:

 
  
void cvWatershed( const CvArr * image, CvArr * markers)

其中: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 ++ ;        }
复制代码

 

 

        您可以用类似下面的方式来使用分水岭算法:

使用分水岭分割算法
复制代码
 
   
        /// <summary>         /// 分水岭算法图像分割        /// </summary>         /// <returns> 返回用时 </returns>         private string Watershed()        {            // 分水岭算法分割             Image < Gray, Int32 > imageMarkers2 = imageMarkers.Copy();            Stopwatch sw = new Stopwatch();            sw.Start();            CvInvoke.cvWatershed(imageSource.Ptr, imageMarkers2.Ptr);            sw.Stop();            // 将分割的结果转换到256级灰度图像             pbResult.Image = imageMarkers2.Bitmap;            imageMarkers2.Dispose();            return string .Format( " 分水岭图像分割,用时:{0:F05}毫秒。\r\n " , sw.Elapsed.TotalMilliseconds);        }
复制代码

 

 

金字塔分割算法
    金字塔分割算法由cvPrySegmentation所实现,该函数的使用很简单;需要注意的是图像的尺寸以及金字塔的层数,图像的宽度和高度必须能被2整除,能够被2整除的次数决定了金字塔的最大层数。下面的代码演示了如果校验金字塔层数:

校验金字塔分割的金字塔层数
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值