Пример #1
0
  /**
   * Locate rectangles in an image
   *
   * @param grayImage Grayscale image
   * @return Rectangle locations
   */
  public RectangleLocationResult locateRectangles(Mat grayImage) {
    Mat gray = grayImage.clone();

    // Filter out some noise
    Filter.downsample(gray, 2);
    Filter.upsample(gray, 2);

    Mat cacheHierarchy = new Mat();
    Mat grayTemp = new Mat();
    List<Rectangle> rectangles = new ArrayList<>();
    List<Contour> contours = new ArrayList<>();

    Imgproc.Canny(gray, grayTemp, 0, THRESHOLD_CANNY, APERTURE_CANNY, true);
    Filter.dilate(gray, 2);

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

    // For each contour, test whether the contour is a rectangle
    // List<Contour> contours = new ArrayList<>();
    MatOfPoint2f approx = new MatOfPoint2f();
    for (MatOfPoint co : contoursTemp) {
      MatOfPoint2f matOfPoint2f = new MatOfPoint2f(co.toArray());
      Contour c = new Contour(co);

      // Attempt to fit the contour to the best polygon
      Imgproc.approxPolyDP(
          matOfPoint2f, approx, c.arcLength(true) * EPLISON_APPROX_TOLERANCE_FACTOR, true);

      Contour approxContour = new Contour(approx);

      // Make sure the contour is big enough, CLOSED (convex), and has exactly 4 points
      if (approx.toArray().length == 4
          && Math.abs(approxContour.area()) > 1000
          && approxContour.isClosed()) {

        // TODO contours and rectangles array may not match up, but why would they?
        contours.add(approxContour);

        // Check each angle to be approximately 90 degrees
        double maxCosine = 0;
        for (int j = 2; j < 5; j++) {
          double cosine =
              Math.abs(
                  MathUtil.angle(
                      approx.toArray()[j % 4], approx.toArray()[j - 2], approx.toArray()[j - 1]));
          maxCosine = Math.max(maxCosine, cosine);
        }

        if (maxCosine < MAX_COSINE_VALUE) {
          // Convert the points to a rectangle instance
          rectangles.add(new Rectangle(approx.toArray()));
        }
      }
    }

    return new RectangleLocationResult(contours, rectangles);
  }
Пример #2
0
  private static Mat findLargestRectangle(Mat original_image) {
    Mat imgSource = original_image.clone();

    // convert the image to black and white
    Imgproc.cvtColor(imgSource, imgSource, Imgproc.COLOR_BGR2GRAY);

    // convert the image to black and white does (8 bit)
    Imgproc.Canny(imgSource, imgSource, 50, 50);

    // apply gaussian blur to smoothen lines of dots
    Imgproc.GaussianBlur(imgSource, imgSource, new Size(5, 5), 5);

    // find the contours
    List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
    Imgproc.findContours(
        imgSource, contours, new Mat(), Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE);

    double maxArea = -1;
    MatOfPoint temp_contour = contours.get(0); // the largest is at the
    // index 0 for starting
    // point
    MatOfPoint2f approxCurve = new MatOfPoint2f();
    List<MatOfPoint> largest_contours = new ArrayList<MatOfPoint>();
    for (int idx = 0; idx < contours.size(); idx++) {
      temp_contour = contours.get(idx);
      double contourarea = Imgproc.contourArea(temp_contour);
      // compare this contour to the previous largest contour found
      if (contourarea > maxArea) {
        // check if this contour is a square
        MatOfPoint2f new_mat = new MatOfPoint2f(temp_contour.toArray());
        int contourSize = (int) temp_contour.total();
        Imgproc.approxPolyDP(new_mat, approxCurve, contourSize * 0.05, true);
        if (approxCurve.total() == 4) {
          maxArea = contourarea;
          largest_contours.add(temp_contour);
        }
      }
    }
    MatOfPoint temp_largest = largest_contours.get(largest_contours.size() - 1);
    largest_contours = new ArrayList<MatOfPoint>();

    largest_contours.add(temp_largest);

    // Imgproc.cvtColor(imgSource, imgSource, Imgproc.COLOR_BayerBG2RGB);
    Imgproc.drawContours(original_image, largest_contours, -1, new Scalar(0, 255, 0), 10);

    // Mat perspectiveTransform = new Mat(3, 3, CvType.CV_32FC1);
    // Imgproc.warpPerspective(original_image, imgSource,
    // perspectiveTransform, new Size(300,300));

    Highgui.imwrite(output, original_image);

    // create the new image here using the largest detected square

    // Toast.makeText(getApplicationContext(), "Largest Contour: ",
    // Toast.LENGTH_LONG).show();

    return imgSource;
  }
  public static Mat getCCH(Mat image) {
    ArrayList<MatOfPoint> contours = new ArrayList<MatOfPoint>();
    Mat hierarchy = new Mat();
    Imgproc.findContours(
        image, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_NONE);

    Mat chainHistogram = Mat.zeros(1, 8, CvType.CV_32F);
    int n = 0;
    MatOfPoint2f approxCurve = new MatOfPoint2f();
    for (MatOfPoint contour : contours) {

      // get the freeman chain code from the contours
      int rows = contour.rows();
      // System.out.println("\nrows"+rows+"\n"+contour.dump());
      int direction = 7;
      Mat prevPoint = contours.get(0).row(0);
      n += rows - 1;
      for (int i = 1; i < rows; i++) {
        // get the current point
        double x1 = contour.get(i - 1, 0)[1];
        double y1 = contour.get(i - 1, 0)[0];

        // get the second point
        double x2 = contour.get(i, 0)[1];
        double y2 = contour.get(i, 0)[0];

        if (x2 == x1 && y2 == y1 + 1) direction = 0;
        else if (x2 == x1 - 1 && y2 == y1 + 1) direction = 1;
        else if (x2 == x1 - 1 && y2 == y1) direction = 2;
        else if (x2 == x1 - 1 && y2 == y1 - 1) direction = 3;
        else if (x2 == x1 && y2 == y1 - 1) direction = 4;
        else if (x2 == x1 + 1 && y2 == y1 - 1) direction = 5;
        else if (x2 == x1 + 1 && y2 == y1) direction = 6;
        else if (x2 == x1 + 1 && y2 == y1 + 1) direction = 7;
        else System.out.print("err");
        double counter = chainHistogram.get(0, direction)[0];
        chainHistogram.put(0, direction, ++counter);
        System.out.print(direction);
      }
    }
    System.out.println("\n" + chainHistogram.dump());
    Scalar alpha = new Scalar(n); // the factor
    Core.divide(chainHistogram, alpha, chainHistogram);
    System.out.println("\nrows=" + n + " " + chainHistogram.dump());
    return chainHistogram;
  }
