Beispiel #1
0
  public Segmenter(ImageUInt8 gray) {

    // Downsample image to smaller size
    int sampleWidth = 300;
    this.scale = (1.0 * gray.getWidth()) / sampleWidth;
    int sampleHeight = (int) (gray.getHeight() / scale);
    ImageUInt8 sample = new ImageUInt8(sampleWidth, sampleHeight);
    boofcv.alg.distort.DistortImageOps.scale(
        gray, sample, boofcv.alg.interpolate.TypeInterpolate.NEAREST_NEIGHBOR);
    this.sample = sample;

    // Calculate mean
    this.mean = GPixelMath.sum(gray) / (gray.width * gray.height);
    this.threshold = this.calculateThreshold();

    Log.i(
        "Setalyzer",
        "brightness histogram: " + Arrays.toString(this.brightnessHistogram.histogram));

    // Blur image and store blurred image
    this.blurred = boofcv.alg.filter.blur.BlurImageOps.mean(sample, null, BLUR_RADIUS, null);

    // Create binary image and label blobs for threshold-based segmentation
    //		Log.i("Setalyzer", "THreshold value is " + this.mean);
    // Threshold to generate binary image
    ImageUInt8 binary =
        boofcv.alg.filter.binary.ThresholdImageOps.threshold(
            this.blurred, null, (int) this.mean, false);
    ImageSInt32 blobImage =
        FactoryImage.create(ImageSInt32.class, sample.getWidth(), sample.getHeight());
    this.numBlobs = boofcv.alg.filter.binary.BinaryImageOps.labelBlobs4(binary, blobImage);
    this.blobQuads = quadsFromBlobs(blobImage, numBlobs);

    // Canny detect edges and store them
    // Dynamic canny edge, which sets the threshold as a function of the image's edge intensity
    DetectEdgeContour<ImageUInt8> cannyD =
        FactoryDetectEdgeContour.canny(0.05, 0.15, true, ImageUInt8.class, ImageSInt16.class);
    cannyD.process(blurred);
    List<List<Point2D_I32>> edges = cannyD.getContours();

    // Prune edges which are obviously not cards
    List<List<Point2D_F64>> prunedEdgeList = new ArrayList<List<Point2D_F64>>();
    for (List<Point2D_I32> edge : edges) {
      // Disregard tiny contours
      if (edge.size() < EDGE_SIZE_THRESHOLD) {
        continue;
      }
      // Disregard shapes with blatantly non-card shapes
      //			if (!isCardShaped(edge)) {
      //				continue;
      //			}
      List<Point2D_F64> f64Edge = new ArrayList<Point2D_F64>();
      for (Point2D_I32 p : edge) {
        f64Edge.add(new Point2D_F64(p.x, p.y));
      }
      prunedEdgeList.add(f64Edge);
    }
    this.prunedCannyEdgeList = prunedEdgeList;
  }
  /** Fits polygons to found contours around binary blobs. */
  public static void fitBinaryImage(ImageFloat32 input) {

    ImageUInt8 binary = new ImageUInt8(input.width, input.height);
    BufferedImage polygon =
        new BufferedImage(input.width, input.height, BufferedImage.TYPE_INT_RGB);

    // the mean pixel value is often a reasonable threshold when creating a binary image
    double mean = ImageStatistics.mean(input);

    // create a binary image by thresholding
    ThresholdImageOps.threshold(input, binary, (float) mean, true);

    // reduce noise with some filtering
    ImageUInt8 filtered = BinaryImageOps.erode8(binary, null);
    filtered = BinaryImageOps.dilate8(filtered, null);

    // Find the contour around the shapes
    List<Contour> contours = BinaryImageOps.contour(filtered, 8, null);

    // Fit a polygon to each shape and draw the results
    Graphics2D g2 = polygon.createGraphics();
    g2.setStroke(new BasicStroke(2));

    for (Contour c : contours) {
      // Fit the polygon to the found external contour.  Note loop = true
      List<PointIndex_I32> vertexes =
          ShapeFittingOps.fitPolygon(c.external, true, toleranceDist, toleranceAngle, 100);

      g2.setColor(Color.RED);
      VisualizeShapes.drawPolygon(vertexes, true, g2);

      // handle internal contours now
      g2.setColor(Color.BLUE);
      for (List<Point2D_I32> internal : c.internal) {
        vertexes = ShapeFittingOps.fitPolygon(internal, true, toleranceDist, toleranceAngle, 100);
        VisualizeShapes.drawPolygon(vertexes, true, g2);
      }
    }

    ShowImages.showWindow(polygon, "Binary Blob Contours");
  }