matlab bwmorph(img,thin';)在Java中的实现出错
我正在Java ImageJ中实现matlab的“bwmorph(img,'thin')”算法。我在网上搜索了很多,发现了一些类似的实现,它们工作得更好,但我在代码中找不到问题所在。有什么想法吗 我的代码:matlab bwmorph(img,thin';)在Java中的实现出错,java,matlab,image-processing,imagej,Java,Matlab,Image Processing,Imagej,我正在Java ImageJ中实现matlab的“bwmorph(img,'thin')”算法。我在网上搜索了很多,发现了一些类似的实现,它们工作得更好,但我在代码中找不到问题所在。有什么想法吗 我的代码: public void run(ImageProcessor ip) { MakeBinary(ip); int sum2 = processThin(ip); int sum = -1; while (sum2 !=
public void run(ImageProcessor ip) {
MakeBinary(ip);
int sum2 = processThin(ip);
int sum = -1;
while (sum2 != sum) {
sum = sum2;
sum2 = processThin(ip);
}
}
public int processThin(ImageProcessor ipOriginal) {
int sum = 0;
// first iteration
ImageProcessor ip = ipOriginal.duplicate();
for (int i = 1; i < ip.getWidth() -1; i++)
for (int j = 1; j < ip.getHeight() -1; j++) {
int[] neighbors = selectNeighbors(ip, i, j);
if (G1(neighbors) == 1 && G2(neighbors) >= 2 && G2(neighbors) <= 3 && G3(neighbors) == 0)
ip.putPixel(i,j, 0);
}
// second iteration
for (int i = 1; i < ip.getWidth() -1; i++)
for (int j = 1; j < ip.getHeight()-1; j++) {
int[] neighbors = selectNeighbors(ip, i, j);
if (G1(neighbors) == 1 && G2(neighbors) >= 2 && G2(neighbors) <= 3 && G3prime(neighbors) == 0)
ip.putPixel(i,j, 0);
}
for(int i = 0; i < ip.getWidth(); i++)
for(int j = 0; j < ip.getHeight(); j++) {
if (ip.getPixel(i,j) != 0) sum++;
ipOriginal.putPixel(i, j, ip.getPixel(i, j));
}
return sum;
}
private int G1(int[] input) {
int xh = 0;
for (int i = 1; i <= 4; i++) {
if (input[2 * i - 1] == 0 && (input[2 * i] == 1 || (2 * i + 1 <= 8 ? input[2 * i + 1] == 1 : input[1] == 1)))
xh += 1;
}
return xh;
}
private int G2(int[] input) {
int n1 = 0, n2 = 0;
n1 = toInt(toBool(input[4]) || toBool(input[3])) + toInt(toBool(input[1]) || toBool(input[2])) +
toInt(toBool(input[8]) || toBool(input[7])) + toInt(toBool(input[6]) || toBool(input[5]));
n2 = toInt(toBool(input[2]) || toBool(input[3])) + toInt(toBool(input[1]) || toBool(input[8])) +
toInt(toBool(input[6]) || toBool(input[7])) + toInt(toBool(input[4]) || toBool(input[5]));
return Math.min(n1,n2);
}
private int G3 (int[] input){
return toInt((toBool(input[2]) || toBool(input[3]) || !toBool(input[8])) && toBool(input[1]));
}
private int G3prime (int[] input){
return toInt((toBool(input[6]) || toBool(input[7]) || !toBool(input[4])) && toBool(input[5]));
}
private boolean toBool(int i ){
return i == 1;
}
private int toInt(boolean i) {
return i ? 1 : 0;
}
private int[] selectNeighbors(ImageProcessor ip, int i, int j) {
int[] result = new int[9];
result[1] = ip.getPixel(i+1,j);
result[2] = ip.getPixel(i+1,j+1);
result[3] = ip.getPixel(i,j+1);
result[4] = ip.getPixel(i-1,j+1);
result[5] = ip.getPixel(i-1,j);
result[6] = ip.getPixel(i-1,j-1);
result[7] = ip.getPixel(i,j-1);
result[8] = ip.getPixel(i+1,j-1);
for (int x = 0; x < result.length; x++)
if (result[x] != 0) result[x] = 1;
return result;
}
原始代码中的问题是您将代码写入了输入图像。在第一次迭代中,从左向右移动,删除连续的像素,因为在修改前一个像素后,每个像素都有一个背景像素作为邻居 实现细化操作有不同的方法,但最简单的方法(如您的代码)需要在细化的每次迭代中通过两次图像:
您可以在输入图像中写入内容。因此,在第一次迭代中,从左向右移动,删除连续的像素,因为在修改前一个像素后,每个像素都有一个背景像素作为邻居。要在适当的位置工作,请在一个过程中标记要删除的每个像素,然后在第二个过程中将其设置为背景值。然后重复这个直到幂等。否则,请在每次迭代后写入不同的映像并交换输入/输出缓冲区。@CrisLuengo,谢谢您的回复。这很有帮助!编辑之后,我更接近我想要的。不过,现在我似乎丢失了一些中间像素。你能再看一次吗?我现在将编辑我的问题啊,是的,当决定是否删除一个像素时,你需要查看如果删除所有标记的像素,将保留的像素集。那么:像素在原始图像中是否有背景邻居?如果是,它是否保留了输出图像中的连接?@CrisLuengo,非常感谢!你愿意留下一个答案,我把它标为正确答案吗?
public int processThin(ImageProcessor ip) {
int sum = 0;
// first iteration
int[][] mask = new int[ip.getWidth()][ip.getHeight()];
for (int i = 1; i < ip.getWidth() -1; i++)
for (int j = 1; j < ip.getHeight() -1; j++) {
int[] neighbors = selectNeighbors(ip, i, j);
if (G1(neighbors) == 1 && G2(neighbors) >= 2 && G2(neighbors) <= 3 && G3(neighbors) == 0)
mask[i][j]++;
}
// second iteration
for (int i = 1; i < ip.getWidth() -1; i++)
for (int j = 1; j < ip.getHeight()-1; j++) {
int[] neighbors = selectNeighbors(ip, i, j);
if (G1(neighbors) == 1 && G2(neighbors) >= 2 && G2(neighbors) <= 3 && G3prime(neighbors) == 0)
mask[i][j]++;
}
for(int i = 0; i < ip.getWidth(); i++)
for(int j = 0; j < ip.getHeight(); j++) {
if (mask[i][j] != 0) sum++;
ip.putPixel(i, j, mask[i][j] > 0 ? 0 : ip.getPixel(i,j));
}
return sum;
}