Zhang-Suen thinning algorithm: Difference between revisions

Updated D entry
(Go solution)
(Updated D entry)
Line 190:
 
=={{header|D}}==
This uses the module from the Bitmap Task. And it performs no heap allocations.
<lang d>import std.stdio, std.algorithm, std.string, std.functional,
std.typecons, std.typetuple, bitmap;
Line 205:
 
/// Zhang-Suen thinning algorithm.
Img zhangSuen(Img image1, Img image2) pure /*nothrow*/ @safe @nogc
in {
assert(image1.image.all!(x => x == Img.black || x == Img.white));
assert(image1.nx == image2.nx && image1.ny == image2.ny);
} out(result) {
assert(result.nx == image1.nx && result.ny == image1.ny);
Line 213 ⟶ 214:
} body {
/// True if inf <= x <= sup.
static inInterval(T)(in T x, in T inf, in T sup) pure nothrow @safe @nogc {
return x >= inf && x <= sup;
}
Line 219 ⟶ 220:
/// Return 8-neighbours+1 of point (x,y) of given image, in order.
static void neighbours(in Img I, in size_t x, in size_t y,
out Neighbours n) pure nothrow @safe @nogc {
n = [I[x,y-1], I[x+1,y-1], I[x+1,y], I[x+1,y+1], // P2,P3,P4,P5
I[x,y+1], I[x-1,y+1], I[x-1,y], I[x-1,y-1], // P6,P7,P8,P9
Line 225 ⟶ 226:
}
 
if (image1.nx < 3 || image1.ny < 3) {
returnimage2.image[] = image1.image[];
return image2;
auto image2 = Img.fromData(image1.image.dup, image1.nx, image1.ny);
}
 
immutable static zeroOne = [0, 1]; //**
Neighbours n;
bool hasChanged;
Line 241 ⟶ 244:
(!n[ab[0]] || !n[4] || !n[6]) && // Cond. 4
(!n[0] || !n[2] || !n[ab[1]]) && // Cond. 3
//n[].count([0, 1]) == 1 && // Cond. 2
n[].count(zeroOne) == 1 && // Cond. 2
// n[0 .. 8].sum in iota(2, 7)) {
inInterval(n[0 .. 8].sum, 2, 6)) { // Cond. 1
Line 311 ⟶ 315:
img.textualShow(/*bl=*/ '.', /*wh=*/ '#');
"\nTo thinned:".writeln;
img.zhangSuen(img.dup).textualShow(/*bl=*/ '.', /*wh=*/ '#');
writeln;
}