Meanshift(均值漂移)

本文介绍OpenCV中MeanShift算法的实现及其在图像分割中的应用,包括cvPyrMeanShiftFiltering函数的使用方法及参数调整技巧。

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

 Meanshift(均值漂移)是一种在一组数据的密度分布中寻找局部极值的稳定的方法。Meanshift不仅可以用于图像滤波,视频跟踪,还可以用于图像分割。

    通过给出一组多维数据点,其维数是(x,y,r,g,b),均值漂移可以用一个窗口扫描空间来找到数据密度最大的区域,可以理解为数据分布最集中的区域。

    在这里需要注意,由于空间位置(也就是上面的x和y)的变化范围与颜色的变化范围(上面的r,g,b)有极大的不同,所以,meanshift对这两个维数要采用不同的窗口半径。在opencv自带的meanshift分割函数cvPyrMeanShiftFiltering()中,就专门有2个半径参数,分别是spatialRadius和colorRadius,这两个参数分别代表的是空间半径(x,y)和颜色(r,g,b)半径。

     当均值漂移窗口移动时,经过窗口变换后收敛到数据峰值的所有点都会连通起来,并且属于该峰值。这种所属关系从密集的尖峰辐射,形成了图像的分割。opencv中的meanshift分割实际上是由比例金字塔(cvPyrUP(),cvPyrDown())完成的,相关的介绍大家可以看年learning opencv中关于图像金字塔的介绍。

     下面的代码是我自己写的,大家可以参考一下。PS:我运行的时候发现实际上cvPyrMeanShiftFiltering的运行效率并不是很高,特别是把spatialRadius的值增大以后迭代时感觉很费时。 

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #include"highgui.h"  
  2. #include"cv.h"  
  3.   
  4. #include <iostream>  
  5.   
  6. using namespace cv;  
  7. using namespace std;  
  8.   
  9.   
  10. IplImage* src;  //source image  
  11. IplImage* dst;  //the dst image after meanshift  
  12. int spatialRad=10,colorRad=20,maxPryLevel=1;  
  13.   
  14.   
  15. void on_Meanshift(int )  //the callback function  
  16. {  
  17.   
  18.     //cout<<"spatialRad="<<spatialRad<<endl;   //for test  
  19.     //cout<<"   colorRad="<<colorRad<<endl;  
  20.     //cout<<"        maxPryLevel="<<maxPryLevel<<endl;  
  21.     cvPyrMeanShiftFiltering(src,dst,spatialRad,colorRad,maxPryLevel);  //segmentation use meanshift  
  22.     cvShowImage("dst",dst);   //show the segmented image  
  23.   
  24. }  
  25. void main()  
  26. {  
  27.     src = cvLoadImage("1.png");   //load the picture  
  28.     CvSize size;  
  29.     size.width = src->width;  
  30.     size.height = src->height;  
  31.     dst = cvCreateImage(size,src->depth,3);  //set the size of the dst image  
  32.     cvNamedWindow("src",CV_WINDOW_AUTOSIZE);  
  33.     cvNamedWindow("dst",CV_WINDOW_AUTOSIZE);  
  34.     cvShowImage("src",src);  
  35.     cvPyrMeanShiftFiltering(src,dst,spatialRad,colorRad,maxPryLevel);  
  36.   
  37.     //create the trackbar  
  38.     cvCreateTrackbar("spatialRad","dst",&spatialRad,50,on_Meanshift);   
  39.     cvCreateTrackbar("colorRad","dst",&colorRad,60,on_Meanshift);  
  40.     cvCreateTrackbar("maxPryLevel","dst",&maxPryLevel,5,on_Meanshift);  
  41.   
  42.     cvShowImage("dst",dst);  
  43.   
  44.     cvWaitKey(0);  
  45. }  

   在代码中使用了trackbar,因此可以自己 改变spatialRad,colorRad,maxPryLevel的值,以便观察不同参数下的效果。截图如下



下面图是源图片


opencv 里面关于 meanshift 算法的应用还有两个函数 CVmeanshift CVCAMshift 函数,都是用于跟踪的,效果还不错。
现在在视频跟踪里, meanshift 方法 + 卡尔曼滤波还是挺流行的。



Opencv之meanshift篇

本文主要是介绍了OPENCV里的meanshift分割函数cvPyrMeanShiftFiltering函数。关于算法的详细叙述可参考《Mean shift: a robust approach toward feature space analysis》D,comaniciu 2003.该函数基本参照上文所描述的算法流程编写的。在opencv实现里加入了金字塔分层分割的概念。Meanshift分割可供选择的只有一个参数即分割的精细度,也就是选择的核宽。cvPyrMeanShiftFiltering函数只能输入8位三通道的RGB图像,输出时分割结果,没有提供分割的具体信息如类别数,模态等。该函数采用的是UNIFORM核,选择的矩形区域为核覆盖区。Meanshift算法在每个样本上都执行一次确定类别,所以复杂度比较高O(N*W),w是操作系数,处理一幅320*240图片需要2,3秒的时间。函数在实现时也没有考虑消除一些小的类别(数量较少的)。使得这个函数更像是discontinuity preserve smoothing.

有很多图片经过这个函数处理后很难感觉出输入输出有什么大区别,其实是被平滑了。观察仔细点可以看出来。

输入图片:

                  

输出图像:


Opencvmeanshift

本文主要是介绍了OPENCV里的meanshift分割函数cvPyrMeanShiftFiltering函数。关于算法的详细叙述可参考Mean shift: a robust approach toward feature space analysisD,comaniciu 2003.该函数基本参照上文所描述的算法流程编写的。在opencv实现里加入了金字塔分层分割的概念。Meanshift分割可供选择的只有一个参数即分割的精细度,也就是选择的核宽。cvPyrMeanShiftFiltering函数只能输入8位三通道的RGB图像,输出时分割结果,没有提供分割的具体信息如类别数,模态等。该函数采用的是UNIFORM核,选择的矩形区域为核覆盖区。Meanshift算法在每个样本上都执行一次确定类别,所以复杂度比较高ON*W),w是操作系数,处理一幅320*240图片需要23秒的时间。函数在实现时也没有考虑消除一些小的类别(数量较少的)。使得这个函数更像是discontinuity preserve smoothing.

有很多图片经过这个函数处理后很难感觉出输入输出有什么大区别,其实是被平滑了。观察仔细点可以看出来。

输入图片:

                  

输出图像:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值