Пример #1
0
  /**
   * Fits lines across the sequence of corners
   *
   * @param numLines number of lines it will fit
   */
  boolean fitLinesUsingCorners(int numLines, GrowQueue_I32 cornerIndexes) {
    for (int i = 1; i <= numLines; i++) {
      int index0 = cornerIndexes.get(CircularIndex.addOffset(anchor0, i - 1, cornerIndexes.size));
      int index1 = cornerIndexes.get(CircularIndex.addOffset(anchor0, i, cornerIndexes.size));

      if (index0 == index1) return false;

      if (!fitLine(index0, index1, lines.get(i - 1))) {
        // TODO do something more intelligent here.  Just leave the corners as is?
        return false;
      }
      LineGeneral2D_F64 l = lines.get(i - 1);
      if (Double.isNaN(l.A) || Double.isNaN(l.B) || Double.isNaN(l.C)) {
        throw new RuntimeException("This should be impossible");
      }
    }
    return true;
  }
Пример #2
0
  /** All the corners should be in increasing order from the first anchor. */
  boolean sanityCheckCornerOrder(int numLines, GrowQueue_I32 corners) {
    int contourAnchor0 = corners.get(anchor0);
    int previous = 0;
    for (int i = 1; i < numLines; i++) {
      int contourIndex = corners.get(CircularIndex.addOffset(anchor0, i, corners.size()));
      int pixelsFromAnchor0 = CircularIndex.distanceP(contourAnchor0, contourIndex, contour.size());

      if (pixelsFromAnchor0 < previous) {
        return false;
      } else {
        previous = pixelsFromAnchor0;
      }
    }
    return true;
  }
Пример #3
0
  /**
   * Given a sequence of points on the contour find the best fit line.
   *
   * @param contourIndex0 contour index of first point in the sequence
   * @param contourIndex1 contour index of last point (exclusive) in the sequence
   * @param line storage for the found line
   * @return true if successful or false if it failed
   */
  boolean fitLine(int contourIndex0, int contourIndex1, LineGeneral2D_F64 line) {
    int numPixels = CircularIndex.distanceP(contourIndex0, contourIndex1, contour.size());

    // if its too small
    if (numPixels < minimumLineLength) return false;

    Point2D_I32 c0 = contour.get(contourIndex0);
    Point2D_I32 c1 = contour.get(contourIndex1);

    double scale = c0.distance(c1);
    double centerX = (c1.x + c0.x) / 2.0;
    double centerY = (c1.y + c0.y) / 2.0;

    int numSamples = Math.min(20, numPixels);

    pointsFit.reset();
    for (int i = 0; i < numSamples; i++) {

      int index = i * (numPixels - 1) / (numSamples - 1);

      Point2D_I32 c = contour.get(CircularIndex.addOffset(contourIndex0, index, contour.size()));

      Point2D_F64 p = pointsFit.grow();
      p.x = (c.x - centerX) / scale;
      p.y = (c.y - centerY) / scale;
    }

    if (null == FitLine_F64.polar(pointsFit.toList(), linePolar)) {
      return false;
    }
    UtilLine2D_F64.convert(linePolar, line);

    // go from local coordinates into global
    line.C = scale * line.C - centerX * line.A - centerY * line.B;

    return true;
  }
Пример #4
0
  /** finds the intersection of a line and update the corner index */
  boolean linesIntoCorners(int numLines, GrowQueue_I32 contourCorners) {

    GrowQueue_I32 skippedCorners = new GrowQueue_I32();

    //		System.out.println("total corners "+contourCorners.size()+"  numLines "+numLines);
    int contourIndexPrevious = contourCorners.get(anchor0);
    for (int i = 1; i < numLines; i++) {
      LineGeneral2D_F64 line0 = lines.get(i - 1);
      LineGeneral2D_F64 line1 = lines.get(i);

      int cornerIndex = CircularIndex.addOffset(anchor0, i, contourCorners.size);
      boolean skipped = false;

      //			System.out.println("  corner index "+cornerIndex);

      if (null == Intersection2D_F64.intersection(line0, line1, intersection)) {
        if (verbose) System.out.println("  SKIPPING no intersection");
        // the two lines are parallel (or a bug earlier inserted NaN), so skip and remove one of
        // them
        skipped = true;
      } else {

        int contourIndex = closestPoint(intersection);
        if (contourIndex != contourIndexPrevious) {

          Point2D_I32 a = contour.get(contourIndexPrevious);
          Point2D_I32 b = contour.get(contourIndex);

          if (a.x == b.x && a.y == b.y) {
            if (verbose) System.out.println("  SKIPPING duplicate coordinate");
            //						System.out.println("  duplicate "+a+" "+b);
            skipped = true;
          } else {
            //						System.out.println("contourCorners[ "+cornerIndex+" ] = "+contourIndex);
            contourCorners.set(cornerIndex, contourIndex);
            contourIndexPrevious = contourIndex;
          }
        } else {
          if (verbose) System.out.println("  SKIPPING duplicate corner index");
          skipped = true;
        }
      }

      if (skipped) {
        skippedCorners.add(cornerIndex);
      }
    }
    // check the last anchor to see if there's a duplicate
    int cornerIndex = CircularIndex.addOffset(anchor0, numLines, contourCorners.size);
    Point2D_I32 a = contour.get(contourIndexPrevious);
    Point2D_I32 b = contour.get(contourCorners.get(cornerIndex));
    if (a.x == b.x && a.y == b.y) {
      skippedCorners.add(cornerIndex);
    }

    // now handle all the skipped corners
    Arrays.sort(skippedCorners.data, 0, skippedCorners.size);

    for (int i = skippedCorners.size - 1; i >= 0; i--) {
      int index = skippedCorners.get(i);
      contourCorners.remove(index);

      if (anchor0 >= index) {
        anchor0--;
      }
      if (anchor1 >= index) {
        anchor1--;
      }
    }
    //		cornerIndexes.size -= skippedCorners.size();

    for (int i = 0; i < contourCorners.size(); i++) {
      int j = (i + 1) % contourCorners.size();
      a = contour.get(contourCorners.get(i));
      b = contour.get(contourCorners.get(j));

      if (a.x == b.x && a.y == b.y) {
        throw new RuntimeException("Well I screwed up");
      }
    }

    return contourCorners.size() >= 3;
  }