// ---------------// // isExtensionOf // // ---------------// public boolean isExtensionOf( Stick other, int maxDeltaCoord, int maxDeltaPos, double maxDeltaSlope) { // Check that a pair of start/stop is compatible if ((Math.abs(other.getStart() - getStop()) <= maxDeltaCoord) || (Math.abs(other.getStop() - getStart()) <= maxDeltaCoord)) { // Check that a pair of positions is compatible if ((Math.abs(other.getLine().yAt(other.getStart()) - getLine().yAt(other.getStop())) <= maxDeltaPos) || (Math.abs(other.getLine().yAt(other.getStop()) - getLine().yAt(other.getStart())) <= maxDeltaPos)) { // Check that slopes are compatible (a useless test ?) if (Math.abs(other.getLine().getSlope() - getLine().getSlope()) <= maxDeltaSlope) { return true; } else if (logger.isFineEnabled()) { logger.fine("isExtensionOf: Incompatible slopes"); } } else if (logger.isFineEnabled()) { logger.fine("isExtensionOf: Incompatible positions"); } } else if (logger.isFineEnabled()) { logger.fine("isExtensionOf: Incompatible coordinates"); } return false; }
// -------------// // computeLine // // -------------// public void computeLine() { line = new BasicLine(); for (GlyphSection section : glyph.getMembers()) { StickSection ss = (StickSection) section; line.includeLine(ss.getLine()); } if (logger.isFineEnabled()) { logger.fine( line + " pointNb=" + line.getNumberOfPoints() + " meanDistance=" + (float) line.getMeanDistance()); } }
// ------------------// // getAlienPixelsIn // // ------------------// public int getAlienPixelsIn(Rectangle area) { int count = 0; final int posMin = area.y; final int posMax = (area.y + area.height) - 1; final List<GlyphSection> neighbors = glyph.getLag().getSectionsIn(area); for (GlyphSection section : neighbors) { // Keep only non-patch sections that are not part of the stick if (!section.isPatch() && (section.getGlyph() != glyph)) { int pos = section.getFirstPos() - 1; // Ordinate for horizontal, // Abscissa for vertical for (Run run : section.getRuns()) { pos++; if (pos > posMax) { break; } if (pos < posMin) { continue; } int coordMin = Math.max(area.x, run.getStart()); int coordMax = Math.min((area.x + area.width) - 1, run.getStop()); if (coordMax >= coordMin) { count += (coordMax - coordMin + 1); } } } } if (logger.isFineEnabled()) { logger.fine("Stick" + glyph.getId() + " " + area + " getAlienPixelsIn=" + count); } return count; }
/** * In a specified system, look for all stems that should not be kept, rebuild surrounding glyphs * and try to recognize them. If this action does not lead to some recognized symbol, then we * restore the stems. * * @return the number of symbols recognized */ public int runStemPattern() { int nb = 0; // Collect all undue stems List<Glyph> SuspectedStems = new ArrayList<Glyph>(); for (Glyph glyph : system.getGlyphs()) { if (glyph.isStem() && glyph.isActive()) { Set<Glyph> goods = new HashSet<Glyph>(); Set<Glyph> bads = new HashSet<Glyph>(); glyph.getSymbolsBefore(reliableStemSymbols, goods, bads); glyph.getSymbolsAfter(reliableStemSymbols, goods, bads); if (goods.isEmpty()) { if (logger.isFineEnabled()) { logger.finest("Suspected Stem " + glyph); } SuspectedStems.add(glyph); // Discard "bad" ones for (Glyph g : bads) { if (logger.isFineEnabled()) { logger.finest("Deassigning bad glyph " + g); } g.setShape((Shape) null); } } } } // Remove these stem glyphs since nearby stems are used for recognition for (Glyph glyph : SuspectedStems) { system.removeGlyph(glyph); } // Extract brand new glyphs (removeInactiveGlyphs + retrieveGlyphs) system.extractNewGlyphs(); // Try to recognize each glyph in turn List<Glyph> symbols = new ArrayList<Glyph>(); final GlyphEvaluator evaluator = GlyphNetwork.getInstance(); final double maxDoubt = GlyphInspector.getPatternsMaxDoubt(); for (Glyph glyph : system.getGlyphs()) { if (glyph.getShape() == null) { Evaluation vote = evaluator.vote(glyph, maxDoubt); if (vote != null) { glyph.setShape(vote.shape, vote.doubt); if (glyph.isWellKnown()) { if (logger.isFineEnabled()) { logger.finest("New symbol " + glyph); } symbols.add(glyph); nb++; } } } } // Keep stems that have not been replaced by symbols, definitively // remove the others for (Glyph stem : SuspectedStems) { // Check if one of its section is now part of a symbol boolean known = false; Glyph glyph = null; for (GlyphSection section : stem.getMembers()) { glyph = section.getGlyph(); if ((glyph != null) && glyph.isWellKnown()) { known = true; break; } } if (!known) { // Remove the newly created glyph if (glyph != null) { system.removeGlyph(glyph); } // Restore the stem system.addGlyph(stem); } } return nb; }