图像处理------Mean Shift滤波(边缘保留的低通滤波) 分类: 视频图像处理 2015-07-24 14:55 45人阅读 评论(0) 收藏

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

版权声明:本文为博主原创文章,未经博主允许不得转载。

原文地址:https://www.cnblogs.com/mao0504/p/4705508.html