// Catalano Imaging Library
// The Catalano Framework
//
// Copyright © Diego Catalano, 2012-2016
// diego.catalano at live.com
//
// Code adapted from ImageJ, thanks to Wayne Rasband.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
//
package Catalano.Imaging.Filters;
import Catalano.Imaging.FastBitmap;
import Catalano.Imaging.IApplyInPlace;
/**
* Zhang-Suen Thinning.
* @author Diego Catalano
*/
public class ZhangSuenThinning implements IApplyInPlace{
private int[] table =
{0,0,0,0,0,0,1,3,0,0,3,1,1,0,1,3,0,0,0,0,0,0,0,0,0,0,2,0,3,0,3,3,
0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,3,0,2,2,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2,0,0,0,0,0,0,0,2,0,0,0,2,0,0,0,3,0,0,0,0,0,0,0,3,0,0,0,3,0,2,0,
0,0,3,1,0,0,1,3,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
3,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2,3,1,3,0,0,1,3,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2,3,0,1,0,0,0,1,0,0,0,0,0,0,0,0,3,3,0,1,0,0,0,0,2,2,0,0,2,0,0,0};
private int[] table2 =
{0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,2,2,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
/**
* Initialize a new instance of the ZhangSuenThinning class.
*/
public ZhangSuenThinning() {}
@Override
public void applyInPlace(FastBitmap fastBitmap) {
if (fastBitmap.isGrayscale()) {
int pass = 0;
int pixelsRemoved;
do {
pixelsRemoved = thin(pass++, table, fastBitmap);
pixelsRemoved += thin(pass++, table, fastBitmap);
} while (pixelsRemoved>0);
do {
// use a second table to remove "stuck" pixels
pixelsRemoved = thin(pass++, table2, fastBitmap);
pixelsRemoved += thin(pass++, table2, fastBitmap);
} while (pixelsRemoved>0);
}
else{
throw new IllegalArgumentException("Zhang Suen Thinning only works with grayscale image.");
}
}
private int thin(int pass, int[] table, FastBitmap fastBitmap) {
int p1, p2, p3, p4, p5, p6, p7, p8, p9;
int height = fastBitmap.getHeight();
int width = fastBitmap.getWidth();
byte[] pixels = fastBitmap.getGrayData();
byte[] pixels2 = new byte[width * height];
System.arraycopy(fastBitmap.getGrayData(), 0, pixels2, 0, width * height);
int v, index, code;
int offset, rowOffset = width;
int pixelsRemoved = 0;
for (int y=1; y<=height - 2; y++) {
offset = y * width + 1;
for (int x=1; x<=width - 2; x++) {
p5 = pixels2[offset];
v = p5;
if (v!=0) {
p1 = pixels2[offset-rowOffset-1];
p2 = pixels2[offset-rowOffset];
p3 = pixels2[offset-rowOffset+1];
p4 = pixels2[offset-1];
p6 = pixels2[offset+1];
p7 = pixels2[offset+rowOffset-1];
p8 = pixels2[offset+rowOffset];
p9 = pixels2[offset+rowOffset+1];
index = 0;
if (p1!=0) index |= 1;
if (p2!=0) index |= 2;
if (p3!=0) index |= 4;
if (p6!=0) index |= 8;
if (p9!=0) index |= 16;
if (p8!=0) index |= 32;
if (p7!=0) index |= 64;
if (p4!=0) index |= 128;
code = table[index];
if ((pass&1)==1) { //odd pass
if (code==2||code==3) {
v = 0;
pixelsRemoved++;
}
} else { //even pass
if (code==1||code==3) {
v = 0;
pixelsRemoved++;
}
}
}
pixels[offset++] = (byte)v;
}
}
return pixelsRemoved;
}
}
Ads help maintain this website.