2012-03-10 3 views
4

私は平均シフトセグメンテーションのスタッフをしています。私はEDISON(http://coewww.rutgers.edu/riul/research/code/EDISON/)というコードを見つけました。これは良いコードを実装しています。また、opencvにはcvPyrMeanShiftFilteringという機能があります。EDISONとcvPyrMeanShiftFilteringの違いは何ですか

ただし、次の図では異なります。 EDISONシステムでは、2つのパラメータは7 & 6.5です。 opencvでは、私は cvPyrMeanShiftFiltering(result, result, 7, 6.5,level);を使用しています(結果はすでにLUVに変換されています)。右のイメージには境界線が表示されていません。私もレベル= 0を試しました...

誰でも助けることができますか?私はopenCVの助けを借りて同じ結果を達成したいと思います。

Comparison

答えて

3

は私がrsbwebから別のコードを試してみました(私はすでにクラスタリングステップを実装しました)...と効果はOpenCVのよりもはるかに優れています!

は、ここで私はより良い結果を得るためにではなくYIQよりマブラヴを使用して、コードの一部を変更し、私の新しい結果

Mean Shift Filter

です。ここで

easyrgbが私のコードであるから、色の方程式は、

import java.awt.image.BufferedImage; 
import java.io.File; 
import java.io.IOException; 

import javax.imageio.ImageIO; 


public class test { 

public static void main(String[] args) throws IOException { 
    BufferedImage img = ImageIO.read(new File("2.png")); 
    filterRGBImage(img); 
    ImageIO.write(img, "png", new File("3.png")); 
} 

private static int rad = 10, rad2=rad*rad; 
private static double radCol2 = Math.pow(10,2); 

private static void RGB2XYZ(double rgb[], double xyz[]) 
{ 
    double var_R = (rgb[0]/255.),var_G = (rgb[1]/255.),var_B = (rgb[2]/255.); 

    if (var_R > 0.04045) 
     var_R = Math.pow(((var_R + 0.055)/1.055),2.4); 
    else     
     var_R = var_R/12.92; 
    if (var_G > 0.04045) 
     var_G = Math.pow((var_G + 0.055)/1.055 , 2.4); 
    else     
     var_G = var_G/12.92; 
    if (var_B > 0.04045) 
     var_B = Math.pow((var_B + 0.055)/1.055 ,2.4); 
    else     
     var_B = var_B/12.92; 

    var_R = var_R * 100; 
    var_G = var_G * 100; 
    var_B = var_B * 100; 

    xyz[0] = var_R * 0.4124 + var_G * 0.3576 + var_B * 0.1805; 
    xyz[1] = var_R * 0.2126 + var_G * 0.7152 + var_B * 0.0722; 
    xyz[2] = var_R * 0.0193 + var_G * 0.1192 + var_B * 0.9505; 
} 

private static void XYZ2RGB(double xyz[], double rgb[]) 
{ 
    double var_X = xyz[0]/100, var_Y = xyz[1]/100 , var_Z = xyz[2]/100; 

    double var_R = var_X * 3.2406 + var_Y * -1.5372 + var_Z * -0.4986, 
      var_G = var_X * -0.9689 + var_Y * 1.8758 + var_Z * 0.0415, 
      var_B = var_X * 0.0557 + var_Y * -0.2040 + var_Z * 1.0570; 

      if (var_R > 0.0031308) 
       var_R = 1.055 * Math.pow(var_R, 1/2.4 ) - 0.055; 
      else      
       var_R = 12.92 * var_R; 
      if (var_G > 0.0031308) 
       var_G = 1.055 * Math.pow(var_G , 1/2.4) - 0.055; 
      else      
       var_G = 12.92 * var_G; 
      if (var_B > 0.0031308) 
       var_B = 1.055 * Math.pow(var_B ,1/2.4) - 0.055; 
      else      
       var_B = 12.92 * var_B; 

      rgb[0] = var_R * 255; 
      rgb[1] = var_G * 255; 
      rgb[2] = var_B * 255 ; 
} 
private static void XYZ2Luv(double xyz[], double luv[]) 
{ 
    double var_U = (4 * xyz[0])/(xyz[0] + (15 * xyz[1]) + (3 * xyz[2])), 
      var_V = (9 * xyz[1])/(xyz[0] + (15 * xyz[1]) + (3 * xyz[2])), 
      var_Y = xyz[1]/100; 
    if (var_Y > 0.008856) 
     var_Y = Math.pow(var_Y, 1./3); 
    else      
     var_Y = (7.787 * var_Y) + (16./116); 

    double ref_X = 95.047, ref_Y = 100.000, ref_Z = 108.883; 

    double ref_U = (4 * ref_X)/(ref_X + (15 * ref_Y) + (3 * ref_Z)), 
      ref_V = (9 * ref_Y)/(ref_X + (15 * ref_Y) + (3 * ref_Z)); 

    luv[0] = (116 * var_Y) - 16; 
    luv[1] = 13 * luv[0] * (var_U - ref_U); 
    luv[2] = 13 * luv[0] * (var_V - ref_V); 
} 
private static void Luv2XYZ(double luv[],double xyz[]) 
{ 
    double var_Y = (luv[0] + 16)/116; 
      if (Math.pow(var_Y,3) > 0.008856) 
       var_Y = Math.pow(var_Y,3); 
      else      
       var_Y = (var_Y - 16./ 116)/7.787; 

    double ref_X = 95.047 ,ref_Y = 100.000,ref_Z = 108.883; 

    double  ref_U = (4 * ref_X)/(ref_X + (15 * ref_Y) + (3 * ref_Z)), 
      ref_V = (9 * ref_Y)/(ref_X + (15 * ref_Y) + (3 * ref_Z)); 

    double var_U = luv[1]/(13 * luv[0]) + ref_U, 
      var_V =luv[2]/(13 * luv[0]) + ref_V; 

    xyz[1] = var_Y * 100; 
    xyz[0] = - (9 * xyz[1] * var_U)/((var_U - 4) * var_V - var_U * var_V); 
    xyz[2] = (9 * xyz[1] - (15 * var_V * xyz[1]) - (var_V * xyz[0]))/(3 * var_V);  
} 
//http://rsbweb.nih.gov/ij/plugins/download/Mean_Shift.java 
public static void filterRGBImage(BufferedImage ip) { 
    int width = ip.getWidth(); 
    int height = ip.getHeight(); 
    double[][][] pixelsf = new double[width][height][3]; 

    for (int y=0; y<height; y++) { 
     for (int x=0; x<width; x++) { 
      int argb = ip.getRGB(x,y); 

      int r = (argb >> 16) & 0xff; 
      int g = (argb >> 8) & 0xff; 
      int b = (argb) & 0xff; 

      // YIQ 
      /*pixelsf[x][y][0] = 0.299f *r + 0.587f *g + 0.114f *b; 
      pixelsf[x][y][1] = 0.5957f *r - 0.2744f*g - 0.3212f *b; 
      pixelsf[x][y][2] = 0.2114f *r - 0.5226f*g + 0.3111f *b;*/ 
      double tmp[]={r,g,b},tmp2[]={0,0,0}; 
      RGB2XYZ(tmp,tmp2); 
      XYZ2Luv(tmp2,pixelsf[x][y]); 
     } 
    } 

    double shift = 0; 
    int iters = 0; 
    for (int y=0; y<height; y++) { 
     for (int x=0; x<width; x++) { 

      int xc = x; 
      int yc = y; 
      int xcOld, ycOld; 
      double YcOld, IcOld, QcOld; 
      double Yc = pixelsf[x][y][0]; 
      double Ic = pixelsf[x][y][1]; 
      double Qc = pixelsf[x][y][2]; 

      iters = 0; 
      do { 
       xcOld = xc; 
       ycOld = yc; 
       YcOld = Yc; 
       IcOld = Ic; 
       QcOld = Qc; 

       float mx = 0; 
       float my = 0; 
       float mY = 0; 
       float mI = 0; 
       float mQ = 0; 
       int num=0; 

       for (int ry=-rad; ry <= rad; ry++) { 
        int y2 = yc + ry; 
        if (y2 >= 0 && y2 < height) { 
         for (int rx=-rad; rx <= rad; rx++) { 
          int x2 = xc + rx; 
          if (x2 >= 0 && x2 < width) { 
           //if (ry*ry + rx*rx <= rad2) { 
            double Y2 = pixelsf[x2][y2][0]; 
            double I2 = pixelsf[x2][y2][1]; 
            double Q2 = pixelsf[x2][y2][2]; 

            double dY = Yc - Y2; 
            double dI = Ic - I2; 
            double dQ = Qc - Q2; 

            if (dY*dY+dI*dI+dQ*dQ <= radCol2) { 
             mx += x2; 
             my += y2; 
             mY += Y2; 
             mI += I2; 
             mQ += Q2; 
             num++; 
            } 
           //} 
          } 
         } 
        } 
       } 
       double num_ = 1./num; 
       Yc = mY*num_; 
       Ic = mI*num_; 
       Qc = mQ*num_; 
       xc = (int) (mx*num_+0.5); 
       yc = (int) (my*num_+0.5); 
       int dx = xc-xcOld; 
       int dy = yc-ycOld; 
       double dY = Yc-YcOld; 
       double dI = Ic-IcOld; 
       double dQ = Qc-QcOld; 

       shift = dx*dx+dy*dy+dY*dY+dI*dI+dQ*dQ; 
       iters++; 
      } 
      while (shift > 3 && iters < 100); 

      double tmp[]={Yc,Ic,Qc},tmp2[]={0,0,0}; 
      Luv2XYZ(tmp,tmp2); 
      XYZ2RGB(tmp2,tmp); 
      int r_ = (int) tmp[0]; 
      int g_ = (int) tmp[1]; 
      int b_ = (int) tmp[2]; 

      ip.setRGB(x, y, (0xFF<<24)|(r_<<16)|(g_<<8)|b_); 
     } 

    } 
} 
} 
関連する問題