Mean shift filter

目录

Mean shift filter

一、算法原理

二、练手实现的算法代码如下:

三、实现结果




一、算法原理

在OpenCV中,meanshift filter函数为 pyrMeanShiftFiltering, 它的函数调用格式如下:

C++: void pyrMeanShiftFiltering(InputArray src, OutputArray dst, double sp, double sr, int maxLevel=1, TermCriteriatermcrit=TermCriteria( TermCriteria::MAX_ITER+TermCriteria::EPS,5,1) )

Parameters:

  • src – The source 8-bit, 3-channel image. //三通道的输入图像
  • dst – The destination image of the same format and the same size as the source. //相同尺寸格式输出图像
  • sp – The spatial window radius.  //空间域半径
  • sr – The color window radius.  //颜色域半径
  • maxLevel – Maximum level of the pyramid for the segmentation. //分割用金字塔的最大层数
  • termcrit – Termination criteria: when to stop meanshift iterations. //迭代终止的条件

算法的描述大致如下:

对于输入图像的每个像素点(X,Y) ,在它的半径为sp的空间域,执行meanshift迭代算法,

像素点(X,Y)的颜色值为(R,G,B), 它的空间邻域点(x,y)的颜色值为(r,g,b),如果点(x,y)的到(X,Y)的颜色距离小于sr,则满足条件,最终我们求得满足条件点的平均空间坐标(X’,Y’)以及平均颜色向量(R',G',B'),并把它们作为下一次迭代的输入。

迭代结果后,我们把最初输入位置的颜色值用最终迭代的颜色值代替。

二、练手实现的算法代码如下:

#include"cv.h"
#include"highgui.h"
#include"cxcore.h"
#include<stdio.h>
#include<stdlib.h>
#include"types.h"void ToYIQ(IplImage *img,IplImage *YIQ_img)
{int i,j;float Y,I,Q;uchar R,G,B;for(i = 0 ;i < img->height;i++){for(j = 0; j < img->width;j++){B = ((uchar*)(img->imageData+i*img->widthStep))[j*img->nChannels+0];G = ((uchar*)(img->imageData+i*img->widthStep))[j*img->nChannels+1];R = ((uchar*)(img->imageData+i*img->widthStep))[j*img->nChannels+2];Y = 0.299*R +0.587*G +0.114*B;I = 0.5957*R-0.2744*G-0.3212*B;Q = 0.2114*R-0.5226*G+0.3111*B;((float*)(YIQ_img->imageData+i*YIQ_img->widthStep))[j*YIQ_img->nChannels+0] = Y;((float*)(YIQ_img->imageData+i*YIQ_img->widthStep))[j*YIQ_img->nChannels+1] = I;((float*)(YIQ_img->imageData+i*YIQ_img->widthStep))[j*YIQ_img->nChannels+2] = Q;}}
}void Mean_Shift_Filter(IplImage *img, IplImage *YIQ_img, IplImage *mean_shift_img,int rad,int colordis )
{float shift,Yc,Ic,Qc,YcOld,IcOld,QcOld,Y2,I2,Q2,dY,dI,dQ,mY,mI,mQ,num_;int i,j,ry,rx,y2,x2,xc,yc,xcOld,ycOld,num,dx,dy,iters,mx,my;uchar R,G,B;shift  = 0;iters  = 0;for(i = 0; i < img->height;i++){for(j = 0; j < img->width;j++){yc = i;xc = j;Yc = ((float*)(YIQ_img->imageData+yc*YIQ_img->widthStep))[xc*YIQ_img->nChannels+0];Ic = ((float*)(YIQ_img->imageData+yc*YIQ_img->widthStep))[xc*YIQ_img->nChannels+1];Qc = ((float*)(YIQ_img->imageData+yc*YIQ_img->widthStep))[xc*YIQ_img->nChannels+2];iters = 0;do{ycOld = yc;xcOld = xc;YcOld = Yc;IcOld = Ic;QcOld = Qc;mx = 0;my = 0;mY = 0;mI = 0;mQ = 0;num = 0;
/*///
假若是rad= 3,则其邻域范围为:其中#为包含在内需要计算的像素点***#*****###***#####*#######*#####***###*****#***
///*/for(ry = - rad;ry <= rad;ry++){y2 = yc+ry;if(y2 >= 0 && y2 < img->height){for(rx = -rad;rx <= rad;rx++){x2 = xc+rx;if(x2 >= 0 && x2 < img->width){if(ry*ry+rx*rx <= rad*rad){Y2 = ((float*)(YIQ_img->imageData+y2*YIQ_img->widthStep))[x2*YIQ_img->nChannels+0];I2 = ((float*)(YIQ_img->imageData+y2*YIQ_img->widthStep))[x2*YIQ_img->nChannels+1];Q2 = ((float*)(YIQ_img->imageData+y2*YIQ_img->widthStep))[x2*YIQ_img->nChannels+2];dY = Yc-Y2;dI = Ic- I2;dQ = Qc- Q2;if(dY*dY + dI*dI+dQ*dQ <= colordis)//当前像素比周围邻域像素相差比较大的时候,在rad半径内(一个菱形领域),只有当前像素满足此条件,所以最后替换当前像素还是自己本身{mx += x2;my += y2;mY += Y2;mI += I2;mQ += Q2;num++;}}}}}}num_ = 1.0/num;Yc = mY*num_;Ic = mI*num_;Qc = mQ*num_;xc = (int)(mx*num_+0.5);yc = (int)(my*num_+0.5);dx = xc - xcOld;dy = yc -ycOld;dY = Yc - YcOld;dI = Ic- IcOld;dQ = Qc - QcOld;shift = dx*dx+dy*dy+dY*dY+dI*dI+dQ*dQ;iters++;}while(shift> 3 && iters < 100);R = CLIP((int)(Yc+0.9653*Ic+0.6210*Qc),0,255);G = CLIP((int)(Yc-0.2721*Ic-0.6473*Qc),0,255);B = CLIP((int)(Yc-1.1070*Ic+1.7046*Qc),0,255);((uchar*)(mean_shift_img->imageData+i*mean_shift_img->widthStep))[j*mean_shift_img->nChannels+0] = B;((uchar*)(mean_shift_img->imageData+i*mean_shift_img->widthStep))[j*mean_shift_img->nChannels+1] = G;((uchar*)(mean_shift_img->imageData+i*mean_shift_img->widthStep))[j*mean_shift_img->nChannels+2] = R; }}}
int main(void)
{int w,h;CvSize img_size;IplImage *src,*mean_shift_img,*YIQ_img;src = cvLoadImage("lg-image4.bmp",-1);if(src == NULL){printf("Please insert image\n");return 0;}img_size = cvGetSize(src);w = img_size.width;h = img_size.height;YIQ_img = cvCreateImage(img_size,IPL_DEPTH_32F,3);mean_shift_img = cvCreateImage(img_size,IPL_DEPTH_8U,3);if((mean_shift_img == NULL) || (YIQ_img==NULL))printf("malloc for image memory failure!\n");cvZero(YIQ_img);cvZero(mean_shift_img);cvNamedWindow("Show original image",0);cvShowImage("Show original image",src);ToYIQ(src,YIQ_img);Mean_Shift_Filter(src, YIQ_img, mean_shift_img,5,15*15 );cvNamedWindow("Mean Shift image",0);cvShowImage("Mean Shift image",mean_shift_img);cvSaveImage("lg-image4_Mean_Shift_filter.bmp",mean_shift_img);cvWaitKey(0);cvDestroyWindow("Mean Shift image");cvDestroyWindow("Show original image");printf("done\n");cvReleaseImage(&YIQ_img);cvReleaseImage(&mean_shift_img);return 0;
}

三、实现结果

左侧为原始图像;右侧为结果图像

标题左侧为原始图像;右侧为结果图像

但是针对椒盐噪声,其效果基本无效:

左侧为原始图像;右侧为添加椒盐噪声图像

左侧为原始图像mean_shift filter之后结果;右侧为添加椒盐噪声图像mean_shift_filter处理结果

保边滤波之Mean shift filter相关推荐

  1. 图像保边滤波算法集锦系列

    在美颜算法的实现中,如何既能把人脸皮肤磨得光滑,雀斑磨得干净,又能保留五官的自然清晰,这就需要一种能保留边缘信息的平滑滤波器,这种滤波器的好坏在一定程度上,也就影响了美颜磨皮效果的好坏,对此,本人将在 ...

  2. 快速导向滤波 matlab,导向滤波小结:从导向滤波(guided filter)到快速导向滤波(fast guide filter)的原理,应用及opencv实现代码...

    http://blog.csdn.net/kuweicai/article/details/78385871 1. 导向滤波简介 导向滤波是何凯明在学生时代提出的一个保边滤波(edge-preserv ...

  3. 双边滤波(bilateral filter)以及联合双边滤波(joint bilateral filter)

    文章目录 双边滤波 理论公式 代码(C++) 数学辅助理解 联合双边滤波(joint bilateral filter) 参考链接 写在最后 双边滤波 自用备忘,若侵则删. 理论公式 利用二维高斯函数 ...

  4. 保边滤波之引导滤波与领域转换滤波

    (1)引导滤波 局部窗口内输出图像O和引导图像G成线性关系Oi=akGi+bk, ∀i∈Ωk 假设输出图像O和输入图像I之间的关系为Oi=Ii−ni,噪声最小即最小化ni,即 每个像素点i包含于多个窗 ...

  5. 导向滤波小结:从导向滤波(guided filter)到快速导向滤波(fast guide filter)的原理,应用及opencv实现代码

    1. 导向滤波简介 导向滤波是何凯明在学生时代提出的一个保边滤波(edge-preserving smoothing)算法.何凯明在cv圈应该算是名人了,学生时代关于图像去雾的研究就以第一作者的身份获 ...

  6. 一种新颖的保边滤波——Sub Window Filtering

    分享2019 CVPR的一篇图像滤波算法论文.这个算法的新颖之处在于:不管传统的滤波器保不保边,运用了Side Window后都可以保边. 基本思路 经典滤波算法基本都是:以某个像素点为中心,按照滤波 ...

  7. 均值滤波计算_从零学美颜算法保边滤波

    作者:天儿哥 有了前面的照片处理基础,这一篇开始讲美颜算法. 一.滤波为什么要保边? 人像美颜技术中,最重要的技术之一就是磨皮,没有磨皮谁还敢自拍,谁还敢直播? 磨皮本质上就是对图像进行滤波,比如前面 ...

  8. 【地震波滤波】保边滤波、傅氏变换干扰波去噪滤波、基于小波分解和重建的干扰波去噪、基于维纳滤波的去噪、中值滤波、视速度滤波

    1.保边滤波 保护边缘滤波器,通常有四种类型,其中性能较为优良的是双边滤波器,其主要原理为: 双边滤波方法(Bilateral filtering)是基于Gsuss滤波方法提出的,主要是针对Gauss ...

  9. c语言双边滤波算法,浅析bilateral filter双边滤波器的理解

    图像去噪的方法很多,如中值滤波,高斯滤波,维纳滤波等等.但这些降噪方法容易模糊图片的边缘细节,对于高频细节的保护效果并不明显.相比较而言,bilateral filter双边滤波器可以很好的边缘保护, ...

  10. 粒子滤波 PF(Particle filter)算法

    代码的路 粒子滤波器方法通常用于视觉跟踪.从统计角度来看,它是一种顺序蒙特卡罗重要抽样方法,用于根据观测序列估计动态系统的潜状态变量. 粒子滤波步骤: 初始状态:用大量粒子模拟X(t),粒子在空间内均 ...

最新文章

  1. market layout
  2. mysql服务器的HA集群之corosync+drbd+pacemaker实现 上
  3. python统计excel文本单元格_python xlrd从excel文本单元格接收浮点数
  4. 3、事件响应函数(一)
  5. 文艺编程 Literate Programming (原文中英文对照)
  6. Eclipse离线安装Svn插件
  7. [AI教程]最全人工智能图谱解析和视频下载
  8. layerdate时间控件不随着input框的滚动移动
  9. sola染毒文件恢复工具
  10. 进程中出现n多的conime.exe怎么办
  11. mbr转gpt 无损 linux,磁盘MBR改成GPT|MBR无损转换GPT分区
  12. uniapp,小程序,实现签名功能
  13. java微信开发教程,Java微信公众平台开发(1) 接入微信公众平台
  14. Excel 操作 第一篇 行列技巧
  15. PHP 对银行卡,手机号,真实姓名,身份证进行掩码加星号处理
  16. Photoshop CC 2019软件安装教程
  17. 匈牙利法及其最优性分析
  18. Linux iperf 用法介绍
  19. 寂静岭2java攻略_寂静岭2攻略 全剧情流程图文攻略+隐藏要素解谜
  20. 什么是MyCat?原理是啥?

热门文章

  1. 2013程序员考证下午题练习
  2. LS1012ARDB - How to reflash u-boot / RCW via built in Kinetis CMSIS-DAP
  3. VBA代码宝工具箱(陈表达)
  4. linux服务器双网卡路由优先级冲突 Metric值
  5. 2019年计算机一级考试pdf,2019年计算机一级考试试题及答案.pdf
  6. js实现页面视频全屏播放
  7. 【C#】Winform常用属性和事件笔记大全(入门者参考)
  8. android 快速unity,关于android:Unity平台-快速集成华为性能管理服务
  9. fudannlp java_中文NLP工具
  10. AVI、WMV、FLV、MKV、WebM、MOV格式视频怎么打开?它们之间有什么区别?答案在这里