一:Mean Shift算法介绍

Mean Shift是一种聚类算法,在数据挖掘,图像提取,视频对象跟踪中都有应用。本文

重要演示Mean Shift算法来实现图像的低通边缘保留滤波效果。其处理以后的图像有点

类似油画一样。Mean Shift算法的输入参数一般有三个:

1.      矩阵半径r,声明大小

2.      像素距离,常见为欧几里德距离或者曼哈顿距离

3.      像素差值value

算法大致的流程如下:

a.      输入像素点P(x, y)

b.      计算该点的像素值pixelv

c.      根据输入的半径r与差值value求出矩阵半径内满足差值像素平均值作为输出像素点值

d.      计算shift与repetition,如果满足条件

e.      继续c ~ d,直到条件不满足退出,得到最终的输出像素值

f.       对输入图像的每个像素重复a ~ e,得到图像输出像素数据

二:色彩空间转换

本文Mean Shift滤波在YIQ颜色空间上完成,关于RGB与YIQ颜色空间转换可以参考

这里:http://en.wikipedia.org/wiki/YIQ我google找来的转换公式截屏:

三:程序效果

滤镜源代码:

  1. package com.gloomyfish.filter.study;
  2. import java.awt.image.BufferedImage;
  3. public class MeanShiftFilter extends AbstractBufferedImageOp {
  4. private int radius;
  5. private float colorDistance;
  6. public MeanShiftFilter() {
  7. radius = 3; // default shift radius
  8. colorDistance = 25; // default color distance
  9. }
  10. public int getRadius() {
  11. return radius;
  12. }
  13. public void setRadius(int radius) {
  14. this.radius = radius;
  15. }
  16. public float getColorDistance() {
  17. return colorDistance;
  18. }
  19. public void setColorDistance(float colorDistance) {
  20. this.colorDistance = colorDistance;
  21. }
  22. @Override
  23. public BufferedImage filter(BufferedImage src, BufferedImage dest) {
  24. int width = src.getWidth();
  25. int height = src.getHeight();
  26. if ( dest == null )
  27. dest = createCompatibleDestImage( src, null );
  28. int[] inPixels = new int[width*height];
  29. int[] outPixels = new int[width*height];
  30. getRGB( src, 0, 0, width, height, inPixels);
  31. // convert RGB color space to YIQ color space
  32. float[][] pixelsf = new float[width*height][3];
  33. for(int i=0; i<inPixels.length; i++) {
  34. int argb = inPixels[i];
  35. int r = (argb >> 16) & 0xff;
  36. int g = (argb >>  8) & 0xff;
  37. int b = (argb) & 0xff;
  38. pixelsf[i][0] = 0.299f  *r + 0.587f *g + 0.114f  *b; // Y
  39. pixelsf[i][1] = 0.5957f *r - 0.2744f*g - 0.3212f *b; // I
  40. pixelsf[i][2] = 0.2114f *r - 0.5226f*g + 0.3111f *b; // Q
  41. }
  42. int index = 0;
  43. float shift = 0;
  44. float repetition = 0;
  45. float radius2 = radius * radius;
  46. float dis2 = colorDistance * colorDistance;
  47. for(int row=0; row<height; row++) {
  48. int ta = 255, tr = 0, tg = 0, tb = 0;
  49. for(int col=0; col<width; col++) {
  50. int xc = col;
  51. int yc = row;
  52. int xcOld, ycOld;
  53. float YcOld, IcOld, QcOld;
  54. index = row*width + col;
  55. float[] yiq = pixelsf[index];
  56. float Yc = yiq[0];
  57. float Ic = yiq[1];
  58. float Qc = yiq[2];
  59. repetition = 0;
  60. do {
  61. xcOld = xc;
  62. ycOld = yc;
  63. YcOld = Yc;
  64. IcOld = Ic;
  65. QcOld = Qc;
  66. float mx = 0;
  67. float my = 0;
  68. float mY = 0;
  69. float mI = 0;
  70. float mQ = 0;
  71. int num=0;
  72. for (int ry=-radius; ry <= radius; ry++) {
  73. int y2 = yc + ry;
  74. if (y2 >= 0 && y2 < height) {
  75. for (int rx=-radius; rx <= radius; rx++) {
  76. int x2 = xc + rx;
  77. if (x2 >= 0 && x2 < width) {
  78. if (ry*ry + rx*rx <= radius2) {
  79. yiq = pixelsf[y2*width + x2];
  80. float Y2 = yiq[0];
  81. float I2 = yiq[1];
  82. float Q2 = yiq[2];
  83. float dY = Yc - Y2;
  84. float dI = Ic - I2;
  85. float dQ = Qc - Q2;
  86. if (dY*dY+dI*dI+dQ*dQ <= dis2) {
  87. mx += x2;
  88. my += y2;
  89. mY += Y2;
  90. mI += I2;
  91. mQ += Q2;
  92. num++;
  93. }
  94. }
  95. }
  96. }
  97. }
  98. }
  99. float num_ = 1f/num;
  100. Yc = mY*num_;
  101. Ic = mI*num_;
  102. Qc = mQ*num_;
  103. xc = (int) (mx*num_+0.5);
  104. yc = (int) (my*num_+0.5);
  105. int dx = xc-xcOld;
  106. int dy = yc-ycOld;
  107. float dY = Yc-YcOld;
  108. float dI = Ic-IcOld;
  109. float dQ = Qc-QcOld;
  110. shift = dx*dx+dy*dy+dY*dY+dI*dI+dQ*dQ;
  111. repetition++;
  112. }
  113. while (shift > 3 && repetition < 100);
  114. tr = (int)(Yc + 0.9563f*Ic + 0.6210f*Qc);
  115. tg = (int)(Yc - 0.2721f*Ic - 0.6473f*Qc);
  116. tb = (int)(Yc - 1.1070f*Ic + 1.7046f*Qc);
  117. outPixels[index] = (ta << 24) | (tr << 16) | (tg << 8) | tb;
  118. }
  119. }
  120. setRGB( dest, 0, 0, width, height, outPixels );
  121. return dest;
  122. }
  123. public String toString() {
  124. System.out.println("Mean Shift Filter...");
  125. return "MeanShiftFilter";
  126. }
  127. }

