// S&P, then regions sclass Gazelle22_ImageToRegions { BufferedImage inputImage; BWIntegralImage ii; SnPSettings snpSettings; BWImage posterized; BWImage_FastRegions regions; Map, Double> scoredRegions; bool wasRun; settable bool withDiagonals; // also walk diagonally? FunctionTimings timings; *(FunctionTimings *timings, BufferedImage *inputImage, SnPSettings *snpSettings) {} Decolorizer decolorizer() { ret snpSettings.decolorizer; } run { set wasRun; var decolorizer = decolorizer(); timings.do(decolorizer != null ? "bwIntegralImage w/decolorizer" : "bwIntegralImage", -> ii = bwIntegralImage_withMeta(inputImage, decolorizer)); timings.do("scaleAndPosterize", -> posterized = scaleAndPosterize(ii, snpSettings)); regions = new BWImage_FastRegions(posterized); regions.collectBounds(); regions.withDiagonals(withDiagonals); timings.do("Regions", regions); } // information about original screenshot if available ScreenShotMeta screenShotMeta() { ret optCast ScreenShotMeta(getMetaSrc(inputImage)); } Pt coordinatesFromScreen(Pt p) { var meta = screenShotMeta(); if (meta == null) null; var r = meta.bounds; if (!r.contains(p)) null; p = translatePt(p, -r.x, -r.y); ret scalePt(p, doubleRatio(snpSettings.pixelRows, r.h)); } Pt coordinatesToScreen(Pt p) { var meta = screenShotMeta(); if (meta == null) null; var r = meta.bounds; ret translatePt(r.x, r.y, scalePt(p, doubleRatio(r.h, snpSettings.pixelRows))); } BWImage_FastRegions regions aka get() { if (!wasRun) run(); ret regions; } int nRegions() { ret regions().nRegions(); } }