javaでmatlabのbwmorph(thin)関数を使いたいと思っていました。matlab ページでアルゴリズムを見つけました: http://www.mathworks.se/help/images/ref/bwmorph.html
そしてJavaで書きました:(画像の保存には、openCV Matデータ構造、基本的に2次元配列を使用します)
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));
}
}
そしてそれはうまくいきませんでした。薄くしようとしている画像:
マトラブの結果:
私のJavaコードの結果:
さらに何をすればよいかわかりません。前もって感謝します
編集: G3 と G3_ を修正しましたが、次のようになります。
これはmatlabのものとはまだ異なりますが、少し異なりますが、まさにそれが必要です