图像处理------Mean Shift滤波(边缘保留的低通滤波)的更多相关文章

  1. 跟我学Python图像处理丨傅里叶变换之高通滤波和低通滤波

    摘要:本文讲解基于傅里叶变换的高通滤波和低通滤波. 本文分享自华为云社区<[Python图像处理] 二十三.傅里叶变换之高通滤波和低通滤波>,作者:eastmount . 一.高通滤波 傅 ...

  2. OpenCV计算机视觉学习(10)——图像变换(傅里叶变换,高通滤波,低通滤波)

    如果需要处理的原图及代码,请移步小编的GitHub地址 传送门:请点击我 如果点击有误:https://github.com/LeBron-Jian/ComputerVisionPractice 在数 ...

  3. python实现直方图均衡化,理想高通滤波与高斯低通滤波

    写在前面 HIT大三上学期视听觉信号处理课程中视觉部分的实验二,经过和学长们实验的对比发现每一级实验要求都不一样,因此这里标明了是2019年秋季学期的视觉实验二. 由于时间紧张,代码没有进行任何优化, ...

  4. blur()低通滤波

    blur()函数可以用标准化的盒式过滤器来平滑图像. C++ API: 相关官网资料: https://docs.opencv.org/3.4.1/d4/d86/group__imgproc__fil ...

  5. 机器学习进阶-直方图与傅里叶变换-傅里叶变换(高低通滤波) 1.cv2.dft(进行傅里叶变化) 2.np.fft.fftshift(将低频移动到图像的中心) 3.cv2.magnitude(计算矩阵的加和平方根) 4.np.fft.ifftshift(将低频和高频移动到原来位置) 5.cv2.idft(傅里叶逆变换)

    1. cv2.dft(img, cv2.DFT_COMPLEX_OUTPUT) 进行傅里叶变化 参数说明: img表示输入的图片, cv2.DFT_COMPLEX_OUTPUT表示进行傅里叶变化的方法 ...

  6. OpenCV笔记(4)(直方图、傅里叶变换、高低通滤波)

    一.直方图 用于统计图片中各像素值: # 画一个图像各通道的直方图 def draw_hist(img): color = ('b', 'g', 'r') for i, col in enumerat ...

  7. 9、OpenCV Python 边缘保留滤波

    __author__ = "WSX" import cv2 as cv import numpy as np # 边缘保留滤波 十分重要(美颜的核心) # 高斯双边模糊(考虑到了像 ...

  8. opencv:边缘保留滤波

    EPF滤波概述 均值与滤波的缺点:并没有考虑中心像素点对整个输出像素的贡献,实际上锚定的那个点贡献应该是最大的 高斯滤波的缺点:当边缘值梯度很大的时候,应减少中心像素点的权重,而高斯滤波没有考虑 边缘 ...

  9. opencv python:边缘保留滤波(EPF)

    EPF:E边缘,P保留,F滤波 import cv2 as cv import numpy as np def bi_demo(image): # bilateralFilter(src, d, si ...

