zoukankan      html  css  js  c++  java
  • 图像处理------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. }  

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

  • 相关阅读:
    Codeforces Round #401 (Div. 2)解题报告
    ICM Technex 2017 and Codeforces Round #400 (Div. 1 + Div. 2, combined) 解题报告
    (线段树)hdoj 3308-LCIS
    Codeforces Round #399 (Div. 1 + Div. 2, combined) D题Jon and Orbs(dp)解题报告
    2019 Multi-University Training Contest 1
    2019 Multi-University Training Contest 6
    2019牛客暑期多校训练营(第八场)
    模板
    2019 Multi-University Training Contest 8
    2019 Multi-University Training Contest 9
  • 原文地址:https://www.cnblogs.com/mao0504/p/4705508.html
Copyright © 2011-2022 走看看