// Lookup table to speed up the last phase of G22RegionThinner_v2. // There are 256 possible neighborhood images for a 3x3 neighborhood // excluding the central pixel. // For each of these, we store whether the central pixel should be // deleted. sclass G22RegionThinner_LookupTable { byte[] table; *() { table = new byte[256/8]; for imgPattern to 256: setBit(table, imgPattern, calculatePattern(imgPattern)); } // imgPattern bit set = black bool calculatePattern(int imgPattern) { Image2B img = new(3, 3); imgPattern = ~imgPattern; img.setPixel(0, 0, testBit(imgPattern, 0)); img.setPixel(1, 0, testBit(imgPattern, 1)); img.setPixel(2, 0, testBit(imgPattern, 2)); img.setPixel(0, 1, testBit(imgPattern, 3)); img.setPixel(2, 1, testBit(imgPattern, 4)); img.setPixel(0, 2, testBit(imgPattern, 5)); img.setPixel(1, 2, testBit(imgPattern, 6)); img.setPixel(2, 2, testBit(imgPattern, 7)); var bwImage = img.toBW(); FastRegions_BWImage regionMaker = new(bwImage); regionMaker.withDiagonals(true); regionMaker.run(); // get all the black regions out of the 3x3 image var regions = regionMaker.regions(); regions = filter(regions, r -> r.brightness() == 0); bool delete = false; int pixels = 0; // no regions? it's a lonely pixel - keep it if (empty(regions)) {} else if (l(regions) == 1) { // one region pixels = first(regions).numberOfPixels(); // if it's only one or two pixels, we are at the end of a line - keep if (pixels <= lastPhaseThreshold1) delete = false; else { // delete pixel if the region is small, but not too small // (lastPhaseThreshold is 5 by default) if (pixels < lastPhaseThreshold) delete = true; else if (pixels == lastPhaseThreshold) { // if it's exactly 5 pixels, check out how far // the region "surrounds" the pixel (does it touch 2 or 3 sides?) // delete pixel if it is not surrounded int sides = 4-(int) (bwImage.getFloatPixel(1, 0) + bwImage.getFloatPixel(0, 1) + bwImage.getFloatPixel(2, 1) + bwImage.getFloatPixel(1, 2)); delete = sides < 3; } } } else // we have more than one region - pixel was // structurally important, keep it {} ret delete; } }