随机推荐

  1. [DeeplearningAI笔记]神经网络与深度学习4.深度神经网络

    觉得有用的话,欢迎一起讨论相互学习~Follow Me 4.2 深层神经网络中的前向传播 4.3 核对矩阵的维数 经验方法论 对于神经网络想增加得到没有bug的程序的概率的方法:需要仔细的思考矩阵的维 ...

  2. xBIM 应用与学习 (一)

    目录 xBIM 应用与学习 (一) xBIM 应用与学习 (二) xBIM 基本的模型操作 xBIM 日志操作 XBIM 3D 墙壁案例 xBIM 格式之间转换 xBIM 使用Linq 来优化查询 x ...

  3. SpringMVC源码情操陶冶-AbstractHandlerMethodMapping

    承接前文SpringMVC源码情操陶冶-AbstractHandlerMapping,本文将介绍如何注册HandlerMethod对象作为handler 类结构瞧一瞧 public abstract ...

  4. NOIP 2017 Day 0. 游记

    刚从曲师大试机回来... 不巧,我抽到了和去年一样的考场,还是那么难用的XP,还是那么难用的键盘. 似乎在考场上有一股奇怪的力量,我本来在自己电脑上打板子打的没那么快,但是试机的那段时间..说出来你们 ...

  5. BZOJ 4108: [Wf2015]Catering [上下界费用流]

    4108: [Wf2015]Catering 题意:有一家装备出租公司收到了按照时间顺序排列的n个请求. 这家公司有k个搬运工.每个搬运工可以搬着一套装备按时间顺序去满足一些请求.一个搬运工从第i个请 ...

  6. BZOJ 2724: [Violet 6]蒲公英 [分块 区间众数]

    传送门 题面太美不忍不放 分块分块 这种题的一个特点是只有查询,通常需要预处理:加入修改的话需要暴力重构预处理 预处理$f[i][j]$为第i块到第j块的众数,显然$f[i][j]=max{f[i][ ...

  7. 51Nod 欢乐手速场1 A Pinball[DP 线段树]

    Pinball xfause (命题人)   基准时间限制:1 秒 空间限制:262144 KB 分值: 20 Pinball的游戏界面由m+2行.n列组成.第一行在顶端.一个球会从第一行的某一列出发 ...

  8. Scrapy框架实战-妹子图爬虫

    Scrapy这个成熟的爬虫框架,用起来之后发现并没有想象中的那么难.即便是在一些小型的项目上,用scrapy甚至比用requests.urllib.urllib2更方便,简单,效率也更高.废话不多说, ...

  9. 在CentOS 6.x上配合Windows客户端搭建 git(gitosis)服务器

    一.在 CentOS 上安装 git 和 gitosis: 逐条执行如下语句: sudo yum install git python-setuptools cd /opt sudo git clon ...

  10. 自己写的一个vii总结

    #include<stdlib.h>#include<stdio.h>#include<unistd.h>#include<errno.h>#inclu ...