2013-11-07 5 views
1

Я хотел использовать функцию bwmorph (thin) matlab в java. Я нашел алгоритм на MatLab странице: http://www.mathworks.se/help/images/ref/bwmorph.htmlmatlab thinning algorithm java implementation

и написал в Java: (для сохранения изображений, я использую структуру данных OpenCV Mat, поясню 2d массив)

package pbl; 

import org.opencv.core.CvType; 
import org.opencv.core.Mat; 


public class Thinning { 

boolean B[][]; 

public Mat doJaniThinning(Mat Image) { 
B = new boolean[Image.rows()][Image.cols()]; 
boolean [][] B_ = new boolean[Image.rows()][Image.cols()]; 
    for(int i=0; i<Image.rows(); i++) 
     for(int j=0; j<Image.cols(); j++) 
        B[i][j] = (Image.get(i, j)[0]>100?false:true); //not a mistake, in matlab first invert and then morph 

    for(int iter = 0; iter < 1000; iter++) { 
      //Iteration #1 
      for(int i=0; i<Image.rows(); i++) 
       for(int j=0; j<Image.cols(); j++) 
        if(B[i][j] && G1(i, j) && G2(i, j) && G3(i, j)) B_[i][j] = false; 
        else B_[i][j] = B[i][j];; 

      for(int i=0; i<Image.rows(); i++) 
       for(int j=0; j<Image.cols(); j++) B[i][j] = B_[i][j]; 
      //Iteration #2 
      for(int i=0; i<Image.rows(); i++) 
       for(int j=0; j<Image.cols(); j++) 
        if(B[i][j] && G1(i, j) && G2(i, j) && G3_(i, j)) B_[i][j] = false; 
        else B_[i][j] = B[i][j]; 


      for(int i=0; i<Image.rows(); i++) 
       for(int j=0; j<Image.cols(); j++) B[i][j] = B_[i][j]; 
    } 


    Mat r = new Mat(Image.rows(), Image.cols(), CvType.CV_32SC1); 

    for(int i=0; i<Image.rows(); i++) 
      for(int j=0; j<Image.cols(); j++) { 
       int[] a = new int[1]; 
       a[0] = B[i][j]?255:0; 
       r.put(i, j, a); 
     } 


     return r; 
} 

public boolean x(int a, int i, int j) { 
    try { 
    switch(a) { 
     case 1: 
      return B[i+1][j]; 

     case 2: 
      return B[i+1][j+1]; 

     case 3: 
      return B[i][j+1]; 

     case 4: 
      return B[i-1][j+1]; 

     case 5: 
      return B[i-1][j]; 

     case 6: 
      return B[i-1][j-1]; 

     case 7: 
      return B[i][j-1]; 

     case 8: 
      return B[i+1][j-1]; 


    } 
    } catch(IndexOutOfBoundsException e) { 
    return false; 
    } 
    return false; 
} 

public boolean G1(int i, int j) { 
    int X = 0; 
    for(int q=1; q<=4; q++) { 
     if(!x(2*q-1, i, j) && (x(2*q, i, j) || x(2*q+1, i, j))) X++; 
    } 
    return X==1; 
} 

public boolean G2(int i, int j) { 
    int m = Math.min(n1(i, j), n2(i, j)); 
    return (m==2 || m==3); 
} 

public int n1(int i, int j) { 
    int r = 0; 
    for(int q=1; q<=4; q++) 
     if(x(2*q-1, i, j) || x(2*q, i, j)) r++; 
    return r; 
} 

public int n2(int i, int j) { 
    int r = 0; 
    for(int q=1; q<=4; q++) 
     if(x(2*q, i, j) || x(2*q+1, i, j)) r++; 
    return r; 
} 

public boolean G3(int i, int j) { 
    return !(x(2, i, j) || x(3, i, j) || !x(8, i, j) && x(1, i, j)); 
} 

public boolean G3_(int i, int j) { 
    return !(x(6, i, j) || x(7, i, j) || !x(4, i, j) && x(5, i, j)); 
} 





} 

и это не сработало. Изображение пытается тонкий:

enter image description here

Matlab результат:

enter image description here

Мой ява код результата:

enter image description here

Не знаю, что делать больше, любая помощь? Заранее спасибо

EDIT: I Исправленный G3 и G3_, но теперь я получаю:

enter image description here

Что еще отличается от MATLAB один, немного отличается, но мне нужно точно, что один

+0

PS Для openCV findcountours версия MATLAB идеальна, но моя реализация прореживания Matlab - это катастрофа, поэтому я хочу точно такой же –

+0

. Вы могли найти свою ошибку в конце концов? –

ответ

2

Я думаю, что G3 и G3_ являются неправильными:

public boolean G3(int i, int j) { 
    return (x(2, i, j) || x(3, i, j) || !x(8, i, j)) && x(1, i, j); 
} 

public boolean G3_(int i, int j) { 
    return (x(6, i, j) || x(7, i, j) || !x(4, i, j)) && x(5, i, j); 
} 
+0

Спасибо! но все еще должна быть какая-то проблема, ответ по-прежнему немного отличается, дает огромную разницу в анализе openCV –

+0

Я не вижу другой ошибки. Я бы рекомендовал вам использовать некоторую реализацию алгоритма с открытым исходным кодом и сравнить его шаг за шагом. Если вы привыкли к matlab, я бы использовал реализацию октавы. Синтаксис почти идентичен, функция также называется bwmorph.m. – Daniel