Esempio n. 1
0
  /**
   * Check that each staff begins with a clef.
   *
   * @return the number of clefs rebuilt
   */
  @Override
  public int runPattern() {
    int successNb = 0;
    int staffId = 0;

    for (StaffInfo staff : system.getStaves()) {
      staffId++;

      // Define the inner box to intersect clef glyph(s)
      int left = (int) Math.rint(staff.getAbscissa(HorizontalSide.LEFT));
      Rectangle inner =
          new Rectangle(
              left + (2 * xOffset) + (clefWidth / 2),
              staff.getFirstLine().yAt(left) + (staff.getHeight() / 2),
              0,
              0);
      inner.grow((clefWidth / 2) - xOffset, (staff.getHeight() / 2) - yOffset);

      // Remember the box, for visual debug
      staff.addAttachment("  ci", inner);

      // We must find a clef out of these glyphs
      Collection<Glyph> glyphs = system.lookupIntersectedGlyphs(inner);
      logger.debug("{}{}", staffId, Glyphs.toString(" int", glyphs));

      // We assume than there can't be any alien among them, so we should
      // rebuild the larger glyph which the alien had wrongly segmented
      Set<Glyph> impacted = new HashSet<>();

      for (Glyph glyph : glyphs) {
        if (glyph.getShape() == Shape.STEM) {
          logger.debug("Clef: Removed stem#{}", glyph.getId());

          impacted.addAll(glyph.getConnectedNeighbors());
          impacted.add(glyph);
        }
      }

      if (!impacted.isEmpty()) {
        // Rebuild the larger glyph
        Glyph larger = system.buildCompound(impacted);
        if (larger != null) {
          logger.debug("Rebuilt stem-segmented {}", larger.idString());
        }

        // Recompute the set of intersected glyphs
        glyphs = system.lookupIntersectedGlyphs(inner);
      }

      if (checkClef(glyphs, staff)) {
        successNb++;
      }
    }

    return successNb;
  }
Esempio n. 2
0
  /**
   * Try to recognize a clef in the compound of the provided glyphs.
   *
   * @param glyphs the parts of a clef candidate
   * @param staff the containing staff
   * @return true if successful
   */
  private boolean checkClef(Collection<Glyph> glyphs, StaffInfo staff) {
    if (glyphs.isEmpty()) {
      return false;
    }

    // Check if we already have a clef among the intersected glyphs
    Set<Glyph> clefs = Glyphs.lookupGlyphs(glyphs, clefGlyphPredicate);
    Glyph orgClef = null;

    if (!clefs.isEmpty()) {
      if (Glyphs.containsManual(clefs)) {
        return false; // Respect user decision
      } else {
        // Remember grade of the best existing clef
        for (Glyph glyph : clefs) {
          if ((orgClef == null) || (glyph.getGrade() > orgClef.getGrade())) {
            orgClef = glyph;
          }
        }
      }
    }

    // Remove potential aliens
    Glyphs.purgeManuals(glyphs);

    Glyph compound = system.buildTransientCompound(glyphs);

    // Check if a clef appears in the top evaluations
    Evaluation vote =
        GlyphNetwork.getInstance().vote(compound, system, Grades.clefMinGrade, clefShapePredicate);

    if ((vote != null) && ((orgClef == null) || (vote.grade > orgClef.getGrade()))) {
      // We now have a clef!
      // Look around for an even better result...
      logger.debug("{} built from {}", vote.shape, Glyphs.toString(glyphs));

      // Look for larger stuff
      Rectangle outer = compound.getBounds();
      outer.grow(xMargin, yMargin);

      // Remember the box, for visual debug
      staff.addAttachment("co", outer);

      List<Glyph> outerGlyphs = system.lookupIntersectedGlyphs(outer);
      outerGlyphs.removeAll(glyphs);
      Collections.sort(outerGlyphs, Glyph.byReverseWeight);

      final double minWeight = constants.minWeight.getValue();

      for (Glyph g : outerGlyphs) {
        // Consider only glyphs with a minimum weight
        if (g.getNormalizedWeight() < minWeight) {
          break;
        }

        logger.debug("Considering {}", g);

        Glyph newCompound = system.buildTransientCompound(Arrays.asList(compound, g));
        final Evaluation newVote =
            GlyphNetwork.getInstance()
                .vote(newCompound, system, Grades.clefMinGrade, clefShapePredicate);

        if ((newVote != null) && (newVote.grade > vote.grade)) {
          logger.debug("{} better built with {}", vote, g.idString());

          compound = newCompound;
          vote = newVote;
        }
      }

      // Register the last definition of the clef
      compound = system.addGlyph(compound);
      compound.setShape(vote.shape, Evaluation.ALGORITHM);

      logger.debug("{} rebuilt as {}", vote.shape, compound.idString());

      return true;
    } else {
      return false;
    }
  }