/**
   * Locate ellipses within an image
   *
   * @param grayImage Grayscale image
   * @return Ellipse locations
   */
  public EllipseLocationResult locateEllipses(Mat grayImage) {
    Mat gray = grayImage.clone();

    Filter.downsample(gray, 2);
    Filter.upsample(gray, 2);

    Imgproc.Canny(gray, gray, 5, 75, 3, true);
    Filter.dilate(gray, 2);

    Mat cacheHierarchy = new Mat();

    List<MatOfPoint> contoursTemp = new ArrayList<>();
    // Find contours - the parameters here are very important to compression and retention
    Imgproc.findContours(
        gray, contoursTemp, cacheHierarchy, Imgproc.CV_RETR_TREE, Imgproc.CHAIN_APPROX_TC89_KCOS);

    // List contours
    List<Contour> contours = new ArrayList<>();
    for (MatOfPoint co : contoursTemp) {
      contours.add(new Contour(co));
    }

    // Find ellipses by finding fit
    List<Ellipse> ellipses = new ArrayList<>();
    for (MatOfPoint co : contoursTemp) {
      contours.add(new Contour(co));
      // Contour must have at least 6 points for fitEllipse
      if (co.toArray().length < 6) continue;
      // Copy MatOfPoint to MatOfPoint2f
      MatOfPoint2f matOfPoint2f = new MatOfPoint2f(co.toArray());
      // Fit an ellipse to the current contour
      Ellipse ellipse = new Ellipse(Imgproc.fitEllipse(matOfPoint2f));

      // Draw ellipse
      ellipses.add(ellipse);
    }

    return new EllipseLocationResult(contours, ellipses);
  }
Esempio n. 2
0
  public static void Circle(List<MatOfPoint> contours, int index) {
    int i = index;
    Mat mRGBA = new Mat();
    Utils.bitmapToMat(image, mRGBA);
    // cyklus s podmienkou na konci
    do {
      int buff[] = new int[4];
      hierarchy.get(0, i, buff);

      // Get contour form list
      Mat contour = contours.get(i);

      // id kont�ry
      int id = i;

      // dostaneme �a��ie id kont�ry
      i = buff[0];

      // zis�ujeme �i m�me dostato�ne ve�k� kont�ru aby sme sa �ou v�bec zaoberali
      if (Imgproc.contourArea(contour) > 500) {

        List<Point> points = new ArrayList<Point>();

        // dostaneme celkov� po�et kont�r
        int num = (int) contour.total();

        // vytvor�me si pole o dvojn�sobnej ve�kosti samotnej kontury
        int temp[] = new int[num * 2];

        // na��tame si kont�ru do do�asnej premennej
        contour.get(0, 0, temp);

        // konvertujeme  List<Point> do MatOfPoint2f pre pou�itie fitEllipse
        for (int j = 0; j < num * 2; j = j + 2) {
          points.add(new Point(temp[j], temp[j + 1]));
        }
        MatOfPoint2f specialPointMtx = new MatOfPoint2f(points.toArray(new Point[0]));

        // do premennej bound uklad�me dokonal� elipsu
        RotatedRect bound = Imgproc.fitEllipse(specialPointMtx);

        // Vypo��ta sa hodnota pi
        double pi =
            Imgproc.contourArea(contour) / ((bound.size.height / 2) * (bound.size.width / 2));

        // zis�ujeme toleranciu pi - zaoplenie
        if (Math.abs(pi - 3.14) > 0.03) {
          int k = buff[2];
          // zis�ujeme �i existuje nejak� rodi� kont�ry
          if (k != -1) {
            Circle(contours, k);
          }
          continue;
        }

        // konvertujeme MatOfPoint2f do MatOfPoint  pre funckiu fitEllipse - rozdie� je len v 32-bit
        // float a 32-bit int
        MatOfPoint NewMtx = new MatOfPoint(specialPointMtx.toArray());
        // dostaneme s�radnice najmen�ieho mo�n�ho �tvorca
        Rect box = Imgproc.boundingRect(NewMtx);
        // nacita obrazok znova
        Mat mat_for_count = new Mat();
        Utils.bitmapToMat(image, mat_for_count);
        // vytvori sa klon stvorca - dobry kandidat pre vyhladanie
        Mat candidate = ((mat_for_count).submat(box)).clone();
        // napln maticu binarnou ciernou
        Mat mask = new Mat(box.size(), candidate.type(), new Scalar(0, 0, 0));
        // naplni ciernu plochu bielimi konturami
        Imgproc.drawContours(
            mask,
            contours,
            id,
            new Scalar(255, 255, 255),
            -1,
            8,
            hierarchy,
            0,
            new Point(-box.x, -box.y));
        // ulozi sa kandidat
        Mat roi = new Mat(candidate.size(), candidate.type(), new Scalar(255, 255, 255));
        // ulozia sa len informacie o kandidatovi
        candidate.copyTo(roi, mask);

        double longAxis;
        double shortAxis;
        // ziska dve osy elipsy
        if (bound.size.height < bound.size.width) {
          shortAxis = bound.size.height / 2;
          longAxis = bound.size.width / 2;
        } else {
          shortAxis = bound.size.width / 2;
          longAxis = bound.size.height / 2;
        }

        // zastavi sa vyhladavanie pokial je elipsa prilis ovalna
        if ((longAxis / shortAxis) < 2.0) {
          signList.add(roi);
          boxList.add(box);
        }
      }
      // zis�uje sa �i je tam e�te �al�� kandid�t
    } while (i != -1);
  }