Пример #4
0
 public static Point getFirstPoint(MatOfPoint o) {
   Point zero = new Point(0, 0);
   Point first = new Point(Double.MAX_VALUE, Double.MAX_VALUE);
   double minDist = Double.MAX_VALUE;
   for (Point point : o.toList()) {
     double dist = Util.euclideanDist(zero, point);
     if (dist < minDist) {
       first = point;
       minDist = dist;
     }
   }
   return first;
 }
Пример #5
0
  /**
   * 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);
  }
Пример #6
0
  public static int identify_R_U(Mat binary) {
    // 0: hull points identified < 2
    // 1: R
    // 2: U
    List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
    List<MatOfPoint> hullPoints = new ArrayList<MatOfPoint>();
    List<Point> hullPointList = new ArrayList<Point>();
    List<Point> filteredPointList = new ArrayList<Point>();
    MatOfPoint hullPointMat = new MatOfPoint();
    MatOfInt hull = new MatOfInt();
    Mat hierarchy = new Mat();

    // Find contour
    Imgproc.findContours(
        binary, contours, hierarchy, Imgproc.RETR_TREE, Imgproc.CHAIN_APPROX_SIMPLE);

    // Find convex hull
    for (int k = 0; k < contours.size(); k++) {
      Imgproc.convexHull(contours.get(k), hull);

      for (int j = 0; j < hull.toList().size(); j++) {
        hullPointList.add(contours.get(k).toList().get(hull.toList().get(j)));
      }

      hullPointMat.fromList(hullPointList);
      hullPoints.add(hullPointMat);
    }

    // Filter hull points. Only hull points relevant to hull classification
    // will remain.
    // Also, count the number of filtered hull points in left and right.
    for (int l = 0; l < hullPointList.size(); l++) {

      if (hullPointList.get(l).y < binary.rows() * 0.25) {

        if (l != hullPointList.size() - 1) {

          if (Math.hypot(
                      hullPointList.get(l).x - hullPointList.get(l + 1).x,
                      hullPointList.get(l).y - hullPointList.get(l + 1).y)
                  / binary.cols()
              > 0.08) {

            filteredPointList.add(hullPointList.get(l));
            // Core.circle(rgb,
            // new Point(UL.x + hullPointList.get(l).x, UL.y
            // + hullPointList.get(l).y), 5,
            // new Scalar(0, 255, 0));
          }
        }
      }
    }

    // Sort points by x axis, increasing
    if (filteredPointList.size() > 1) {
      if (filteredPointList.get(0).x > filteredPointList.get(1).x) {
        Point temp = filteredPointList.get(0);
        filteredPointList.set(0, filteredPointList.get(1));
        filteredPointList.set(1, temp);
      }

      if (filteredPointList.get(0).y > filteredPointList.get(1).y) return 1; // R
      else return 2; // U
    }

    return 0;
  }
Пример #7
0
  public void run() {
    ArrayList<Geometry.Quad> squares;

    Mat image = new Mat();
    Utils.bitmapToMat(source, image);

    Mat bwimage = new Mat();
    cvtColor(image, bwimage, COLOR_RGB2GRAY);

    Mat blurred = new Mat();
    medianBlur(image, blurred, 9);

    int width = blurred.width();
    int height = blurred.height();
    int depth = blurred.depth();

    Mat gray0 = new Mat(width, height, depth);
    blurred.copyTo(gray0);

    squares = new ArrayList<Geometry.Quad>();

    // find squares in every color plane of the image
    for (int c = 0; c < 3; c++) {
      Core.mixChannels(
          Arrays.asList(blurred), Arrays.asList(new Mat[] {gray0}), new MatOfInt(c, 0));

      // try several threshold levels
      int thresholdLevel = 8;
      for (int l = 0; l < thresholdLevel; l++) {
        // use canny instead of 0 threshold level
        // canny helps catch squares with gradient shading
        Mat gray = new Mat();

        if (l == 0) {
          Canny(gray0, gray, 10.0, 20.0, 3, false);
          Mat kernel = new Mat(11, 11, CvType.CV_8UC1, new Scalar(1));
          dilate(gray, gray, kernel);
        } else {
          Mat thresh = new Mat(gray0.rows(), gray0.cols(), gray0.type());
          threshold(gray0, thresh, ((double) l) / thresholdLevel * 255, 128, THRESH_BINARY_INV);
          cvtColor(thresh, gray, COLOR_BGR2GRAY);
        }

        // find contours and store them in a list
        List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
        findContours(gray, contours, new Mat(), RETR_LIST, CHAIN_APPROX_SIMPLE);

        // test contours
        for (MatOfPoint contour : contours) {
          // approximate contour with accuracy proportional to the contour perimeter
          MatOfPoint2f thisContour = new MatOfPoint2f(contour.toArray());
          double arclength = 0.02 * arcLength(thisContour, true);
          MatOfPoint2f approx = new MatOfPoint2f();
          approxPolyDP(thisContour, approx, arclength, true);

          double area = contourArea(approx);
          boolean isConvex = isContourConvex(new MatOfPoint(approx.toArray()));

          if (approx.rows() == 4 && Math.abs(area) > SQUARE_SIZE && isConvex) {
            double maxCosine = 0;

            Point[] approxArray = approx.toArray();
            for (int j = 2; j < 5; j++) {
              double cosine =
                  Math.abs(angle(approxArray[j % 4], approxArray[j - 2], approxArray[j - 1]));
              maxCosine = Math.max(maxCosine, cosine);
            }

            if (maxCosine > THRESHOLD_COS) {
              squares.add(new Geometry.Quad(approxArray));
              Log.d(TAG, "area = " + area);
            }
          }
        }
      }
    }

    result = new Bundle();
    result.putParcelableArrayList("squares", squares);
    Log.d(TAG, "result created");

    finish();
  }
Пример #8
0
  public Point findLaser(Mat inputFrame) {
    Mat mHsv = new Mat();

    Imgproc.cvtColor(inputFrame, mHsv, Imgproc.COLOR_RGB2HSV);

    // Find laser center
    Mat center = new Mat();
    Core.inRange(mHsv, new Scalar(0, 0, 250), new Scalar(180, 16, 255), center);

    Mat h = new Mat();
    List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
    Imgproc.findContours(center, contours, h, Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE);
    center.release();

    Mat center_mask = Mat.zeros(inputFrame.rows(), inputFrame.cols(), CvType.CV_8U);
    if (contours.size() > 0) {
      for (int i = 0; i < contours.size(); i++) {
        int radius = 10;
        // Point[] cont_pos = contours.get(i).toArray();
        Moments m = Imgproc.moments(contours.get(i));
        Point p = new Point();
        p.x = m.get_m10() / m.get_m00();
        p.y = m.get_m01() / m.get_m00();
        Core.circle(center_mask, p, radius * 2, new Scalar(255), -1);
      }
    }

    // Find halo
    Mat ranged = new Mat();
    Core.inRange(mHsv, new Scalar(100, 32, 225), new Scalar(150, 255, 255), ranged);
    mHsv.release();
    // Mat f_frame =ranged.clone();

    // Find halo around bright dot
    Core.bitwise_and(ranged, center_mask, ranged);
    center_mask.release();

    // Find biggest resulting contour
    for (int i = 1; i < contours.size(); i++) {
      contours.get(i).release();
    }
    contours.clear();
    Imgproc.findContours(ranged, contours, h, Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE);
    h.release();
    ranged.release();

    if (contours.size() > 0) {
      MatOfPoint biggest_cont = contours.get(0);
      double cont_size = Imgproc.contourArea(biggest_cont);
      for (int i = 1; i < contours.size(); i++) {
        MatOfPoint cur = contours.get(i);
        if (Imgproc.contourArea(cur) > cont_size) {
          biggest_cont = cur;
          cont_size = Imgproc.contourArea(cur);
        }
      }
      Moments m = Imgproc.moments(biggest_cont);
      Point p = new Point();
      p.x = m.get_m10() / m.get_m00();
      p.y = m.get_m01() / m.get_m00();
      for (int i = 1; i < contours.size(); i++) {
        contours.get(i).release();
      }
      biggest_cont.release();

      return p;
    } else {
      return null;
    }
  }
Пример #9
0
  public static void getSquare(Mat imgSource) {
    Mat sourceImage = imgSource.clone();
    Imgproc.cvtColor(imgSource, imgSource, Imgproc.COLOR_BGR2GRAY);
    // convert the image to black and white does (8 bit)
    Imgproc.Canny(imgSource, imgSource, 50, 50);

    // apply gaussian blur to smoothen lines of dots
    Imgproc.GaussianBlur(imgSource, imgSource, new org.opencv.core.Size(5, 5), 5);

    // find the contours
    List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
    Imgproc.findContours(
        imgSource, contours, new Mat(), Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE);

    double maxArea = -1;
    int maxAreaIdx = -1;
    // Log.d("size",Integer.toString(contours.size()));
    MatOfPoint temp_contour = contours.get(0); // the largest is at the
    // index 0 for starting
    // point
    MatOfPoint2f approxCurve = new MatOfPoint2f();
    MatOfPoint largest_contour = contours.get(0);
    // largest_contour.ge
    List<MatOfPoint> largest_contours = new ArrayList<MatOfPoint>();
    // Imgproc.drawContours(imgSource,contours, -1, new Scalar(0, 255, 0),
    // 1);

    for (int idx = 0; idx < contours.size(); idx++) {
      temp_contour = contours.get(idx);
      double contourarea = Imgproc.contourArea(temp_contour);
      // compare this contour to the previous largest contour found
      if (contourarea > maxArea) {
        // check if this contour is a square
        MatOfPoint2f new_mat = new MatOfPoint2f(temp_contour.toArray());
        int contourSize = (int) temp_contour.total();
        MatOfPoint2f approxCurve_temp = new MatOfPoint2f();
        Imgproc.approxPolyDP(new_mat, approxCurve_temp, contourSize * 0.05, true);
        if (approxCurve_temp.total() == 4) {
          maxArea = contourarea;
          maxAreaIdx = idx;
          approxCurve = approxCurve_temp;
          largest_contour = temp_contour;
        }
      }
    }

    Imgproc.cvtColor(imgSource, imgSource, Imgproc.COLOR_BayerBG2RGB);

    double[] temp_double;
    temp_double = approxCurve.get(0, 0);
    Point p1 = new Point(temp_double[0], temp_double[1]);
    // Core.circle(imgSource,p1,55,new Scalar(0,0,255));
    // Imgproc.warpAffine(sourceImage, dummy, rotImage,sourceImage.size());
    temp_double = approxCurve.get(1, 0);
    Point p2 = new Point(temp_double[0], temp_double[1]);
    // Core.circle(imgSource,p2,150,new Scalar(255,255,255));
    temp_double = approxCurve.get(2, 0);
    Point p3 = new Point(temp_double[0], temp_double[1]);
    // Core.circle(imgSource,p3,200,new Scalar(255,0,0));
    temp_double = approxCurve.get(3, 0);
    Point p4 = new Point(temp_double[0], temp_double[1]);
    // Core.circle(imgSource,p4,100,new Scalar(0,0,255));
    List<Point> source = getCorners(p1, p2, p3, p4);
    for (Point p : source) {
      // System.out.println(p);
    }
    Mat startM = Converters.vector_Point2f_to_Mat(source);
    // Imgproc.cvtColor(sourceImage, sourceImage, Imgproc.COLOR_BGR2GRAY);
    Mat result = warp(sourceImage, startM, 5);
    // result = warp(result,result,1);
    // Imgproc.cvtColor(result, result, Imgproc.COLOR_BGR2GRAY);
    Highgui.imwrite(output, result);
    // System.out.println("Done");
    // return result;
  }